Преглед на файлове

新增是否开启用户注册功能

RuoYi преди 4 години
родител
ревизия
329aa68644
променени са 33 файла, в които са добавени 810 реда и са изтрити 317 реда
  1. 8 7
      ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java
  2. 18 2
      ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java
  3. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java
  4. 3 2
      ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteLogFallbackFactory.java
  5. 8 1
      ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java
  6. 9 0
      ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java
  7. 11 0
      ruoyi-auth/src/main/java/com/ruoyi/auth/form/RegisterBody.java
  8. 75 11
      ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
  9. 0 25
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java
  10. 44 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java
  11. 16 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/InnerAuthException.java
  12. 6 6
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/SecurityUtils.java
  13. 2 1
      ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.java
  14. 19 0
      ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/InnerAuth.java
  15. 51 0
      ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/InnerAuthAspect.java
  16. 8 8
      ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignRequestInterceptor.java
  17. 12 2
      ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java
  18. 1 0
      ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring.factories
  19. 11 3
      ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java
  20. 3 3
      ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/ValidateCodeFilter.java
  21. 5 23
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysLogininforController.java
  22. 2 0
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysOperlogController.java
  23. 25 0
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java
  24. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java
  25. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java
  26. 8 0
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
  27. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java
  28. 11 0
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
  29. 12 0
      ruoyi-ui/src/api/login.js
  30. 5 0
      ruoyi-ui/src/router/index.js
  31. 9 3
      ruoyi-ui/src/views/login.vue
  32. 208 0
      ruoyi-ui/src/views/register.vue
  33. 216 216
      sql/ry_config_20210728.sql

+ 8 - 7
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java

@@ -3,9 +3,11 @@ package com.ruoyi.system.api;
3 3
 import org.springframework.cloud.openfeign.FeignClient;
4 4
 import org.springframework.web.bind.annotation.PostMapping;
5 5
 import org.springframework.web.bind.annotation.RequestBody;
6
-import org.springframework.web.bind.annotation.RequestParam;
6
+import org.springframework.web.bind.annotation.RequestHeader;
7
+import com.ruoyi.common.core.constant.SecurityConstants;
7 8
 import com.ruoyi.common.core.constant.ServiceNameConstants;
8 9
 import com.ruoyi.common.core.domain.R;
10
+import com.ruoyi.system.api.domain.SysLogininfor;
9 11
 import com.ruoyi.system.api.domain.SysOperLog;
10 12
 import com.ruoyi.system.api.factory.RemoteLogFallbackFactory;
11 13
 
@@ -21,20 +23,19 @@ public interface RemoteLogService
21 23
      * 保存系统日志
22 24
      *
23 25
      * @param sysOperLog 日志实体
26
+     * @param source 请求来源
24 27
      * @return 结果
25 28
      */
26 29
     @PostMapping("/operlog")
27
-    R<Boolean> saveLog(@RequestBody SysOperLog sysOperLog);
30
+    public R<Boolean> saveLog(@RequestBody SysOperLog sysOperLog, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
28 31
 
29 32
     /**
30 33
      * 保存访问记录
31 34
      *
32
-     * @param username 用户名称
33
-     * @param status 状态
34
-     * @param message 消息
35
+     * @param sysLogininfor 访问实体
36
+     * @param source 请求来源
35 37
      * @return 结果
36 38
      */
37 39
     @PostMapping("/logininfor")
38
-    R<Boolean> saveLogininfor(@RequestParam("username") String username, @RequestParam("status") String status,
39
-            @RequestParam("message") String message);
40
+    public R<Boolean> saveLogininfor(@RequestBody SysLogininfor sysLogininfor, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
40 41
 }

+ 18 - 2
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java

@@ -3,8 +3,13 @@ package com.ruoyi.system.api;
3 3
 import org.springframework.cloud.openfeign.FeignClient;
4 4
 import org.springframework.web.bind.annotation.GetMapping;
5 5
 import org.springframework.web.bind.annotation.PathVariable;
6
+import org.springframework.web.bind.annotation.PostMapping;
7
+import org.springframework.web.bind.annotation.RequestBody;
8
+import org.springframework.web.bind.annotation.RequestHeader;
9
+import com.ruoyi.common.core.constant.SecurityConstants;
6 10
 import com.ruoyi.common.core.constant.ServiceNameConstants;
7 11
 import com.ruoyi.common.core.domain.R;
12
+import com.ruoyi.system.api.domain.SysUser;
8 13
 import com.ruoyi.system.api.factory.RemoteUserFallbackFactory;
9 14
 import com.ruoyi.system.api.model.LoginUser;
10 15
 
@@ -20,8 +25,19 @@ public interface RemoteUserService
20 25
      * 通过用户名查询用户信息
21 26
      *
22 27
      * @param username 用户名
28
+     * @param source 请求来源
23 29
      * @return 结果
24 30
      */
25
-    @GetMapping(value = "/user/info/{username}")
26
-    public R<LoginUser> getUserInfo(@PathVariable("username") String username);
31
+    @GetMapping("/user/info/{username}")
32
+    public R<LoginUser> getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
33
+
34
+    /**
35
+     * 注册用户信息
36
+     *
37
+     * @param sysUser 用户信息
38
+     * @param source 请求来源
39
+     * @return 结果
40
+     */
41
+    @PostMapping("/user/register")
42
+    public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
27 43
 }

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysLogininfor.java

@@ -1,4 +1,4 @@
1
-package com.ruoyi.system.domain;
1
+package com.ruoyi.system.api.domain;
2 2
 
3 3
 import java.util.Date;
4 4
 import com.fasterxml.jackson.annotation.JsonFormat;

+ 3 - 2
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteLogFallbackFactory.java

@@ -6,6 +6,7 @@ import org.springframework.cloud.openfeign.FallbackFactory;
6 6
 import org.springframework.stereotype.Component;
7 7
 import com.ruoyi.common.core.domain.R;
8 8
 import com.ruoyi.system.api.RemoteLogService;
9
+import com.ruoyi.system.api.domain.SysLogininfor;
9 10
 import com.ruoyi.system.api.domain.SysOperLog;
10 11
 
11 12
 /**
@@ -25,13 +26,13 @@ public class RemoteLogFallbackFactory implements FallbackFactory<RemoteLogServic
25 26
         return new RemoteLogService()
26 27
         {
27 28
             @Override
28
-            public R<Boolean> saveLog(SysOperLog sysOperLog)
29
+            public R<Boolean> saveLog(SysOperLog sysOperLog, String source)
29 30
             {
30 31
                 return null;
31 32
             }
32 33
 
33 34
             @Override
34
-            public R<Boolean> saveLogininfor(String username, String status, String message)
35
+            public R<Boolean> saveLogininfor(SysLogininfor sysLogininfor, String source)
35 36
             {
36 37
                 return null;
37 38
             }

+ 8 - 1
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java

@@ -6,6 +6,7 @@ import org.springframework.cloud.openfeign.FallbackFactory;
6 6
 import org.springframework.stereotype.Component;
7 7
 import com.ruoyi.common.core.domain.R;
8 8
 import com.ruoyi.system.api.RemoteUserService;
9
+import com.ruoyi.system.api.domain.SysUser;
9 10
 import com.ruoyi.system.api.model.LoginUser;
10 11
 
11 12
 /**
@@ -25,10 +26,16 @@ public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserServ
25 26
         return new RemoteUserService()
26 27
         {
27 28
             @Override
28
-            public R<LoginUser> getUserInfo(String username)
29
+            public R<LoginUser> getUserInfo(String username, String source)
29 30
             {
30 31
                 return R.fail("获取用户失败:" + throwable.getMessage());
31 32
             }
33
+
34
+            @Override
35
+            public R<Boolean> registerUserInfo(SysUser sysUser, String source)
36
+            {
37
+                return R.fail("注册用户失败:" + throwable.getMessage());
38
+            }
32 39
         };
33 40
     }
34 41
 }

+ 9 - 0
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java

@@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.PostMapping;
7 7
 import org.springframework.web.bind.annotation.RequestBody;
8 8
 import org.springframework.web.bind.annotation.RestController;
9 9
 import com.ruoyi.auth.form.LoginBody;
10
+import com.ruoyi.auth.form.RegisterBody;
10 11
 import com.ruoyi.auth.service.SysLoginService;
11 12
 import com.ruoyi.common.core.domain.R;
12 13
 import com.ruoyi.common.core.utils.StringUtils;
@@ -63,4 +64,12 @@ public class TokenController
63 64
         }
64 65
         return R.ok();
65 66
     }
67
+
68
+    @PostMapping("register")
69
+    public R<?> register(@RequestBody RegisterBody registerBody)
70
+    {
71
+        // 用户注册
72
+        sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
73
+        return R.ok();
74
+    }
66 75
 }

+ 11 - 0
ruoyi-auth/src/main/java/com/ruoyi/auth/form/RegisterBody.java

@@ -0,0 +1,11 @@
1
+package com.ruoyi.auth.form;
2
+
3
+/**
4
+ * 用户注册对象
5
+ * 
6
+ * @author ruoyi
7
+ */
8
+public class RegisterBody extends LoginBody
9
+{
10
+
11
+}

+ 75 - 11
ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java

@@ -3,14 +3,18 @@ package com.ruoyi.auth.service;
3 3
 import org.springframework.beans.factory.annotation.Autowired;
4 4
 import org.springframework.stereotype.Component;
5 5
 import com.ruoyi.common.core.constant.Constants;
6
+import com.ruoyi.common.core.constant.SecurityConstants;
6 7
 import com.ruoyi.common.core.constant.UserConstants;
7 8
 import com.ruoyi.common.core.domain.R;
8 9
 import com.ruoyi.common.core.enums.UserStatus;
9 10
 import com.ruoyi.common.core.exception.BaseException;
10 11
 import com.ruoyi.common.core.utils.SecurityUtils;
12
+import com.ruoyi.common.core.utils.ServletUtils;
11 13
 import com.ruoyi.common.core.utils.StringUtils;
14
+import com.ruoyi.common.core.utils.ip.IpUtils;
12 15
 import com.ruoyi.system.api.RemoteLogService;
13 16
 import com.ruoyi.system.api.RemoteUserService;
17
+import com.ruoyi.system.api.domain.SysLogininfor;
14 18
 import com.ruoyi.system.api.domain.SysUser;
15 19
 import com.ruoyi.system.api.model.LoginUser;
16 20
 
@@ -36,25 +40,25 @@ public class SysLoginService
36 40
         // 用户名或密码为空 错误
37 41
         if (StringUtils.isAnyBlank(username, password))
38 42
         {
39
-            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写");
43
+            recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写");
40 44
             throw new BaseException("用户/密码必须填写");
41 45
         }
42 46
         // 密码如果不在指定范围内 错误
43 47
         if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
44 48
                 || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
45 49
         {
46
-            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围");
50
+            recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围");
47 51
             throw new BaseException("用户密码不在指定范围");
48 52
         }
49 53
         // 用户名不在指定范围内 错误
50 54
         if (username.length() < UserConstants.USERNAME_MIN_LENGTH
51 55
                 || username.length() > UserConstants.USERNAME_MAX_LENGTH)
52 56
         {
53
-            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围");
57
+            recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围");
54 58
             throw new BaseException("用户名不在指定范围");
55 59
         }
56 60
         // 查询用户信息
57
-        R<LoginUser> userResult = remoteUserService.getUserInfo(username);
61
+        R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
58 62
 
59 63
         if (R.FAIL == userResult.getCode())
60 64
         {
@@ -63,33 +67,93 @@ public class SysLoginService
63 67
 
64 68
         if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
65 69
         {
66
-            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
70
+            recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
67 71
             throw new BaseException("登录用户:" + username + " 不存在");
68 72
         }
69 73
         LoginUser userInfo = userResult.getData();
70 74
         SysUser user = userResult.getData().getSysUser();
71 75
         if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
72 76
         {
73
-            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
74
-
77
+            recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
75 78
             throw new BaseException("对不起,您的账号:" + username + " 已被删除");
76 79
         }
77 80
         if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
78 81
         {
79
-            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
82
+            recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
80 83
             throw new BaseException("对不起,您的账号:" + username + " 已停用");
81 84
         }
82 85
         if (!SecurityUtils.matchesPassword(password, user.getPassword()))
83 86
         {
84
-            remoteLogService.saveLogininfor(username, Constants.LOGIN_FAIL, "用户密码错误");
87
+            recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码错误");
85 88
             throw new BaseException("用户不存在/密码错误");
86 89
         }
87
-        remoteLogService.saveLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
90
+        recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
88 91
         return userInfo;
89 92
     }
90 93
 
91 94
     public void logout(String loginName)
92 95
     {
93
-        remoteLogService.saveLogininfor(loginName, Constants.LOGOUT, "退出成功");
96
+        recordLogininfor(loginName, Constants.LOGOUT, "退出成功");
97
+    }
98
+
99
+    /**
100
+     * 注册
101
+     */
102
+    public void register(String username, String password)
103
+    {
104
+        // 用户名或密码为空 错误
105
+        if (StringUtils.isAnyBlank(username, password))
106
+        {
107
+            throw new BaseException("用户/密码必须填写");
108
+        }
109
+        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
110
+                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
111
+        {
112
+            throw new BaseException("账户长度必须在2到20个字符之间");
113
+        }
114
+        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
115
+                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
116
+        {
117
+            throw new BaseException("密码长度必须在5到20个字符之间");
118
+        }
119
+
120
+        // 注册用户信息
121
+        SysUser sysUser = new SysUser();
122
+        sysUser.setUserName(username);
123
+        sysUser.setNickName(username);
124
+        sysUser.setPassword(SecurityUtils.encryptPassword(password));
125
+        R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
126
+
127
+        if (R.FAIL == registerResult.getCode())
128
+        {
129
+            throw new BaseException(registerResult.getMsg());
130
+        }
131
+        recordLogininfor(username, Constants.REGISTER, "注册成功");
132
+    }
133
+
134
+    /**
135
+     * 记录登录信息
136
+     * 
137
+     * @param username 用户名
138
+     * @param status 状态
139
+     * @param message 消息内容
140
+     * @return
141
+     */
142
+    public void recordLogininfor(String username, String status, String message)
143
+    {
144
+        SysLogininfor logininfor = new SysLogininfor();
145
+        logininfor.setUserName(username);
146
+        logininfor.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
147
+        logininfor.setMsg(message);
148
+        // 日志状态
149
+        if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
150
+        {
151
+            logininfor.setStatus("0");
152
+        }
153
+        else if (Constants.LOGIN_FAIL.equals(status))
154
+        {
155
+            logininfor.setStatus("1");
156
+        }
157
+        remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER);
94 158
     }
95 159
 }

+ 0 - 25
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java

@@ -8,32 +8,7 @@ package com.ruoyi.common.core.constant;
8 8
 public class CacheConstants
9 9
 {
10 10
     /**
11
-     * 令牌自定义标识
12
-     */
13
-    public static final String TOKEN_AUTHENTICATION = "Authorization";
14
-
15
-    /**
16
-     * 令牌前缀
17
-     */
18
-    public static final String TOKEN_PREFIX = "Bearer ";
19
-
20
-    /**
21 11
      * 权限缓存前缀
22 12
      */
23 13
     public final static String LOGIN_TOKEN_KEY = "login_tokens:";
24
-
25
-    /**
26
-     * 用户ID字段
27
-     */
28
-    public static final String DETAILS_USER_ID = "user_id";
29
-
30
-    /**
31
-     * 用户名字段
32
-     */
33
-    public static final String DETAILS_USERNAME = "username";
34
-
35
-    /**
36
-     * 授权信息字段
37
-     */
38
-    public static final String AUTHORIZATION_HEADER = "authorization";
39 14
 }

+ 44 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java

@@ -0,0 +1,44 @@
1
+package com.ruoyi.common.core.constant;
2
+
3
+/**
4
+ * 权限相关通用常量
5
+ * 
6
+ * @author ruoyi
7
+ */
8
+public class SecurityConstants
9
+{
10
+    /**
11
+     * 令牌自定义标识
12
+     */
13
+    public static final String TOKEN_AUTHENTICATION = "Authorization";
14
+
15
+    /**
16
+     * 令牌前缀
17
+     */
18
+    public static final String TOKEN_PREFIX = "Bearer ";
19
+
20
+    /**
21
+     * 用户ID字段
22
+     */
23
+    public static final String DETAILS_USER_ID = "user_id";
24
+
25
+    /**
26
+     * 用户名字段
27
+     */
28
+    public static final String DETAILS_USERNAME = "username";
29
+
30
+    /**
31
+     * 授权信息字段
32
+     */
33
+    public static final String AUTHORIZATION_HEADER = "authorization";
34
+
35
+    /**
36
+     * 请求来源
37
+     */
38
+    public static final String FROM_SOURCE = "from-source";
39
+
40
+    /**
41
+     * 内部请求
42
+     */
43
+    public static final String INNER = "inner";
44
+}

+ 16 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/InnerAuthException.java

@@ -0,0 +1,16 @@
1
+package com.ruoyi.common.core.exception;
2
+
3
+/**
4
+ * 内部认证异常
5
+ * 
6
+ * @author ruoyi
7
+ */
8
+public class InnerAuthException extends RuntimeException
9
+{
10
+    private static final long serialVersionUID = 1L;
11
+
12
+    public InnerAuthException(String message)
13
+    {
14
+        super(message);
15
+    }
16
+}

+ 6 - 6
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/SecurityUtils.java

@@ -2,7 +2,7 @@ package com.ruoyi.common.core.utils;
2 2
 
3 3
 import javax.servlet.http.HttpServletRequest;
4 4
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
5
-import com.ruoyi.common.core.constant.CacheConstants;
5
+import com.ruoyi.common.core.constant.SecurityConstants;
6 6
 import com.ruoyi.common.core.text.Convert;
7 7
 
8 8
 /**
@@ -17,7 +17,7 @@ public class SecurityUtils
17 17
      */
18 18
     public static String getUsername()
19 19
     {
20
-        String username = ServletUtils.getRequest().getHeader(CacheConstants.DETAILS_USERNAME);
20
+        String username = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USERNAME);
21 21
         return ServletUtils.urlDecode(username);
22 22
     }
23 23
 
@@ -26,7 +26,7 @@ public class SecurityUtils
26 26
      */
27 27
     public static Long getUserId()
28 28
     {
29
-        return Convert.toLong(ServletUtils.getRequest().getHeader(CacheConstants.DETAILS_USER_ID));
29
+        return Convert.toLong(ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USER_ID));
30 30
     }
31 31
 
32 32
     /**
@@ -42,7 +42,7 @@ public class SecurityUtils
42 42
      */
43 43
     public static String getToken(HttpServletRequest request)
44 44
     {
45
-        String token = request.getHeader(CacheConstants.TOKEN_AUTHENTICATION);
45
+        String token = request.getHeader(SecurityConstants.TOKEN_AUTHENTICATION);
46 46
         return replaceTokenPrefix(token);
47 47
     }
48 48
 
@@ -51,9 +51,9 @@ public class SecurityUtils
51 51
      */
52 52
     public static String replaceTokenPrefix(String token)
53 53
     {
54
-        if (StringUtils.isNotEmpty(token) && token.startsWith(CacheConstants.TOKEN_PREFIX))
54
+        if (StringUtils.isNotEmpty(token) && token.startsWith(SecurityConstants.TOKEN_PREFIX))
55 55
         {
56
-            token = token.replace(CacheConstants.TOKEN_PREFIX, "");
56
+            token = token.replace(SecurityConstants.TOKEN_PREFIX, "");
57 57
         }
58 58
         return token;
59 59
     }

+ 2 - 1
ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.java

@@ -3,6 +3,7 @@ package com.ruoyi.common.log.service;
3 3
 import org.springframework.beans.factory.annotation.Autowired;
4 4
 import org.springframework.scheduling.annotation.Async;
5 5
 import org.springframework.stereotype.Service;
6
+import com.ruoyi.common.core.constant.SecurityConstants;
6 7
 import com.ruoyi.system.api.RemoteLogService;
7 8
 import com.ruoyi.system.api.domain.SysOperLog;
8 9
 
@@ -23,6 +24,6 @@ public class AsyncLogService
23 24
     @Async
24 25
     public void saveSysLog(SysOperLog sysOperLog)
25 26
     {
26
-        remoteLogService.saveLog(sysOperLog);
27
+        remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER);
27 28
     }
28 29
 }

+ 19 - 0
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/InnerAuth.java

@@ -0,0 +1,19 @@
1
+package com.ruoyi.common.security.annotation;
2
+
3
+import java.lang.annotation.*;
4
+
5
+/**
6
+ * 内部认证注解
7
+ * 
8
+ * @author ruoyi
9
+ */
10
+@Target(ElementType.METHOD)
11
+@Retention(RetentionPolicy.RUNTIME)
12
+@Documented
13
+public @interface InnerAuth
14
+{
15
+    /**
16
+     * 是否校验用户信息
17
+     */
18
+    boolean isUser() default false;
19
+}

+ 51 - 0
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/InnerAuthAspect.java

@@ -0,0 +1,51 @@
1
+package com.ruoyi.common.security.aspect;
2
+
3
+import org.aspectj.lang.ProceedingJoinPoint;
4
+import org.aspectj.lang.annotation.Around;
5
+import org.aspectj.lang.annotation.Aspect;
6
+import org.springframework.core.Ordered;
7
+import org.springframework.stereotype.Component;
8
+import com.ruoyi.common.core.constant.SecurityConstants;
9
+import com.ruoyi.common.core.exception.InnerAuthException;
10
+import com.ruoyi.common.core.utils.ServletUtils;
11
+import com.ruoyi.common.core.utils.StringUtils;
12
+import com.ruoyi.common.security.annotation.InnerAuth;
13
+
14
+/**
15
+ * 内部服务调用验证处理
16
+ * 
17
+ * @author ruoyi
18
+ */
19
+@Aspect
20
+@Component
21
+public class InnerAuthAspect implements Ordered
22
+{
23
+    @Around("@annotation(innerAuth)")
24
+    public Object innerAround(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable
25
+    {
26
+        String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE);
27
+        // 内部请求验证
28
+        if (!StringUtils.equals(SecurityConstants.INNER, source))
29
+        {
30
+            throw new InnerAuthException("没有内部访问权限,不允许访问");
31
+        }
32
+
33
+        String userid = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USER_ID);
34
+        String username = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USERNAME);
35
+        // 用户信息验证
36
+        if (innerAuth.isUser() && (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)))
37
+        {
38
+            throw new InnerAuthException("没有设置用户信息,不允许访问 ");
39
+        }
40
+        return point.proceed();
41
+    }
42
+
43
+    /**
44
+     * 确保在权限认证aop执行前执行
45
+     */
46
+    @Override
47
+    public int getOrder()
48
+    {
49
+        return Ordered.HIGHEST_PRECEDENCE + 1;
50
+    }
51
+}

+ 8 - 8
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignRequestInterceptor.java

@@ -2,11 +2,11 @@ package com.ruoyi.common.security.feign;
2 2
 
3 3
 import java.util.Map;
4 4
 import javax.servlet.http.HttpServletRequest;
5
-import com.ruoyi.common.core.utils.ip.IpUtils;
6 5
 import org.springframework.stereotype.Component;
7
-import com.ruoyi.common.core.constant.CacheConstants;
6
+import com.ruoyi.common.core.constant.SecurityConstants;
8 7
 import com.ruoyi.common.core.utils.ServletUtils;
9 8
 import com.ruoyi.common.core.utils.StringUtils;
9
+import com.ruoyi.common.core.utils.ip.IpUtils;
10 10
 import feign.RequestInterceptor;
11 11
 import feign.RequestTemplate;
12 12
 
@@ -26,20 +26,20 @@ public class FeignRequestInterceptor implements RequestInterceptor
26 26
         {
27 27
             Map<String, String> headers = ServletUtils.getHeaders(httpServletRequest);
28 28
             // 传递用户信息请求头,防止丢失
29
-            String userId = headers.get(CacheConstants.DETAILS_USER_ID);
29
+            String userId = headers.get(SecurityConstants.DETAILS_USER_ID);
30 30
             if (StringUtils.isNotEmpty(userId))
31 31
             {
32
-                requestTemplate.header(CacheConstants.DETAILS_USER_ID, userId);
32
+                requestTemplate.header(SecurityConstants.DETAILS_USER_ID, userId);
33 33
             }
34
-            String userName = headers.get(CacheConstants.DETAILS_USERNAME);
34
+            String userName = headers.get(SecurityConstants.DETAILS_USERNAME);
35 35
             if (StringUtils.isNotEmpty(userName))
36 36
             {
37
-                requestTemplate.header(CacheConstants.DETAILS_USERNAME, userName);
37
+                requestTemplate.header(SecurityConstants.DETAILS_USERNAME, userName);
38 38
             }
39
-            String authentication = headers.get(CacheConstants.AUTHORIZATION_HEADER);
39
+            String authentication = headers.get(SecurityConstants.AUTHORIZATION_HEADER);
40 40
             if (StringUtils.isNotEmpty(authentication))
41 41
             {
42
-                requestTemplate.header(CacheConstants.AUTHORIZATION_HEADER, authentication);
42
+                requestTemplate.header(SecurityConstants.AUTHORIZATION_HEADER, authentication);
43 43
             }
44 44
 
45 45
             // 配置客户端IP

+ 12 - 2
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java

@@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
9 9
 import com.ruoyi.common.core.exception.BaseException;
10 10
 import com.ruoyi.common.core.exception.CustomException;
11 11
 import com.ruoyi.common.core.exception.DemoModeException;
12
+import com.ruoyi.common.core.exception.InnerAuthException;
12 13
 import com.ruoyi.common.core.exception.PreAuthorizeException;
13 14
 import com.ruoyi.common.core.utils.StringUtils;
14 15
 import com.ruoyi.common.core.web.domain.AjaxResult;
@@ -73,7 +74,7 @@ public class GlobalExceptionHandler
73 74
         String message = e.getBindingResult().getFieldError().getDefaultMessage();
74 75
         return AjaxResult.error(message);
75 76
     }
76
-    
77
+
77 78
     /**
78 79
      * 权限异常
79 80
      */
@@ -82,7 +83,16 @@ public class GlobalExceptionHandler
82 83
     {
83 84
         return AjaxResult.error("没有权限,请联系管理员授权");
84 85
     }
85
-    
86
+
87
+    /**
88
+     * 内部认证异常
89
+     */
90
+    @ExceptionHandler(InnerAuthException.class)
91
+    public AjaxResult InnerAuthException(InnerAuthException e)
92
+    {
93
+        return AjaxResult.error(e.getMessage());
94
+    }
95
+
86 96
     /**
87 97
      * 演示模式异常
88 98
      */

+ 1 - 0
ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring.factories

@@ -1,4 +1,5 @@
1 1
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 2
   com.ruoyi.common.security.service.TokenService,\
3 3
   com.ruoyi.common.security.aspect.PreAuthorizeAspect,\
4
+  com.ruoyi.common.security.aspect.InnerAuthAspect,\
4 5
   com.ruoyi.common.security.handler.GlobalExceptionHandler

+ 11 - 3
ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java

@@ -15,6 +15,7 @@ import com.alibaba.fastjson.JSONObject;
15 15
 import com.ruoyi.common.core.constant.CacheConstants;
16 16
 import com.ruoyi.common.core.constant.Constants;
17 17
 import com.ruoyi.common.core.constant.HttpStatus;
18
+import com.ruoyi.common.core.constant.SecurityConstants;
18 19
 import com.ruoyi.common.core.utils.SecurityUtils;
19 20
 import com.ruoyi.common.core.utils.ServletUtils;
20 21
 import com.ruoyi.common.core.utils.StringUtils;
@@ -77,8 +78,10 @@ public class AuthFilter implements GlobalFilter, Ordered
77 78
         // 设置过期时间
78 79
         redisService.expire(getTokenKey(token), EXPIRE_TIME);
79 80
         // 设置用户信息到请求
80
-        addHeader(mutate, CacheConstants.DETAILS_USER_ID, userid);
81
-        addHeader(mutate, CacheConstants.DETAILS_USERNAME, username);
81
+        addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid);
82
+        addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username);
83
+        // 内部请求来源参数清除
84
+        removeHeader(mutate, SecurityConstants.FROM_SOURCE);
82 85
         return chain.filter(exchange.mutate().request(mutate.build()).build());
83 86
     }
84 87
 
@@ -93,6 +96,11 @@ public class AuthFilter implements GlobalFilter, Ordered
93 96
         mutate.header(name, valueEncode);
94 97
     }
95 98
 
99
+    private void removeHeader(ServerHttpRequest.Builder mutate, String name)
100
+    {
101
+        mutate.headers(httpHeaders -> httpHeaders.remove(name)).build();
102
+    }
103
+
96 104
     private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg)
97 105
     {
98 106
         log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
@@ -112,7 +120,7 @@ public class AuthFilter implements GlobalFilter, Ordered
112 120
      */
113 121
     private String getToken(ServerHttpRequest request)
114 122
     {
115
-        String token = request.getHeaders().getFirst(CacheConstants.TOKEN_AUTHENTICATION);
123
+        String token = request.getHeaders().getFirst(SecurityConstants.TOKEN_AUTHENTICATION);
116 124
         return SecurityUtils.replaceTokenPrefix(token);
117 125
     }
118 126
 

+ 3 - 3
ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/ValidateCodeFilter.java

@@ -25,7 +25,7 @@ import reactor.core.publisher.Flux;
25 25
 @Component
26 26
 public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
27 27
 {
28
-    private final static String AUTH_URL = "/auth/login";
28
+    private final static String[] VALIDATE_URL = new String[] { "/auth/login", "/auth/register" };
29 29
 
30 30
     @Autowired
31 31
     private ValidateCodeService validateCodeService;
@@ -43,8 +43,8 @@ public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
43 43
         return (exchange, chain) -> {
44 44
             ServerHttpRequest request = exchange.getRequest();
45 45
 
46
-            // 非登录请求或验证码关闭,不处理
47
-            if (!StringUtils.containsIgnoreCase(request.getURI().getPath(), AUTH_URL) || !captchaProperties.getEnabled())
46
+            // 非登录/注册请求或验证码关闭,不处理
47
+            if (!StringUtils.containsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled())
48 48
             {
49 49
                 return chain.filter(exchange);
50 50
             }

+ 5 - 23
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysLogininforController.java

@@ -8,20 +8,18 @@ import org.springframework.web.bind.annotation.DeleteMapping;
8 8
 import org.springframework.web.bind.annotation.GetMapping;
9 9
 import org.springframework.web.bind.annotation.PathVariable;
10 10
 import org.springframework.web.bind.annotation.PostMapping;
11
+import org.springframework.web.bind.annotation.RequestBody;
11 12
 import org.springframework.web.bind.annotation.RequestMapping;
12
-import org.springframework.web.bind.annotation.RequestParam;
13 13
 import org.springframework.web.bind.annotation.RestController;
14
-import com.ruoyi.common.core.constant.Constants;
15
-import com.ruoyi.common.core.utils.ServletUtils;
16
-import com.ruoyi.common.core.utils.ip.IpUtils;
17 14
 import com.ruoyi.common.core.utils.poi.ExcelUtil;
18 15
 import com.ruoyi.common.core.web.controller.BaseController;
19 16
 import com.ruoyi.common.core.web.domain.AjaxResult;
20 17
 import com.ruoyi.common.core.web.page.TableDataInfo;
21 18
 import com.ruoyi.common.log.annotation.Log;
22 19
 import com.ruoyi.common.log.enums.BusinessType;
20
+import com.ruoyi.common.security.annotation.InnerAuth;
23 21
 import com.ruoyi.common.security.annotation.PreAuthorize;
24
-import com.ruoyi.system.domain.SysLogininfor;
22
+import com.ruoyi.system.api.domain.SysLogininfor;
25 23
 import com.ruoyi.system.service.ISysLogininforService;
26 24
 
27 25
 /**
@@ -72,26 +70,10 @@ public class SysLogininforController extends BaseController
72 70
         return AjaxResult.success();
73 71
     }
74 72
 
73
+    @InnerAuth
75 74
     @PostMapping
76
-    public AjaxResult add(@RequestParam("username") String username, @RequestParam("status") String status,
77
-            @RequestParam("message") String message)
75
+    public AjaxResult add(@RequestBody SysLogininfor logininfor)
78 76
     {
79
-        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
80
-
81
-        // 封装对象
82
-        SysLogininfor logininfor = new SysLogininfor();
83
-        logininfor.setUserName(username);
84
-        logininfor.setIpaddr(ip);
85
-        logininfor.setMsg(message);
86
-        // 日志状态
87
-        if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status))
88
-        {
89
-            logininfor.setStatus("0");
90
-        }
91
-        else if (Constants.LOGIN_FAIL.equals(status))
92
-        {
93
-            logininfor.setStatus("1");
94
-        }
95 77
         return toAjax(logininforService.insertLogininfor(logininfor));
96 78
     }
97 79
 }

+ 2 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysOperlogController.java

@@ -17,6 +17,7 @@ import com.ruoyi.common.core.web.domain.AjaxResult;
17 17
 import com.ruoyi.common.core.web.page.TableDataInfo;
18 18
 import com.ruoyi.common.log.annotation.Log;
19 19
 import com.ruoyi.common.log.enums.BusinessType;
20
+import com.ruoyi.common.security.annotation.InnerAuth;
20 21
 import com.ruoyi.common.security.annotation.PreAuthorize;
21 22
 import com.ruoyi.system.api.domain.SysOperLog;
22 23
 import com.ruoyi.system.service.ISysOperLogService;
@@ -69,6 +70,7 @@ public class SysOperlogController extends BaseController
69 70
         return AjaxResult.success();
70 71
     }
71 72
 
73
+    @InnerAuth
72 74
     @PostMapping
73 75
     public AjaxResult add(@RequestBody SysOperLog operLog)
74 76
     {

+ 25 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java

@@ -27,10 +27,12 @@ import com.ruoyi.common.core.web.domain.AjaxResult;
27 27
 import com.ruoyi.common.core.web.page.TableDataInfo;
28 28
 import com.ruoyi.common.log.annotation.Log;
29 29
 import com.ruoyi.common.log.enums.BusinessType;
30
+import com.ruoyi.common.security.annotation.InnerAuth;
30 31
 import com.ruoyi.common.security.annotation.PreAuthorize;
31 32
 import com.ruoyi.system.api.domain.SysRole;
32 33
 import com.ruoyi.system.api.domain.SysUser;
33 34
 import com.ruoyi.system.api.model.LoginUser;
35
+import com.ruoyi.system.service.ISysConfigService;
34 36
 import com.ruoyi.system.service.ISysPermissionService;
35 37
 import com.ruoyi.system.service.ISysPostService;
36 38
 import com.ruoyi.system.service.ISysRoleService;
@@ -57,6 +59,9 @@ public class SysUserController extends BaseController
57 59
     @Autowired
58 60
     private ISysPermissionService permissionService;
59 61
 
62
+    @Autowired
63
+    private ISysConfigService configService;
64
+
60 65
     /**
61 66
      * 获取用户列表
62 67
      */
@@ -101,6 +106,7 @@ public class SysUserController extends BaseController
101 106
     /**
102 107
      * 获取当前用户信息
103 108
      */
109
+    @InnerAuth
104 110
     @GetMapping("/info/{username}")
105 111
     public R<LoginUser> info(@PathVariable("username") String username)
106 112
     {
@@ -121,6 +127,25 @@ public class SysUserController extends BaseController
121 127
     }
122 128
 
123 129
     /**
130
+     * 注册用户信息
131
+     */
132
+    @InnerAuth
133
+    @PostMapping("/register")
134
+    public R<Boolean> register(@RequestBody SysUser sysUser)
135
+    {
136
+        String username = sysUser.getUserName();
137
+        if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
138
+        {
139
+            return R.fail("当前系统没有开启注册功能!");
140
+        }
141
+        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(username)))
142
+        {
143
+            return R.fail("保存用户'" + username + "'失败,注册账号已存在");
144
+        }
145
+        return R.ok(userService.registerUser(sysUser));
146
+    }
147
+
148
+    /**
124 149
      * 获取用户信息
125 150
      * 
126 151
      * @return 用户信息

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java

@@ -1,7 +1,7 @@
1 1
 package com.ruoyi.system.mapper;
2 2
 
3 3
 import java.util.List;
4
-import com.ruoyi.system.domain.SysLogininfor;
4
+import com.ruoyi.system.api.domain.SysLogininfor;
5 5
 
6 6
 /**
7 7
  * 系统访问日志情况信息 数据层

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java

@@ -1,7 +1,7 @@
1 1
 package com.ruoyi.system.service;
2 2
 
3 3
 import java.util.List;
4
-import com.ruoyi.system.domain.SysLogininfor;
4
+import com.ruoyi.system.api.domain.SysLogininfor;
5 5
 
6 6
 /**
7 7
  * 系统访问日志情况信息 服务层

+ 8 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java

@@ -106,6 +106,14 @@ public interface ISysUserService
106 106
     public int insertUser(SysUser user);
107 107
 
108 108
     /**
109
+     * 注册用户信息
110
+     * 
111
+     * @param user 用户信息
112
+     * @return 结果
113
+     */
114
+    public boolean registerUser(SysUser user);
115
+
116
+    /**
109 117
      * 修改用户信息
110 118
      * 
111 119
      * @param user 用户信息

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java

@@ -3,7 +3,7 @@ package com.ruoyi.system.service.impl;
3 3
 import java.util.List;
4 4
 import org.springframework.beans.factory.annotation.Autowired;
5 5
 import org.springframework.stereotype.Service;
6
-import com.ruoyi.system.domain.SysLogininfor;
6
+import com.ruoyi.system.api.domain.SysLogininfor;
7 7
 import com.ruoyi.system.mapper.SysLogininforMapper;
8 8
 import com.ruoyi.system.service.ISysLogininforService;
9 9
 

+ 11 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -247,6 +247,17 @@ public class SysUserServiceImpl implements ISysUserService
247 247
     }
248 248
 
249 249
     /**
250
+     * 注册用户信息
251
+     * 
252
+     * @param user 用户信息
253
+     * @return 结果
254
+     */
255
+    public boolean registerUser(SysUser user)
256
+    {
257
+        return userMapper.insertUser(user) > 0;
258
+    }
259
+
260
+    /**
250 261
      * 修改保存用户信息
251 262
      * 
252 263
      * @param user 用户信息

+ 12 - 0
ruoyi-ui/src/api/login.js

@@ -9,6 +9,18 @@ export function login(username, password, code, uuid) {
9 9
   })
10 10
 }
11 11
 
12
+// 注册方法
13
+export function register(data) {
14
+  return request({
15
+    url: '/auth/register',
16
+    headers: {
17
+      isToken: false
18
+    },
19
+    method: 'post',
20
+    data: data
21
+  })
22
+}
23
+
12 24
 // 刷新方法
13 25
 export function refreshToken() {
14 26
   return request({

+ 5 - 0
ruoyi-ui/src/router/index.js

@@ -44,6 +44,11 @@ export const constantRoutes = [
44 44
     hidden: true
45 45
   },
46 46
   {
47
+    path: '/register',
48
+    component: (resolve) => require(['@/views/register'], resolve),
49
+    hidden: true
50
+  },
51
+  {
47 52
     path: '/404',
48 53
     component: (resolve) => require(['@/views/error/404'], resolve),
49 54
     hidden: true

+ 9 - 3
ruoyi-ui/src/views/login.vue

@@ -44,6 +44,9 @@
44 44
           <span v-if="!loading">登 录</span>
45 45
           <span v-else>登 录 中...</span>
46 46
         </el-button>
47
+        <div style="float: right;" v-if="register">
48
+          <router-link class="link-type" :to="'/register'">立即注册</router-link>
49
+        </div>
47 50
       </el-form-item>
48 51
     </el-form>
49 52
     <!--  底部  -->
@@ -73,15 +76,18 @@ export default {
73 76
       },
74 77
       loginRules: {
75 78
         username: [
76
-          { required: true, trigger: "blur", message: "用户名不能为空" }
79
+          { required: true, trigger: "blur", message: "请输入您的账号" }
77 80
         ],
78 81
         password: [
79
-          { required: true, trigger: "blur", message: "密码不能为空" }
82
+          { required: true, trigger: "blur", message: "请输入您的密码" }
80 83
         ],
81
-        code: [{ required: true, trigger: "change", message: "验证码不能为空" }]
84
+        code: [{ required: true, trigger: "change", message: "请输入验证码" }]
82 85
       },
83 86
       loading: false,
87
+      // 验证码开关
84 88
       captchaOnOff: true,
89
+      // 注册开关
90
+      register: false,
85 91
       redirect: undefined
86 92
     };
87 93
   },

+ 208 - 0
ruoyi-ui/src/views/register.vue

@@ -0,0 +1,208 @@
1
+<template>
2
+  <div class="register">
3
+    <el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
4
+      <h3 class="title">若依后台管理系统</h3>
5
+      <el-form-item prop="username">
6
+        <el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
7
+          <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
8
+        </el-input>
9
+      </el-form-item>
10
+      <el-form-item prop="password">
11
+        <el-input
12
+          v-model="registerForm.password"
13
+          type="password"
14
+          auto-complete="off"
15
+          placeholder="密码"
16
+          @keyup.enter.native="handleRegister"
17
+        >
18
+          <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
19
+        </el-input>
20
+      </el-form-item>
21
+      <el-form-item prop="confirmPassword">
22
+        <el-input
23
+          v-model="registerForm.confirmPassword"
24
+          type="password"
25
+          auto-complete="off"
26
+          placeholder="确认密码"
27
+          @keyup.enter.native="handleRegister"
28
+        >
29
+          <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
30
+        </el-input>
31
+      </el-form-item>
32
+      <el-form-item prop="code" v-if="captchaOnOff">
33
+        <el-input
34
+          v-model="registerForm.code"
35
+          auto-complete="off"
36
+          placeholder="验证码"
37
+          style="width: 63%"
38
+          @keyup.enter.native="handleRegister"
39
+        >
40
+          <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
41
+        </el-input>
42
+        <div class="register-code">
43
+          <img :src="codeUrl" @click="getCode" class="register-code-img"/>
44
+        </div>
45
+      </el-form-item>
46
+      <el-form-item style="width:100%;">
47
+        <el-button
48
+          :loading="loading"
49
+          size="medium"
50
+          type="primary"
51
+          style="width:100%;"
52
+          @click.native.prevent="handleRegister"
53
+        >
54
+          <span v-if="!loading">注 册</span>
55
+          <span v-else>注 册 中...</span>
56
+        </el-button>
57
+        <div style="float: right;">
58
+          <router-link class="link-type" :to="'/login'">使用已有账户登录</router-link>
59
+        </div>
60
+      </el-form-item>
61
+    </el-form>
62
+    <!--  底部  -->
63
+    <div class="el-register-footer">
64
+      <span>Copyright © 2018-2021 ruoyi.vip All Rights Reserved.</span>
65
+    </div>
66
+  </div>
67
+</template>
68
+
69
+<script>
70
+import { getCodeImg, register } from "@/api/login";
71
+
72
+export default {
73
+  name: "Register",
74
+  data() {
75
+    const equalToPassword = (rule, value, callback) => {
76
+      if (this.registerForm.password !== value) {
77
+        callback(new Error("两次输入的密码不一致"));
78
+      } else {
79
+        callback();
80
+      }
81
+    };
82
+    return {
83
+      codeUrl: "",
84
+      registerForm: {
85
+        username: "",
86
+        password: "",
87
+        confirmPassword: "",
88
+        code: "",
89
+        uuid: ""
90
+      },
91
+      registerRules: {
92
+        username: [
93
+          { required: true, trigger: "blur", message: "请输入您的账号" },
94
+          { min: 2, max: 20, message: '用户账号长度必须介于 2 和 20 之间', trigger: 'blur' }
95
+        ],
96
+        password: [
97
+          { required: true, trigger: "blur", message: "请输入您的密码" },
98
+          { min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }
99
+        ],
100
+        confirmPassword: [
101
+          { required: true, trigger: "blur", message: "请再次输入您的密码" },
102
+          { required: true, validator: equalToPassword, trigger: "blur" }
103
+        ],
104
+        code: [{ required: true, trigger: "change", message: "请输入验证码" }]
105
+      },
106
+      loading: false,
107
+      captchaOnOff: true
108
+    };
109
+  },
110
+  created() {
111
+    this.getCode();
112
+  },
113
+  methods: {
114
+    getCode() {
115
+      getCodeImg().then(res => {
116
+        this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff;
117
+        if (this.captchaOnOff) {
118
+          this.codeUrl = "data:image/gif;base64," + res.img;
119
+          this.registerForm.uuid = res.uuid;
120
+        }
121
+      });
122
+    },
123
+    handleRegister() {
124
+      this.$refs.registerForm.validate(valid => {
125
+        if (valid) {
126
+          this.loading = true;
127
+          register(this.registerForm).then(res => {
128
+            const username = this.registerForm.username;
129
+            this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
130
+              dangerouslyUseHTMLString: true
131
+            }).then(() => {
132
+              this.$router.push("/login");
133
+            }).catch(() => {});
134
+          }).catch(() => {
135
+            this.loading = false;
136
+            if (this.captchaOnOff) {
137
+              this.getCode();
138
+            }
139
+          })
140
+        }
141
+      });
142
+    }
143
+  }
144
+};
145
+</script>
146
+
147
+<style rel="stylesheet/scss" lang="scss">
148
+.register {
149
+  display: flex;
150
+  justify-content: center;
151
+  align-items: center;
152
+  height: 100%;
153
+  background-image: url("../assets/images/login-background.jpg");
154
+  background-size: cover;
155
+}
156
+.title {
157
+  margin: 0px auto 30px auto;
158
+  text-align: center;
159
+  color: #707070;
160
+}
161
+
162
+.register-form {
163
+  border-radius: 6px;
164
+  background: #ffffff;
165
+  width: 400px;
166
+  padding: 25px 25px 5px 25px;
167
+  .el-input {
168
+    height: 38px;
169
+    input {
170
+      height: 38px;
171
+    }
172
+  }
173
+  .input-icon {
174
+    height: 39px;
175
+    width: 14px;
176
+    margin-left: 2px;
177
+  }
178
+}
179
+.register-tip {
180
+  font-size: 13px;
181
+  text-align: center;
182
+  color: #bfbfbf;
183
+}
184
+.register-code {
185
+  width: 33%;
186
+  height: 38px;
187
+  float: right;
188
+  img {
189
+    cursor: pointer;
190
+    vertical-align: middle;
191
+  }
192
+}
193
+.el-register-footer {
194
+  height: 40px;
195
+  line-height: 40px;
196
+  position: fixed;
197
+  bottom: 0;
198
+  width: 100%;
199
+  text-align: center;
200
+  color: #fff;
201
+  font-family: Arial;
202
+  font-size: 12px;
203
+  letter-spacing: 1px;
204
+}
205
+.register-code-img {
206
+  height: 38px;
207
+}
208
+</style>

Файловите разлики са ограничени, защото са твърде много
+ 216 - 216
sql/ry_config_20210728.sql