fix(auth):App注册接口空实现,补全手机号+短信验证码注册链路

1.AppTokenController.register改为透传完整LoginDTO
2.TokenLoginApplicationService.register原为TODO空壳(仅格式校验直接返回成功),现补全:注册短信验证码校验(SMS_REGISTER redis)→域名解析一级组织→按手机号查重→复用registerAddUser创建用户(含默认角色/YMS同步)→注册成功清验证码并记录日志
3.配套网关白名单(/auth/app/register,/auth/app/getOrganizationByPath/**)需在Nacos发布,不入库
This commit is contained in:
rcx
2026-08-18 18:09:18 +08:00
parent 6661c016e8
commit 0ff327a071
2 changed files with 57 additions and 24 deletions
@@ -179,34 +179,67 @@ public class TokenLoginApplicationService {
} }
/** /**
* 注册 * App注册(手机号 + 注册短信验证码 + 密码)
*/ */
public void register(String username, String password) { public void register(LoginDTO loginDTO) {
// 用户名或密码为空 错误 String userPhone = loginDTO.getUserPhone(); // LoginDTO.java:27-28
if (StringUtils.isAnyBlank(username, password)) { String verificationCode = loginDTO.getVerificationCode(); // LoginDTO.java:30-31
throw new ServiceException("用户/密码必须填写"); String password = loginDTO.getPassword();
// 1. 基础校验
if (StringUtils.isAnyBlank(userPhone, verificationCode, password)) {
throw new ServiceException("手机号、验证码、密码必须填写");
} }
if (username.length() < UserConstants.USERNAME_MIN_LENGTH if (!RegexUtil.isPhoneLegal(userPhone)) {
|| username.length() > UserConstants.USERNAME_MAX_LENGTH) { throw new DigitalLogisticsException(UserError.USER_PHONE_REG_ERROR);
throw new ServiceException("账户长度必须在2到20个字符之间");
}
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
throw new ServiceException("密码长度必须在5到20个字符之间");
} }
// 注册用户信息 // 2. 校验注册短信验证码(发送时写入 redis,见 SmsApplicationService.java:112, :165
SysUser sysUser = new SysUser(); String key = CacheConstants.SMS_REGISTER + userPhone; // "sms_register:" CacheConstants.java:51
sysUser.setUserName(username); Object cache = redisService.getCacheObject(key);
sysUser.setNickName(username); if (cache == null || !ObjectUtil.equal(String.valueOf(cache), verificationCode)) {
sysUser.setPassword(SecurityUtils.encryptPassword(password)); recordLogininfor(userPhone, Constants.LOGIN_FAIL, "注册验证码错误", 1);
//TODO app注册没写 throw new ServiceException("验证码错误或已过期");
/*R<?> registerResult = userServiceFeign.registerUserInfo(sysUser, SecurityConstants.INNER); }
// 3. 域名 → 一级组织(与 loginByVerificationCode :103-110 一致)
String path = loginDTO.getPath();
AjaxResult topOrganizationIdR = organizationServiceFeign.getOrganizationByPath(path);
if (ObjectUtil.isNull(topOrganizationIdR) || ObjectUtil.isNull(topOrganizationIdR.get("data"))) {
throw new ServiceException("组织不存在,请检查登录域名");
}
SysTenantsPo sysTenantsPo = JSON.parseObject(JSON.toJSONString(topOrganizationIdR.get("data")), SysTenantsPo.class);
Long topOrganizationId = sysTenantsPo.getOrganizationId();
Long selectedOrgId = loginDTO.getOrganizationId(); // LoginDTO.java:37-38App 选择组织时传
Long organizationId = (selectedOrgId != null) ? selectedOrgId : topOrganizationId;
// 4. 手机号已注册则直接提示(UserMapper.xml:199 按 user_phone+top_organization_id 查)
UserDTO query = new UserDTO();
query.setUserPhone(userPhone);
query.setTopOrganizationId(topOrganizationId);
R<LoginUser> exist = userServiceFeign.getUserByTopOrganizationUserPhone(query, SecurityConstants.INNER);
if (exist != null && exist.getData() != null && exist.getData().getUserPo() != null) {
throw new ServiceException("该手机号已注册,请直接登录");
}
// 5. 创建用户(复用验证码登录自动注册的同一链路:
// auth feign UserServiceFeign.java:47-48 → user-center UserAPI.java:332-336
// → UserApplicationService.registerAddUser:1820-1927,内部已处理默认角色/YMS同步)
UserDTO userDTO = new UserDTO();
userDTO.setUserPhone(userPhone);
userDTO.setUserPassword(SecurityUtils.encryptPassword(password));
userDTO.setTopOrganizationId(topOrganizationId);
userDTO.setOrganizationId(organizationId);
userDTO.setOrganizationName(StringUtils.isNotBlank(loginDTO.getOrganizationName())
? loginDTO.getOrganizationName() : sysTenantsPo.getOrganizationName());
R<LoginUser> registerResult = userServiceFeign.registerAddUser(userDTO, SecurityConstants.INNER);
if (R.FAIL == registerResult.getCode()) { if (R.FAIL == registerResult.getCode()) {
throw new ServiceException(registerResult.getMsg()); throw new ServiceException(registerResult.getMsg());
}*/ }
// recordLogininfor(username, Constants.REGISTER, "注册成功");
// 6. 注册成功后清掉验证码并记日志
redisService.deleteObject(key);
recordLogininfor(userPhone, Constants.REGISTER, "注册成功", 2);
} }
/** /**
@@ -72,9 +72,9 @@ public class AppTokenController extends BaseController {
@PostMapping("register") @PostMapping("register")
public R<?> register(@RequestBody LoginDTO loginDTO) { public R<?> register(@RequestBody LoginDTO loginDTO) {
// 用户注册 // 用户注册(手机号+短信验证码+密码)
tokenLoginApplicationService.register(loginDTO.getUsername(), loginDTO.getPassword()); tokenLoginApplicationService.register(loginDTO);
return R.ok(); return R.ok("注册成功");
} }
/** /**