Pārlūkot izejas kodu

重构手机号登录接口

tsurumure 8 mēneši atpakaļ
vecāks
revīzija
e5b919072c

+ 102 - 102
src/main/java/com/backendsys/controller/Systems/SysUserRoleV1Controller.java

@@ -1,106 +1,106 @@
-package com.backendsys.controller.Systems;
-
-import cn.hutool.core.collection.CollUtil;
-import com.backendsys.aspect.QueryNullCheck;
-import com.backendsys.aspect.QueryNullCheckAspect;
-import com.backendsys.entity.System.SysUserRoleDTO;
-import com.backendsys.service.System.SysUserRoleModuleService;
-import com.backendsys.service.System.SysUserRoleService;
-import com.backendsys.utils.response.Result;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 系统用户角色
- */
-@Validated
-@RestController
-public class SysUserRoleV1Controller {
-    @Autowired
-    private SysUserRoleService sysUserRoleService;
-
-    @Autowired
-    private SysUserRoleModuleService sysUserRoleModuleService;
-
-    // 判断 role.modules: [{ id: 1 }, { id: 2 }],是否有重复值
-    //public boolean hasDuplicateIds(List<LinkedHashMap<String, Object>> modules) {
-    //    List<Object> ids = CollUtil.getFieldValues(modules, "id");
-    //    return CollUtil.isNotEmpty(ids) && ids.size() != CollUtil.distinct(ids).size();
-    //}
-    public boolean hasDuplicateIds(List<Object> ids) {
-        return CollUtil.isNotEmpty(ids) && ids.size() != CollUtil.distinct(ids).size();
-    }
-
-//    // @Operation(summary = "系统用户角色列表")
-//    @PreAuthorize("@ss.hasPermi('4.1')")
-//    @GetMapping("/api/system/user/getUserRole")
-//    public Result getUserRole(@Validated PageDTO pageDTO, @Validated SysUserRoleDTO sysUserRoleDTO) {
-//        return Result.success(sysUserRoleService.queryUserRole(pageDTO.getPage_num(), pageDTO.getPage_size(), sysUserRoleDTO));
-//    }
-
-    //@Operation(summary = "系统用户角色详情")
-    @PreAuthorize("@ss.hasPermi('4.1.1')")
-    @QueryNullCheck(serviceClass = SysUserRoleService.class, serviceMethod = "queryUserRoleDetail", argField = "role_id", message = "用户角色不存在")
-    @GetMapping("/api/v1/system/user/getUserRoleDetail")
-    public Result getUserRoleDetail(@Validated(SysUserRoleDTO.Detail.class) SysUserRoleDTO sysUserRoleDTO) {
-        return Result.success(QueryNullCheckAspect.getQueryResult());
-    }
-
-//    //@Operation(summary = "创建系统用户角色")
-//    @PreAuthorize("@ss.hasPermi('4.1.2')")
-//    @PostMapping("/api/system/user/createUserRole")
-//    public Result createUserRole(@Validated(SysUserRoleDTO.Create.class) @RequestBody SysUserRoleDTO sysUserRoleDTO) {
-//        // 判断 role.modules 是否重复
-//        if (hasDuplicateIds(sysUserRoleDTO.getModules())) {
-//            return Result.error(ResultEnum.DATABASE_OPERATION_FAILED.getCode(), "模块ID出现重复值");
-//        }
-//        // 创建
-//        return Result.success(sysUserRoleService.insertUserRole(sysUserRoleDTO), "创建成功");
-//    }
-
-//    //@Operation(summary = "更新系统用户角色")
-//    @PreAuthorize("@ss.hasPermi('4.1.3')")
-//    @QueryNullCheck(serviceClass = SysUserRoleService.class, serviceMethod = "queryUserRoleDetail", argField = "role_id", message = "用户角色不存在")
-//    @PutMapping("/api/system/user/updateUserRole")
-//    public Result updateUserRole(@Validated(SysUserRoleDTO.Update.class) @RequestBody SysUserRoleDTO sysUserRoleDTO) {
-//        // 判断 role.modules 是否重复
-//        if (hasDuplicateIds(sysUserRoleDTO.getModules())) {
-//            return Result.error(ResultEnum.DATABASE_OPERATION_FAILED.getCode(), "模块ID出现重复值");
-//        }
-//        // 更新
-//        return Result.success(sysUserRoleService.updateUserRole(sysUserRoleDTO), "更新成功");
-//    }
-
-//    //@Operation(summary = "删除系统用户角色")
-//    @PreAuthorize("@ss.hasPermi('4.1.4')")
-//    @QueryNullCheck(serviceClass = SysUserRoleService.class, serviceMethod = "queryUserRoleDetail", argField = "role_id", message = "用户角色不存在")
-//    @DeleteMapping("/api/system/user/deleteUserRole")
-//    public Result deleteUserRole(@Validated(SysUserRoleDTO.Delete.class) @RequestBody SysUserRoleDTO sysUserRoleDTO) {
+//package com.backendsys.controller.Systems;
 //
-//        // 如果角色ID: 1管理员, 2游客,则不可删除
-//        Long role_id = sysUserRoleDTO.getRole_id();
-//        Set<Long> filterRoles = new HashSet<>(Arrays.asList(1L, 2L));
-//        if (filterRoles.contains(role_id)) {
-//            return Result.error(ResultEnum.DATABASE_OPERATION_FAILED.getCode(), "该角色不可删除");
-//        }
+//import cn.hutool.core.collection.CollUtil;
+//import com.backendsys.aspect.QueryNullCheck;
+//import com.backendsys.aspect.QueryNullCheckAspect;
+//import com.backendsys.entity.System.SysUserRoleDTO;
+//import com.backendsys.service.System.SysUserRoleModuleService;
+//import com.backendsys.service.System.SysUserRoleService;
+//import com.backendsys.utils.response.Result;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.security.access.prepost.PreAuthorize;
+//import org.springframework.validation.annotation.Validated;
+//import org.springframework.web.bind.annotation.*;
 //
-//        // 判断角色是否有关联用户,如有则不可删除
-//        Map<String, Object> query = QueryNullCheckAspect.getQueryResult();
-//        Long user_count = (Long) query.get("user_count");
-//        if (user_count != 0) {
-//            return Result.error(ResultEnum.DATABASE_OPERATION_FAILED.getCode(), "角色已关联 " + user_count + " 个用户,请解除关联后再删除");
-//        }
-//        // 删除用户 (物理删除)
-//        return Result.success(sysUserRoleService.deleteUserRole(sysUserRoleDTO), "删除成功");
-//    }
+//import java.util.List;
+//
+///**
+// * 系统用户角色
+// */
+//@Validated
+//@RestController
+//public class SysUserRoleV1Controller {
+//    @Autowired
+//    private SysUserRoleService sysUserRoleService;
+//
+//    @Autowired
+//    private SysUserRoleModuleService sysUserRoleModuleService;
 //
-//    @PreAuthorize("@ss.hasPermi('4.1.5')")
-//    @GetMapping("/api/system/user/getUserRoleModule")
-//    public Result getUserRoleModule() {
-//        return Result.success(sysUserRoleModuleService.queryUserRoleModule());
+//    // 判断 role.modules: [{ id: 1 }, { id: 2 }],是否有重复值
+//    //public boolean hasDuplicateIds(List<LinkedHashMap<String, Object>> modules) {
+//    //    List<Object> ids = CollUtil.getFieldValues(modules, "id");
+//    //    return CollUtil.isNotEmpty(ids) && ids.size() != CollUtil.distinct(ids).size();
+//    //}
+//    public boolean hasDuplicateIds(List<Object> ids) {
+//        return CollUtil.isNotEmpty(ids) && ids.size() != CollUtil.distinct(ids).size();
 //    }
-}
+//
+////    // @Operation(summary = "系统用户角色列表")
+////    @PreAuthorize("@ss.hasPermi('4.1')")
+////    @GetMapping("/api/system/user/getUserRole")
+////    public Result getUserRole(@Validated PageDTO pageDTO, @Validated SysUserRoleDTO sysUserRoleDTO) {
+////        return Result.success(sysUserRoleService.queryUserRole(pageDTO.getPage_num(), pageDTO.getPage_size(), sysUserRoleDTO));
+////    }
+//
+//    //@Operation(summary = "系统用户角色详情")
+////    @PreAuthorize("@ss.hasPermi('4.1.1')")
+////    @QueryNullCheck(serviceClass = SysUserRoleService.class, serviceMethod = "queryUserRoleDetail", argField = "role_id", message = "用户角色不存在")
+////    @GetMapping("/api/v1/system/user/getUserRoleDetail")
+////    public Result getUserRoleDetail(@Validated(SysUserRoleDTO.Detail.class) SysUserRoleDTO sysUserRoleDTO) {
+////        return Result.success(QueryNullCheckAspect.getQueryResult());
+////    }
+//
+////    //@Operation(summary = "创建系统用户角色")
+////    @PreAuthorize("@ss.hasPermi('4.1.2')")
+////    @PostMapping("/api/system/user/createUserRole")
+////    public Result createUserRole(@Validated(SysUserRoleDTO.Create.class) @RequestBody SysUserRoleDTO sysUserRoleDTO) {
+////        // 判断 role.modules 是否重复
+////        if (hasDuplicateIds(sysUserRoleDTO.getModules())) {
+////            return Result.error(ResultEnum.DATABASE_OPERATION_FAILED.getCode(), "模块ID出现重复值");
+////        }
+////        // 创建
+////        return Result.success(sysUserRoleService.insertUserRole(sysUserRoleDTO), "创建成功");
+////    }
+//
+////    //@Operation(summary = "更新系统用户角色")
+////    @PreAuthorize("@ss.hasPermi('4.1.3')")
+////    @QueryNullCheck(serviceClass = SysUserRoleService.class, serviceMethod = "queryUserRoleDetail", argField = "role_id", message = "用户角色不存在")
+////    @PutMapping("/api/system/user/updateUserRole")
+////    public Result updateUserRole(@Validated(SysUserRoleDTO.Update.class) @RequestBody SysUserRoleDTO sysUserRoleDTO) {
+////        // 判断 role.modules 是否重复
+////        if (hasDuplicateIds(sysUserRoleDTO.getModules())) {
+////            return Result.error(ResultEnum.DATABASE_OPERATION_FAILED.getCode(), "模块ID出现重复值");
+////        }
+////        // 更新
+////        return Result.success(sysUserRoleService.updateUserRole(sysUserRoleDTO), "更新成功");
+////    }
+//
+////    //@Operation(summary = "删除系统用户角色")
+////    @PreAuthorize("@ss.hasPermi('4.1.4')")
+////    @QueryNullCheck(serviceClass = SysUserRoleService.class, serviceMethod = "queryUserRoleDetail", argField = "role_id", message = "用户角色不存在")
+////    @DeleteMapping("/api/system/user/deleteUserRole")
+////    public Result deleteUserRole(@Validated(SysUserRoleDTO.Delete.class) @RequestBody SysUserRoleDTO sysUserRoleDTO) {
+////
+////        // 如果角色ID: 1管理员, 2游客,则不可删除
+////        Long role_id = sysUserRoleDTO.getRole_id();
+////        Set<Long> filterRoles = new HashSet<>(Arrays.asList(1L, 2L));
+////        if (filterRoles.contains(role_id)) {
+////            return Result.error(ResultEnum.DATABASE_OPERATION_FAILED.getCode(), "该角色不可删除");
+////        }
+////
+////        // 判断角色是否有关联用户,如有则不可删除
+////        Map<String, Object> query = QueryNullCheckAspect.getQueryResult();
+////        Long user_count = (Long) query.get("user_count");
+////        if (user_count != 0) {
+////            return Result.error(ResultEnum.DATABASE_OPERATION_FAILED.getCode(), "角色已关联 " + user_count + " 个用户,请解除关联后再删除");
+////        }
+////        // 删除用户 (物理删除)
+////        return Result.success(sysUserRoleService.deleteUserRole(sysUserRoleDTO), "删除成功");
+////    }
+////
+////    @PreAuthorize("@ss.hasPermi('4.1.5')")
+////    @GetMapping("/api/system/user/getUserRoleModule")
+////    public Result getUserRoleModule() {
+////        return Result.success(sysUserRoleModuleService.queryUserRoleModule());
+////    }
+//}

+ 11 - 1
src/main/java/com/backendsys/modules/system/controller/SysAuthV2Controller.java

@@ -4,6 +4,7 @@ import com.backendsys.aspect.RateLimiting;
 import com.backendsys.entity.System.SysUserDTO;
 import com.backendsys.modules.common.utils.Result;
 import com.backendsys.modules.system.entity.SysAuth;
+import com.backendsys.modules.system.entity.SysAuthPhone;
 import com.backendsys.modules.system.entity.SysMobileArea;
 import com.backendsys.modules.system.service.SysAuthV2Service;
 import io.swagger.v3.oas.annotations.Operation;
@@ -39,11 +40,20 @@ public class SysAuthV2Controller {
         return Result.success().put("data", sysAuthV2Service.getMobileAreaList(sysMobileArea));
     }
 
-    @Operation(summary = "系统用户登录")
+    @Operation(summary = "系统用户登录 (用户名)")
     @PostMapping(value = "/api/system/auth/login")
     // @RateLimiting(key = "systemLogin", limit = 5) // 限流?
     public Result systemLogin(@Validated(SysAuth.Login.class) @RequestBody SysAuth sysAuth) {
         return Result.success().put("data", sysAuthV2Service.login(sysAuth));
     }
 
+    /**
+     * 登录 (手机号码)
+     */
+    @PostMapping(value = "/api/v2/system/auth/loginWithPhone")
+//    @RateLimiting(key = "systemLoginWithPhone", limit = 5)
+    public Result systemLoginWithPhone(@Validated(SysAuthPhone.Login.class) @RequestBody SysAuthPhone sysAuthPhone) {
+        return Result.success().put("data", sysAuthV2Service.loginWithPhone(sysAuthPhone));
+    }
+
 }

+ 33 - 0
src/main/java/com/backendsys/modules/system/entity/SysAuthPhone.java

@@ -0,0 +1,33 @@
+package com.backendsys.modules.system.entity;
+
+import com.backendsys.entity.validator.Phone;
+import jakarta.validation.constraints.*;
+import lombok.Data;
+
+@Data
+public class SysAuthPhone {
+
+    public static interface Login{}
+    public static interface ForgotPassword{}
+    public static interface Register{}
+    public static interface Create{}
+    public static interface Update{}
+
+    private Long user_id;
+
+    @NotEmpty(message="手机号码不能为空", groups = { Create.class, Register.class, Login.class, ForgotPassword.class })
+    @Phone(message="手机号码格式不正确", groups = { Create.class, Update.class, Login.class, ForgotPassword.class })
+    @Size(min = 9, max = 20, message = "手机号码长度在 {min}-{max} 字符", groups = { Create.class, Update.class, Login.class, ForgotPassword.class })
+    private String phone;
+
+    @NotNull(message="区号/国家码不能为空", groups = { Register.class, Login.class, ForgotPassword.class })
+    @Max(value = 999999, message = "区号/国家码长度不超过 {value} 字符", groups = { Register.class })
+    private Integer phone_area_code;
+
+    @NotNull(message="验证码不能为空", groups = { Register.class, Login.class, ForgotPassword.class })
+    @Min(value = 100000, message = "验证码长度是 6 位字符", groups = { Register.class })
+    @Max(value = 999999, message = "验证码长度是 6 位字符", groups = { Register.class })
+    private Integer phone_valid_code;
+
+    private Integer is_remember;
+}

+ 2 - 0
src/main/java/com/backendsys/modules/system/service/SysAuthV2Service.java

@@ -1,6 +1,7 @@
 package com.backendsys.modules.system.service;
 
 import com.backendsys.modules.system.entity.SysAuth;
+import com.backendsys.modules.system.entity.SysAuthPhone;
 import com.backendsys.modules.system.entity.SysMobileArea;
 import com.backendsys.modules.system.entity.SysUserInfo;
 import jakarta.servlet.http.HttpServletRequest;
@@ -16,5 +17,6 @@ public interface SysAuthV2Service {
     List<SysMobileArea> getMobileAreaList(SysMobileArea sysMobileArea);
 
     SysUserInfo login(SysAuth sysAuth);
+    SysUserInfo loginWithPhone(SysAuthPhone sysAuthPhone);
 
 }

+ 56 - 18
src/main/java/com/backendsys/modules/system/service/impl/SysAuthV2ServiceImpl.java

@@ -12,10 +12,7 @@ import com.backendsys.modules.common.config.security.utils.JwtUtil;
 import com.backendsys.modules.system.dao.SysMobileAreaDao;
 import com.backendsys.modules.system.dao.SysUserDao;
 import com.backendsys.modules.system.dao.SysUserInfoDao;
-import com.backendsys.modules.system.entity.SysAuth;
-import com.backendsys.modules.system.entity.SysMobileArea;
-import com.backendsys.modules.system.entity.SysUser;
-import com.backendsys.modules.system.entity.SysUserInfo;
+import com.backendsys.modules.system.entity.*;
 import com.backendsys.modules.system.service.SysAuthV2Service;
 import com.backendsys.modules.system.service.SysUserV2Service;
 import com.backendsys.utils.response.ResultEnum;
@@ -64,6 +61,8 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
     @Autowired
     private SysMobileAreaDao sysMobileAreaDao;
 
+    @Value("${tencent.sms.debug}")
+    private String SMS_DEBUG;
     @Value("${CAPTCHA_DURATION}")
     private Integer CAPTCHA_DURATION;
     @Value("${TOKEN_DURATION_SYSTEM}")
@@ -111,10 +110,10 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
     }
 
     // [方法] 登录成功
-    private SysUserInfo loginSuccess(SysAuth sysAuth) {
+    private SysUserInfo loginSuccess(Long user_id, Integer is_remember) {
 
         // [查询] 登录的用户信息
-        SysUserInfo sysUserInfo = sysUserV2Service.selectUserInfo(sysAuth.getUser_id());
+        SysUserInfo sysUserInfo = sysUserV2Service.selectUserInfo(user_id);
 
         // 清除缓存
         redisUtil.delete(httpRequestUtil.getKaptchaKey());                       // 作废验证码密钥
@@ -141,8 +140,7 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
         sysUserInfoDao.updateById(sysUserInfo);
 
         // 设置 Token 过期时间
-        Integer isRemember = sysAuth.getIs_remember();
-        Integer tokenDuration = (isRemember != null && isRemember.equals(1)) ? TOKEN_DURATION_SYSTEM * 7 : TOKEN_DURATION_SYSTEM;
+        Integer tokenDuration = (is_remember != null && is_remember.equals(1)) ? TOKEN_DURATION_SYSTEM * 7 : TOKEN_DURATION_SYSTEM;
         Date tokenExpiration = new Date((new Date()).getTime() + tokenDuration);
         sysUserInfo.setToken_expiration(DateUtil.format(tokenExpiration, "yyyy-MM-dd HH:mm:ss"));
 
@@ -160,32 +158,72 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
     @Transactional
     public SysUserInfo login(SysAuth sysAuth) {
 
+        String username = sysAuth.getUsername();
+        String password = sysAuth.getPassword();
+        String captcha = sysAuth.getCaptcha();
+
         // 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
-        countUtilV2.checkErrorStatus("login-error", sysAuth.getUsername());
+        countUtilV2.checkErrorStatus("login-error", username);
 
         // [Method] 判断验证码是否正确 (RedisKey: (ua + ip))
-        if (!captchaUtil.isCaptchaValid(sysAuth.getCaptcha(), httpRequestUtil.getKaptchaKey())) {
-            loginFail("验证码错误", sysAuth.getUsername(), false);
+        if (!captchaUtil.isCaptchaValid(captcha, httpRequestUtil.getKaptchaKey())) {
+            loginFail("验证码错误", username, false);
             return null;
         }
 
         // [Method] 判断 用户 是否存在 && 密码是否正确
-        SysUser sysUser = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysAuth.getUsername()));
-        if (sysUser == null) {
+        SysUser sysUserSimple = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
+        if (sysUserSimple == null) {
             // [登录失败] 用户不存在
-            loginFail("用户名或密码错误", sysAuth.getUsername(), true);
+            loginFail("用户名或密码错误", username, true);
             return null;
         } else {
 
             // [登录失败] 密码不正确
             BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
-            if (!encoder.matches(sysAuth.getPassword(), sysUser.getPassword())) {
-                loginFail("用户名或密码错误", sysAuth.getUsername(), true);
+            if (!encoder.matches(password, sysUserSimple.getPassword())) {
+                loginFail("用户名或密码错误", username, true);
             }
 
             // [登录成功]
-            sysAuth.setUser_id(sysUser.getId());
-            return loginSuccess(sysAuth);
+            return loginSuccess(sysUserSimple.getId(), sysAuth.getIs_remember());
+        }
+
+    }
+
+    @Override
+    @Transactional
+    public SysUserInfo loginWithPhone(SysAuthPhone sysAuthPhone) {
+
+        String phone = sysAuthPhone.getPhone();
+        Integer phoneAreaCode = sysAuthPhone.getPhone_area_code();
+        Integer phoneValidCode = sysAuthPhone.getPhone_valid_code();
+
+        // 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
+        countUtilV2.checkErrorStatus("login-error", sysAuthPhone.getPhone());
+
+        // [Redis] 验证码缓存
+        String redisKey = "sms-login-" + phone;
+        Integer smsCode = redisUtil.getCacheObject(redisKey);
+
+        // 判断是否发送验证码
+        if ("false".equals(SMS_DEBUG) &&smsCode == null) throw new CustException("请先发送验证码");
+        // 判断短信验证码是否错误
+        if ("false".equals(SMS_DEBUG) && !smsCode.equals(phoneValidCode)) loginFail("短信验证码错误", phone, true);
+
+        // [Method] 判断手机号是否存在
+        SysUser sysUserSimple = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhone, phone));
+        if (sysUserSimple == null) {
+            // [登录失败] 用户不存在
+            loginFail("手机号码不存在", phone, true);
+            return null;
+        } else {
+
+            // 登录成功,销毁 smsCode
+            redisUtil.delete(redisKey);
+
+            // [登录成功]
+            return loginSuccess(sysUserSimple.getId(), sysAuthPhone.getIs_remember());
         }
 
     }

+ 1 - 1
src/main/resources/application-local.yml

@@ -93,7 +93,7 @@ tencent:
     secret-id: AKIDlNn7F9tRlCWsIe7d3IOM9mAIRhsIfxAV
     secret-key: c9Zt0sa5UzQf4HNOURAetFYfehqwpolc
   sms:
-    debug: false
+    debug: true
     secret-id: AKIDITiApJZjt27AEOhzA92467Nbilw4RyRp
     secret-key: iMqEZ3hVbwUwU3cBrXCpPH27968LUViu
     sdk-app-id: 1400892090