chenshudong 3 тижнів тому
батько
коміт
5403675de0
16 змінених файлів з 534 додано та 7 видалено
  1. 54 0
      airport-admin/src/main/java/com/sundot/airport/web/controller/system/SmsController.java
  2. 10 3
      airport-admin/src/main/java/com/sundot/airport/web/controller/system/SysLoginController.java
  3. 14 0
      airport-admin/src/main/resources/application.yml
  4. 7 0
      airport-common/pom.xml
  5. 41 0
      airport-common/src/main/java/com/sundot/airport/common/config/AliyunSmsConfig.java
  6. 10 0
      airport-common/src/main/java/com/sundot/airport/common/constant/CacheConstants.java
  7. 28 2
      airport-common/src/main/java/com/sundot/airport/common/core/domain/model/LoginBody.java
  8. 35 0
      airport-common/src/main/java/com/sundot/airport/common/service/SmsService.java
  9. 190 0
      airport-common/src/main/java/com/sundot/airport/common/service/impl/AliyunSmsServiceImpl.java
  10. 1 1
      airport-framework/src/main/java/com/sundot/airport/framework/config/SecurityConfig.java
  11. 1 1
      airport-framework/src/main/java/com/sundot/airport/framework/config/WebAdminInterceptorConfig.java
  12. 111 0
      airport-framework/src/main/java/com/sundot/airport/framework/web/service/SysLoginService.java
  13. 8 0
      airport-system/src/main/java/com/sundot/airport/system/mapper/SysUserMapper.java
  14. 8 0
      airport-system/src/main/java/com/sundot/airport/system/service/ISysUserService.java
  15. 11 0
      airport-system/src/main/java/com/sundot/airport/system/service/impl/SysUserServiceImpl.java
  16. 5 0
      airport-system/src/main/resources/mapper/system/SysUserMapper.xml

+ 54 - 0
airport-admin/src/main/java/com/sundot/airport/web/controller/system/SmsController.java

@@ -0,0 +1,54 @@
1
+package com.sundot.airport.web.controller.system;
2
+
3
+import com.sundot.airport.common.core.domain.AjaxResult;
4
+import com.sundot.airport.common.service.SmsService;
5
+import com.sundot.airport.common.utils.StringUtils;
6
+import io.swagger.annotations.Api;
7
+import io.swagger.annotations.ApiOperation;
8
+import lombok.extern.slf4j.Slf4j;
9
+import org.springframework.beans.factory.annotation.Autowired;
10
+import org.springframework.web.bind.annotation.PostMapping;
11
+import org.springframework.web.bind.annotation.RequestMapping;
12
+import org.springframework.web.bind.annotation.RequestParam;
13
+import org.springframework.web.bind.annotation.RestController;
14
+
15
+/**
16
+ * 短信验证码控制器
17
+ *
18
+ * @author wangxx
19
+ */
20
+@Slf4j
21
+@RestController
22
+@RequestMapping("/sms")
23
+@Api(tags = "短信验证码管理")
24
+public class SmsController {
25
+
26
+    @Autowired
27
+    private SmsService smsService;
28
+
29
+    /**
30
+     * 发送短信验证码
31
+     *
32
+     * @param phoneNumber 手机号码
33
+     * @return 结果
34
+     */
35
+    @PostMapping("/code")
36
+    @ApiOperation("发送短信验证码")
37
+    public AjaxResult sendSmsCode(@RequestParam String phoneNumber) {
38
+        if (StringUtils.isEmpty(phoneNumber)) {
39
+            return AjaxResult.error("手机号码不能为空");
40
+        }
41
+
42
+        try {
43
+            boolean result = smsService.sendSmsCode(phoneNumber);
44
+            if (result) {
45
+                return AjaxResult.success("验证码发送成功,请注意查收短信");
46
+            } else {
47
+                return AjaxResult.error("验证码发送失败");
48
+            }
49
+        } catch (Exception e) {
50
+            log.error("发送短信验证码异常:{}", e.getMessage(), e);
51
+            return AjaxResult.error(e.getMessage());
52
+        }
53
+    }
54
+}

+ 10 - 3
airport-admin/src/main/java/com/sundot/airport/web/controller/system/SysLoginController.java

@@ -61,9 +61,16 @@ public class SysLoginController {
61 61
     @PostMapping("/login")
62 62
     public AjaxResult login(@RequestBody LoginBody loginBody) {
63 63
         AjaxResult ajax = AjaxResult.success();
64
-        // 生成令牌
65
-        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
66
-                loginBody.getUuid());
64
+        String token;
65
+        // 判断登录类型
66
+        if ("sms".equals(loginBody.getLoginType())) {
67
+            // 短信验证码登录
68
+            token = loginService.smsLogin(loginBody);
69
+        } else {
70
+            // 密码登录(默认)
71
+            token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
72
+                    loginBody.getUuid());
73
+        }
67 74
         ajax.put(Constants.TOKEN, token);
68 75
         return ajax;
69 76
     }

+ 14 - 0
airport-admin/src/main/resources/application.yml

@@ -148,3 +148,17 @@ xss:
148 148
   excludes: /system/notice
149 149
   # 匹配链接
150 150
   urlPatterns: /system/*,/monitor/*,/tool/*
151
+
152
+# 阿里云短信配置
153
+aliyun:
154
+  sms:
155
+    # AccessKey ID
156
+    accessKeyId: LTAI5t8wXQNPkEQxEk1vvUay
157
+    # AccessKey Secret
158
+    accessKeySecret: RIRVNNt5IjJ0VJqSszHk3RYZG9xAdA
159
+    # 短信签名名称
160
+    signName: 北京阳光汇点数码科技
161
+    # 短信模板 CODE
162
+    templateCode: SMS_503630027
163
+    # 是否启用短信登录
164
+    enabled: true

+ 7 - 0
airport-common/pom.xml

@@ -148,6 +148,13 @@
148 148
             <artifactId>easyexcel</artifactId>
149 149
         </dependency>
150 150
 
151
+        <!-- 阿里云短信 SDK -->
152
+        <dependency>
153
+            <groupId>com.aliyun</groupId>
154
+            <artifactId>dysmsapi20170525</artifactId>
155
+            <version>4.5.0</version>
156
+        </dependency>
157
+
151 158
     </dependencies>
152 159
 
153 160
 </project>

+ 41 - 0
airport-common/src/main/java/com/sundot/airport/common/config/AliyunSmsConfig.java

@@ -0,0 +1,41 @@
1
+package com.sundot.airport.common.config;
2
+
3
+import lombok.Data;
4
+import org.springframework.boot.context.properties.ConfigurationProperties;
5
+import org.springframework.stereotype.Component;
6
+
7
+/**
8
+ * 阿里云短信配置
9
+ *
10
+ * @author wangxx
11
+ */
12
+@Data
13
+@Component
14
+@ConfigurationProperties(prefix = "aliyun.sms")
15
+public class AliyunSmsConfig {
16
+
17
+    /**
18
+     * 访问凭证 AccessKey ID
19
+     */
20
+    private String accessKeyId;
21
+
22
+    /**
23
+     * 访问凭证 AccessKey Secret
24
+     */
25
+    private String accessKeySecret;
26
+
27
+    /**
28
+     * 短信签名名称
29
+     */
30
+    private String signName;
31
+
32
+    /**
33
+     * 短信模板 CODE
34
+     */
35
+    private String templateCode;
36
+
37
+    /**
38
+     * 是否启用短信登录(默认关闭)
39
+     */
40
+    private Boolean enabled;
41
+}

+ 10 - 0
airport-common/src/main/java/com/sundot/airport/common/constant/CacheConstants.java

@@ -50,4 +50,14 @@ public class CacheConstants {
50 50
      * 用户巡检合格率全量数据缓存
51 51
      */
52 52
     public static final String USER_CHECK_PASS_RATE_KEY = "user_check_pass_rate:";
53
+
54
+    /**
55
+     * 短信验证码 redis key
56
+     */
57
+    public static final String SMS_CODE_KEY = "sms_codes:";
58
+
59
+    /**
60
+     * 短信发送间隔 redis key
61
+     */
62
+    public static final String SMS_SEND_INTERVAL_KEY = "sms_send_interval:";
53 63
 }

+ 28 - 2
airport-common/src/main/java/com/sundot/airport/common/core/domain/model/LoginBody.java

@@ -17,15 +17,25 @@ public class LoginBody {
17 17
     private String password;
18 18
 
19 19
     /**
20
-     * 验证码
20
+     * 验证码(图形验证码或短信验证码)
21 21
      */
22 22
     private String code;
23 23
 
24 24
     /**
25
-     * 唯一标识
25
+     * 唯一标识(用于图形验证码)
26 26
      */
27 27
     private String uuid;
28 28
 
29
+    /**
30
+     * 手机号码(用于短信登录)
31
+     */
32
+    private String phoneNumber;
33
+
34
+    /**
35
+     * 登录类型:password-密码登录,sms-短信登录
36
+     */
37
+    private String loginType = "password";
38
+
29 39
     public String getUsername() {
30 40
         return username;
31 41
     }
@@ -57,4 +67,20 @@ public class LoginBody {
57 67
     public void setUuid(String uuid) {
58 68
         this.uuid = uuid;
59 69
     }
70
+
71
+    public String getPhoneNumber() {
72
+        return phoneNumber;
73
+    }
74
+
75
+    public void setPhoneNumber(String phoneNumber) {
76
+        this.phoneNumber = phoneNumber;
77
+    }
78
+
79
+    public String getLoginType() {
80
+        return loginType;
81
+    }
82
+
83
+    public void setLoginType(String loginType) {
84
+        this.loginType = loginType;
85
+    }
60 86
 }

+ 35 - 0
airport-common/src/main/java/com/sundot/airport/common/service/SmsService.java

@@ -0,0 +1,35 @@
1
+package com.sundot.airport.common.service;
2
+
3
+/**
4
+ * 短信服务接口
5
+ *
6
+ * @author wangxx
7
+ */
8
+public interface SmsService {
9
+
10
+    /**
11
+     * 发送短信验证码
12
+     *
13
+     * @param phoneNumber 手机号码
14
+     * @return 发送结果,true-成功,false-失败
15
+     */
16
+    boolean sendSmsCode(String phoneNumber);
17
+
18
+    /**
19
+     * 校验短信验证码
20
+     *
21
+     * @param phoneNumber 手机号码
22
+     * @param code        验证码
23
+     * @return 校验结果,true-成功,false-失败
24
+     */
25
+    boolean verifySmsCode(String phoneNumber, String code);
26
+
27
+    /**
28
+     * 发送自定义短信内容(用于扩展)
29
+     *
30
+     * @param phoneNumber   手机号码
31
+     * @param templateParam 模板参数(JSON 格式)
32
+     * @return 发送结果,true-成功,false-失败
33
+     */
34
+    boolean sendSms(String phoneNumber, String templateParam);
35
+}

+ 190 - 0
airport-common/src/main/java/com/sundot/airport/common/service/impl/AliyunSmsServiceImpl.java

@@ -0,0 +1,190 @@
1
+package com.sundot.airport.common.service.impl;
2
+
3
+import cn.hutool.core.util.RandomUtil;
4
+import cn.hutool.json.JSONUtil;
5
+import com.aliyun.dysmsapi20170525.Client;
6
+import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
7
+import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
8
+import com.aliyun.teaopenapi.models.Config;
9
+import com.sundot.airport.common.config.AliyunSmsConfig;
10
+import com.sundot.airport.common.constant.CacheConstants;
11
+import com.sundot.airport.common.core.redis.RedisCache;
12
+import com.sundot.airport.common.exception.ServiceException;
13
+import com.sundot.airport.common.service.SmsService;
14
+import com.sundot.airport.common.utils.StringUtils;
15
+import lombok.extern.slf4j.Slf4j;
16
+import org.springframework.beans.factory.annotation.Autowired;
17
+import org.springframework.stereotype.Service;
18
+
19
+import javax.annotation.PostConstruct;
20
+import java.util.HashMap;
21
+import java.util.Map;
22
+import java.util.concurrent.TimeUnit;
23
+
24
+/**
25
+ * 短信服务实现类
26
+ *
27
+ * @author wangxx
28
+ */
29
+@Slf4j
30
+@Service
31
+public class AliyunSmsServiceImpl implements SmsService {
32
+
33
+    @Autowired
34
+    private AliyunSmsConfig smsConfig;
35
+
36
+    @Autowired
37
+    private RedisCache redisCache;
38
+
39
+    private Client client;
40
+
41
+    /**
42
+     * 短信验证码有效期(秒)
43
+     */
44
+    private static final int CODE_EXPIRE_TIME = 300;
45
+
46
+    /**
47
+     * 短信发送间隔(秒)
48
+     */
49
+    private static final int SEND_INTERVAL = 60;
50
+
51
+    @PostConstruct
52
+    public void init() {
53
+        if (smsConfig.getEnabled()) {
54
+            try {
55
+                Config config = new Config()
56
+                        .setAccessKeyId(smsConfig.getAccessKeyId())
57
+                        .setAccessKeySecret(smsConfig.getAccessKeySecret());
58
+                // 设置 endpoint,不同地域可能不同,请根据实际情况修改
59
+                config.endpoint = "dysmsapi.aliyuncs.com";
60
+                client = new Client(config);
61
+                log.info("短信客户端初始化成功");
62
+            } catch (Exception e) {
63
+                log.error("短信客户端初始化失败:{}", e.getMessage(), e);
64
+            }
65
+        } else {
66
+            log.warn("短信登录功能未开启,跳过短信客户端初始化");
67
+        }
68
+    }
69
+
70
+    @Override
71
+    public boolean sendSmsCode(String phoneNumber) {
72
+        if (!smsConfig.getEnabled()) {
73
+            throw new ServiceException("短信登录功能暂未开启");
74
+        }
75
+
76
+        if (StringUtils.isEmpty(phoneNumber)) {
77
+            throw new ServiceException("手机号码不能为空");
78
+        }
79
+
80
+        // 校验手机号格式
81
+        if (!isValidPhone(phoneNumber)) {
82
+            throw new ServiceException("手机号码格式不正确");
83
+        }
84
+
85
+        // 检查是否发送频繁
86
+        String sendKey = CacheConstants.SMS_SEND_INTERVAL_KEY + phoneNumber;
87
+        if (redisCache.hasKey(sendKey)) {
88
+            throw new ServiceException("短信发送太过频繁,请" + getExpireTime(sendKey) + "秒后再试");
89
+        }
90
+
91
+        // 生成 6 位数字验证码
92
+        String code = RandomUtil.randomNumbers(6);
93
+
94
+        // 构建模板参数
95
+        Map<String, String> templateParam = new HashMap<>();
96
+        templateParam.put("code", code);
97
+
98
+        // 发送到阿里云短信
99
+        boolean result = sendSms(phoneNumber, JSONUtil.toJsonStr(templateParam));
100
+
101
+        if (result) {
102
+            // 存储验证码到 Redis,用于后续验证
103
+            String verifyKey = CacheConstants.SMS_CODE_KEY + phoneNumber;
104
+            redisCache.setCacheObject(verifyKey, code, CODE_EXPIRE_TIME, TimeUnit.SECONDS);
105
+
106
+            // 设置发送间隔锁
107
+            redisCache.setCacheObject(sendKey, "1", SEND_INTERVAL, TimeUnit.SECONDS);
108
+
109
+            log.info("短信验证码发送成功 - 手机号:{}, 验证码:{}", phoneNumber, code);
110
+        } else {
111
+            log.error("短信验证码发送失败 - 手机号:{}", phoneNumber);
112
+        }
113
+
114
+        return result;
115
+    }
116
+
117
+    @Override
118
+    public boolean verifySmsCode(String phoneNumber, String code) {
119
+        if (!smsConfig.getEnabled()) {
120
+            throw new ServiceException("短信登录功能暂未开启");
121
+        }
122
+
123
+        if (StringUtils.isEmpty(phoneNumber) || StringUtils.isEmpty(code)) {
124
+            throw new ServiceException("手机号或验证码不能为空");
125
+        }
126
+
127
+        String verifyKey = CacheConstants.SMS_CODE_KEY + phoneNumber;
128
+        String storedCode = redisCache.getCacheObject(verifyKey);
129
+
130
+        if (storedCode == null) {
131
+            throw new ServiceException("验证码已过期,请重新获取");
132
+        }
133
+
134
+        if (!code.equals(storedCode)) {
135
+            throw new ServiceException("验证码错误");
136
+        }
137
+
138
+        // 验证成功后删除验证码,防止重复使用
139
+        redisCache.deleteObject(verifyKey);
140
+        return true;
141
+    }
142
+
143
+    @Override
144
+    public boolean sendSms(String phoneNumber, String templateParam) {
145
+        if (!smsConfig.getEnabled()) {
146
+            throw new ServiceException("短信登录功能暂未开启");
147
+        }
148
+
149
+        try {
150
+            SendSmsRequest request = new SendSmsRequest()
151
+                    .setPhoneNumbers(phoneNumber)
152
+                    .setSignName(smsConfig.getSignName())
153
+                    .setTemplateCode(smsConfig.getTemplateCode())
154
+                    .setTemplateParam(templateParam);
155
+
156
+            SendSmsResponse response = client.sendSms(request);
157
+
158
+            // 判断发送结果
159
+            if ("OK".equals(response.getBody().getCode())) {
160
+                log.info("短信发送成功 - 手机号:{}, 请求 ID: {}", phoneNumber, response.getBody().getRequestId());
161
+                return true;
162
+            } else {
163
+                log.error("短信发送失败 - 手机号:{}, 错误码:{}, 错误信息:{}",
164
+                        phoneNumber, response.getBody().getCode(), response.getBody().getMessage());
165
+                throw new ServiceException("短信发送失败:" + response.getBody().getMessage());
166
+            }
167
+        } catch (Exception e) {
168
+            log.error("发送短信异常 - 手机号:{}, 错误:{}", phoneNumber, e.getMessage(), e);
169
+            throw new ServiceException("短信发送异常:" + e.getMessage());
170
+        }
171
+    }
172
+
173
+    /**
174
+     * 验证手机号格式
175
+     */
176
+    private boolean isValidPhone(String phoneNumber) {
177
+        if (phoneNumber == null || phoneNumber.length() != 11) {
178
+            return false;
179
+        }
180
+        String regex = "^1(3[0-9]|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$";
181
+        return phoneNumber.matches(regex);
182
+    }
183
+
184
+    /**
185
+     * 获取 Redis key 的剩余过期时间
186
+     */
187
+    private Long getExpireTime(String key) {
188
+        return redisCache.getExpire(key);
189
+    }
190
+}

+ 1 - 1
airport-framework/src/main/java/com/sundot/airport/framework/config/SecurityConfig.java

@@ -108,7 +108,7 @@ public class SecurityConfig {
108 108
                 .authorizeHttpRequests((requests) -> {
109 109
                     permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
110 110
                     // 对于登录login 注册register 验证码captchaImage 允许匿名访问
111
-                    requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
111
+                    requests.antMatchers("/login", "/register", "/captchaImage", "/sms/code").permitAll()
112 112
                             // 静态资源,可匿名访问
113 113
                             .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
114 114
                             .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

+ 1 - 1
airport-framework/src/main/java/com/sundot/airport/framework/config/WebAdminInterceptorConfig.java

@@ -21,7 +21,7 @@ public class WebAdminInterceptorConfig implements WebMvcConfigurer {
21 21
     public void addInterceptors(InterceptorRegistry registry) {
22 22
         registry.addInterceptor(requestSourceInterceptor)
23 23
                 .addPathPatterns("/**")
24
-                .excludePathPatterns("/captchaImage", "/login", "/logout");
24
+                .excludePathPatterns("/captchaImage", "/login", "/logout", "/sms/code");
25 25
     }
26 26
 
27 27
 }

+ 111 - 0
airport-framework/src/main/java/com/sundot/airport/framework/web/service/SysLoginService.java

@@ -2,6 +2,10 @@ package com.sundot.airport.framework.web.service;
2 2
 
3 3
 import javax.annotation.Resource;
4 4
 
5
+import com.sundot.airport.common.config.AliyunSmsConfig;
6
+import com.sundot.airport.common.core.domain.model.LoginBody;
7
+import com.sundot.airport.common.service.SmsService;
8
+import com.sundot.airport.common.utils.spring.SpringUtils;
5 9
 import org.springframework.beans.factory.annotation.Autowired;
6 10
 import org.springframework.security.authentication.AuthenticationManager;
7 11
 import org.springframework.security.authentication.BadCredentialsException;
@@ -52,6 +56,12 @@ public class SysLoginService {
52 56
     @Autowired
53 57
     private ISysConfigService configService;
54 58
 
59
+    @Autowired
60
+    private SmsService smsService;
61
+
62
+    @Autowired
63
+    private AliyunSmsConfig smsConfig;
64
+
55 65
     /**
56 66
      * 登录验证
57 67
      *
@@ -62,6 +72,46 @@ public class SysLoginService {
62 72
      * @return 结果
63 73
      */
64 74
     public String login(String username, String password, String code, String uuid) {
75
+        // 默认使用密码登录
76
+        return loginByPassword(username, password, code, uuid);
77
+    }
78
+
79
+    /**
80
+     * 短信验证码登录
81
+     *
82
+     * @param loginBody 登录信息
83
+     * @return 令牌
84
+     */
85
+    public String smsLogin(LoginBody loginBody) {
86
+        String phoneNumber = loginBody.getPhoneNumber();
87
+        String smsCode = loginBody.getCode();
88
+
89
+        // 校验短信验证码
90
+        validateSmsCode(phoneNumber, smsCode);
91
+
92
+        // 根据手机号查询用户
93
+        SysUser user = userService.selectUserByPhonenumber(phoneNumber);
94
+        if (user == null) {
95
+            AsyncManager.me().execute(AsyncFactory.recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
96
+            throw new UserNotExistsException();
97
+        }
98
+
99
+        // 检查用户状态
100
+        smsLoginPreCheck(user.getUserName());
101
+
102
+        // 创建登录用户信息
103
+        LoginUser loginUser = createLoginUserForSms(user);
104
+
105
+        AsyncManager.me().execute(AsyncFactory.recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
106
+        recordLoginInfo(loginUser.getUserId());
107
+        // 生成 token
108
+        return tokenService.createToken(loginUser);
109
+    }
110
+
111
+    /**
112
+     * 密码登录
113
+     */
114
+    private String loginByPassword(String username, String password, String code, String uuid) {
65 115
         // 验证码校验
66 116
         validateCaptcha(username, code, uuid);
67 117
         // 登录前置校验
@@ -117,6 +167,22 @@ public class SysLoginService {
117 167
     }
118 168
 
119 169
     /**
170
+     * 校验短信验证码
171
+     *
172
+     * @param phoneNumber 手机号码
173
+     * @param code        短信验证码
174
+     */
175
+    private void validateSmsCode(String phoneNumber, String code) {
176
+        // 检查是否开启短信登录
177
+        if (!smsConfig.getEnabled()) {
178
+            throw new ServiceException("短信登录功能暂未开启");
179
+        }
180
+
181
+        // 校验短信验证码
182
+        smsService.verifySmsCode(phoneNumber, code);
183
+    }
184
+
185
+    /**
120 186
      * 登录前置校验
121 187
      *
122 188
      * @param username 用户名
@@ -149,6 +215,51 @@ public class SysLoginService {
149 215
     }
150 216
 
151 217
     /**
218
+     * 短信登录前置校验
219
+     *
220
+     * @param username 用户名
221
+     */
222
+    public void smsLoginPreCheck(String username) {
223
+        // 用户名为空 错误
224
+        if (StringUtils.isEmpty(username)) {
225
+            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
226
+            throw new UserNotExistsException();
227
+        }
228
+        // 用户名不在指定范围内 错误
229
+        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
230
+                || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
231
+            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
232
+            throw new UserPasswordNotMatchException();
233
+        }
234
+        // IP 黑名单校验
235
+        String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
236
+        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) {
237
+            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
238
+            throw new BlackListException();
239
+        }
240
+    }
241
+
242
+    /**
243
+     * 短信登录创建登录用户
244
+     *
245
+     * @param user 系统用户
246
+     * @return 登录用户
247
+     */
248
+    private LoginUser createLoginUserForSms(SysUser user) {
249
+        // 创建登录用户信息
250
+        LoginUser loginUser = new LoginUser();
251
+        loginUser.setUserId(user.getUserId());
252
+        loginUser.setDeptId(user.getDeptId());
253
+        loginUser.setUser(user);
254
+
255
+        // 获取权限信息
256
+        SysPermissionService permissionService = SpringUtils.getBean(SysPermissionService.class);
257
+        loginUser.setPermissions(permissionService.getMenuPermission(user));
258
+
259
+        return loginUser;
260
+    }
261
+
262
+    /**
152 263
      * 记录登录信息
153 264
      *
154 265
      * @param userId 用户ID

+ 8 - 0
airport-system/src/main/java/com/sundot/airport/system/mapper/SysUserMapper.java

@@ -45,6 +45,14 @@ public interface SysUserMapper {
45 45
     public SysUser selectUserByUserName(String userName);
46 46
 
47 47
     /**
48
+     * 通过手机号查询用户
49
+     *
50
+     * @param phonenumber 手机号
51
+     * @return 用户对象信息
52
+     */
53
+    public SysUser selectUserByPhonenumber(String phonenumber);
54
+
55
+    /**
48 56
      * 通过用户ID查询用户
49 57
      *
50 58
      * @param userId 用户ID

+ 8 - 0
airport-system/src/main/java/com/sundot/airport/system/service/ISysUserService.java

@@ -50,6 +50,14 @@ public interface ISysUserService {
50 50
     public SysUser selectUserByUserName(String userName);
51 51
 
52 52
     /**
53
+     * 通过手机号查询用户
54
+     *
55
+     * @param phonenumber 手机号
56
+     * @return 用户对象信息
57
+     */
58
+    public SysUser selectUserByPhonenumber(String phonenumber);
59
+
60
+    /**
53 61
      * 通过用户ID查询用户
54 62
      *
55 63
      * @param userId 用户ID

+ 11 - 0
airport-system/src/main/java/com/sundot/airport/system/service/impl/SysUserServiceImpl.java

@@ -144,6 +144,17 @@ public class SysUserServiceImpl implements ISysUserService {
144 144
     }
145 145
 
146 146
     /**
147
+     * 通过手机号查询用户
148
+     *
149
+     * @param phonenumber 手机号
150
+     * @return 用户对象信息
151
+     */
152
+    @Override
153
+    public SysUser selectUserByPhonenumber(String phonenumber) {
154
+        return userMapper.selectUserByPhonenumber(phonenumber);
155
+    }
156
+
157
+    /**
147 158
      * 通过用户ID查询用户
148 159
      *
149 160
      * @param userId 用户ID

+ 5 - 0
airport-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -382,6 +382,11 @@
382 382
         where u.user_name = #{userName} and u.del_flag = '0'
383 383
     </select>
384 384
 
385
+    <select id="selectUserByPhonenumber" parameterType="String" resultMap="SysUserResult">
386
+        <include refid="selectUserVo"/>
387
+        where u.phonenumber = #{phonenumber} and u.del_flag = '0'
388
+    </select>
389
+
385 390
     <select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
386 391
         <include refid="selectUserVo"/>
387 392
         where u.user_id = #{userId}