fix: 手机验证码和微信手机号登录,如果用户不存在,自动创建系统用户和鱼测云用户信息。
This commit is contained in:
@@ -3,6 +3,7 @@ package com.intc.web.service.impl;
|
|||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.crypto.digest.BCrypt;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.intc.common.core.constant.Constants;
|
import com.intc.common.core.constant.Constants;
|
||||||
import com.intc.common.core.constant.GlobalConstants;
|
import com.intc.common.core.constant.GlobalConstants;
|
||||||
@@ -19,10 +20,16 @@ import com.intc.common.json.utils.JsonUtils;
|
|||||||
import com.intc.common.redis.utils.RedisUtils;
|
import com.intc.common.redis.utils.RedisUtils;
|
||||||
import com.intc.common.satoken.utils.LoginHelper;
|
import com.intc.common.satoken.utils.LoginHelper;
|
||||||
import com.intc.common.tenant.helper.TenantHelper;
|
import com.intc.common.tenant.helper.TenantHelper;
|
||||||
|
import com.intc.fishery.domain.AquUser;
|
||||||
|
import com.intc.fishery.domain.bo.AquUserBo;
|
||||||
|
import com.intc.fishery.mapper.AquUserMapper;
|
||||||
|
import com.intc.fishery.service.IAquUserService;
|
||||||
import com.intc.system.domain.SysUser;
|
import com.intc.system.domain.SysUser;
|
||||||
|
import com.intc.system.domain.bo.SysUserBo;
|
||||||
import com.intc.system.domain.vo.SysClientVo;
|
import com.intc.system.domain.vo.SysClientVo;
|
||||||
import com.intc.system.domain.vo.SysUserVo;
|
import com.intc.system.domain.vo.SysUserVo;
|
||||||
import com.intc.system.mapper.SysUserMapper;
|
import com.intc.system.mapper.SysUserMapper;
|
||||||
|
import com.intc.system.service.ISysUserService;
|
||||||
import com.intc.web.domain.vo.LoginVo;
|
import com.intc.web.domain.vo.LoginVo;
|
||||||
import com.intc.web.service.IAuthStrategy;
|
import com.intc.web.service.IAuthStrategy;
|
||||||
import com.intc.web.service.SysLoginService;
|
import com.intc.web.service.SysLoginService;
|
||||||
@@ -30,6 +37,9 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信认证策略
|
* 短信认证策略
|
||||||
*
|
*
|
||||||
@@ -42,6 +52,9 @@ public class SmsAuthStrategy implements IAuthStrategy {
|
|||||||
|
|
||||||
private final SysLoginService loginService;
|
private final SysLoginService loginService;
|
||||||
private final SysUserMapper userMapper;
|
private final SysUserMapper userMapper;
|
||||||
|
private final ISysUserService userService;
|
||||||
|
private final AquUserMapper aquUserMapper;
|
||||||
|
private final IAquUserService aquUserService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoginVo login(String body, SysClientVo client) {
|
public LoginVo login(String body, SysClientVo client) {
|
||||||
@@ -90,16 +103,149 @@ public class SmsAuthStrategy implements IAuthStrategy {
|
|||||||
return code.equals(smsCode);
|
return code.equals(smsCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据手机号加载系统用户,如果不存在则自动创建
|
||||||
|
*
|
||||||
|
* @param phonenumber 手机号
|
||||||
|
* @return 系统用户信息
|
||||||
|
*/
|
||||||
private SysUserVo loadUserByPhonenumber(String phonenumber) {
|
private SysUserVo loadUserByPhonenumber(String phonenumber) {
|
||||||
SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber));
|
SysUserVo user = userMapper.selectVoOne(
|
||||||
|
new LambdaQueryWrapper<SysUser>()
|
||||||
|
.eq(SysUser::getPhonenumber, phonenumber)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 如果用户不存在,创建新用户
|
||||||
if (ObjectUtil.isNull(user)) {
|
if (ObjectUtil.isNull(user)) {
|
||||||
log.info("登录用户:{} 不存在.", phonenumber);
|
log.info("系统中不存在该手机号的用户,自动创建新用户: phone={}", phonenumber);
|
||||||
throw new UserException("user.not.exists", phonenumber);
|
user = createNewUser(phonenumber);
|
||||||
} else if (SystemConstants.DISABLE.equals(user.getStatus())) {
|
}
|
||||||
|
|
||||||
|
// 检查用户状态
|
||||||
|
if (SystemConstants.DISABLE.equals(user.getStatus())) {
|
||||||
log.info("登录用户:{} 已被停用.", phonenumber);
|
log.info("登录用户:{} 已被停用.", phonenumber);
|
||||||
throw new UserException("user.blocked", phonenumber);
|
throw new UserException("user.blocked", phonenumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建新的系统用户
|
||||||
|
*
|
||||||
|
* @param phone 手机号
|
||||||
|
* @return 新创建的用户信息
|
||||||
|
*/
|
||||||
|
private SysUserVo createNewUser(String phone) {
|
||||||
|
try {
|
||||||
|
// 构建新用户对象
|
||||||
|
SysUserBo newUser = new SysUserBo();
|
||||||
|
// 使用手机号作为用户名
|
||||||
|
newUser.setUserName(phone);
|
||||||
|
// 使用手机号作为昵称
|
||||||
|
newUser.setNickName("用户" + phone.substring(phone.length() - 4));
|
||||||
|
// 设置手机号
|
||||||
|
newUser.setPhonenumber(phone);
|
||||||
|
// 设置用户类型为系统用户
|
||||||
|
newUser.setUserType("sys_user");
|
||||||
|
// 设置默认部门ID
|
||||||
|
newUser.setDeptId(SystemConstants.DEFAULT_DEPT_ID);
|
||||||
|
// 设置状态为正常
|
||||||
|
newUser.setStatus(SystemConstants.NORMAL);
|
||||||
|
// 设置性别为未知
|
||||||
|
newUser.setSex("2");
|
||||||
|
// 设置默认密码
|
||||||
|
newUser.setPassword(BCrypt.hashpw("yuceyun@123"));
|
||||||
|
// 设置创建人和更新人为系统
|
||||||
|
newUser.setCreateBy(0L);
|
||||||
|
newUser.setUpdateBy(0L);
|
||||||
|
|
||||||
|
// 调用用户服务创建用户
|
||||||
|
boolean success = userService.registerUser(newUser, LoginHelper.getTenantId());
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
log.error("创建新用户失败: phone={}", phone);
|
||||||
|
throw new UserException("user.register.error");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询刚创建的用户信息
|
||||||
|
SysUserVo createdUser = userMapper.selectVoOne(
|
||||||
|
new LambdaQueryWrapper<SysUser>()
|
||||||
|
.eq(SysUser::getPhonenumber, phone)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ObjectUtil.isNull(createdUser)) {
|
||||||
|
log.error("创建用户后查询失败: phone={}", phone);
|
||||||
|
throw new UserException("user.register.error");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("成功创建系统用户: phone={}, userId={}, userName={}",
|
||||||
|
phone, createdUser.getUserId(), createdUser.getUserName());
|
||||||
|
|
||||||
|
// 创建对应的鱼测云用户(AquUser)
|
||||||
|
createAquUser(createdUser);
|
||||||
|
|
||||||
|
return createdUser;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("创建新用户异常: phone={}, error={}", phone, e.getMessage(), e);
|
||||||
|
throw new UserException("user.register.error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建鱼测云用户(AquUser)
|
||||||
|
*
|
||||||
|
* @param sysUser 系统用户信息
|
||||||
|
*/
|
||||||
|
private void createAquUser(SysUserVo sysUser) {
|
||||||
|
try {
|
||||||
|
// 检查是否已存在鱼测云用户
|
||||||
|
AquUser existingAquUser = aquUserMapper.selectById(sysUser.getUserId());
|
||||||
|
if (existingAquUser != null) {
|
||||||
|
log.info("鱼测云用户已存在,跳过创建: userId={}", sysUser.getUserId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建报警电话列表(包含用户手机号)
|
||||||
|
List<String> warnPhoneList = new ArrayList<>();
|
||||||
|
if (StringUtils.isNotBlank(sysUser.getPhonenumber())) {
|
||||||
|
warnPhoneList.add(sysUser.getPhonenumber());
|
||||||
|
}
|
||||||
|
String warnPhoneJson = JsonUtils.toJsonString(warnPhoneList);
|
||||||
|
|
||||||
|
// 创建鱼测云用户对象
|
||||||
|
AquUserBo aquUserBo = new AquUserBo();
|
||||||
|
// 使用系统用户ID作为鱼测云用户ID,保持一致
|
||||||
|
aquUserBo.setId(sysUser.getUserId());
|
||||||
|
// 使用系统用户的昵称作为用户名
|
||||||
|
aquUserBo.setUserName(sysUser.getNickName());
|
||||||
|
// 设置手机号
|
||||||
|
aquUserBo.setMobilePhone(sysUser.getPhonenumber());
|
||||||
|
// 设置报警电话列表
|
||||||
|
aquUserBo.setWarnPhoneJson(warnPhoneJson);
|
||||||
|
// 非管理员
|
||||||
|
aquUserBo.setIsManager(0L);
|
||||||
|
// 没有大屏权限
|
||||||
|
aquUserBo.setHasScreen(0L);
|
||||||
|
// 备注
|
||||||
|
aquUserBo.setRemark("短信登录自动创建");
|
||||||
|
|
||||||
|
// 调用服务创建鱼测云用户
|
||||||
|
boolean success = aquUserService.insertByBo(aquUserBo);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
log.info("成功创建鱼测云用户: userId={}, userName={}, phone={}",
|
||||||
|
sysUser.getUserId(), aquUserBo.getUserName(), aquUserBo.getMobilePhone());
|
||||||
|
} else {
|
||||||
|
log.error("创建鱼测云用户失败: userId={}", sysUser.getUserId());
|
||||||
|
// 不抛异常,不影响登录流程
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("创建鱼测云用户异常: userId={}, error={}", sysUser.getUserId(), e.getMessage(), e);
|
||||||
|
// 不抛异常,不影响登录流程
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.intc.web.service.impl;
|
|||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.crypto.digest.BCrypt;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.intc.common.core.constant.SystemConstants;
|
import com.intc.common.core.constant.SystemConstants;
|
||||||
import com.intc.common.core.domain.model.LoginUser;
|
import com.intc.common.core.domain.model.LoginUser;
|
||||||
@@ -14,10 +15,15 @@ import com.intc.common.json.utils.JsonUtils;
|
|||||||
import com.intc.common.satoken.utils.LoginHelper;
|
import com.intc.common.satoken.utils.LoginHelper;
|
||||||
import com.intc.common.tenant.helper.TenantHelper;
|
import com.intc.common.tenant.helper.TenantHelper;
|
||||||
import com.intc.fishery.domain.AquUser;
|
import com.intc.fishery.domain.AquUser;
|
||||||
|
import com.intc.fishery.domain.bo.AquUserBo;
|
||||||
|
import com.intc.fishery.mapper.AquUserMapper;
|
||||||
|
import com.intc.fishery.service.IAquUserService;
|
||||||
import com.intc.system.domain.SysUser;
|
import com.intc.system.domain.SysUser;
|
||||||
|
import com.intc.system.domain.bo.SysUserBo;
|
||||||
import com.intc.system.domain.vo.SysClientVo;
|
import com.intc.system.domain.vo.SysClientVo;
|
||||||
import com.intc.system.domain.vo.SysUserVo;
|
import com.intc.system.domain.vo.SysUserVo;
|
||||||
import com.intc.system.mapper.SysUserMapper;
|
import com.intc.system.mapper.SysUserMapper;
|
||||||
|
import com.intc.system.service.ISysUserService;
|
||||||
import com.intc.web.domain.vo.LoginVo;
|
import com.intc.web.domain.vo.LoginVo;
|
||||||
import com.intc.web.service.IAuthStrategy;
|
import com.intc.web.service.IAuthStrategy;
|
||||||
import com.intc.web.service.SysLoginService;
|
import com.intc.web.service.SysLoginService;
|
||||||
@@ -27,6 +33,9 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信小程序认证策略
|
* 微信小程序认证策略
|
||||||
*
|
*
|
||||||
@@ -40,6 +49,9 @@ public class WechatAuthStrategy implements IAuthStrategy {
|
|||||||
private final WxLoginService wxLoginService;
|
private final WxLoginService wxLoginService;
|
||||||
private final SysLoginService loginService;
|
private final SysLoginService loginService;
|
||||||
private final SysUserMapper userMapper;
|
private final SysUserMapper userMapper;
|
||||||
|
private final ISysUserService userService;
|
||||||
|
private final AquUserMapper aquUserMapper;
|
||||||
|
private final IAquUserService aquUserService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoginVo login(String body, SysClientVo client) {
|
public LoginVo login(String body, SysClientVo client) {
|
||||||
@@ -110,7 +122,7 @@ public class WechatAuthStrategy implements IAuthStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据手机号加载系统用户
|
* 根据手机号加载系统用户,如果不存在则自动创建
|
||||||
*
|
*
|
||||||
* @param phone 手机号
|
* @param phone 手机号
|
||||||
* @return 系统用户信息
|
* @return 系统用户信息
|
||||||
@@ -121,11 +133,13 @@ public class WechatAuthStrategy implements IAuthStrategy {
|
|||||||
.eq(SysUser::getPhonenumber, phone)
|
.eq(SysUser::getPhonenumber, phone)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 如果用户不存在,创建新用户
|
||||||
if (ObjectUtil.isNull(user)) {
|
if (ObjectUtil.isNull(user)) {
|
||||||
log.error("系统中不存在该手机号的用户: phone={}", phone);
|
log.info("系统中不存在该手机号的用户,自动创建新用户: phone={}", phone);
|
||||||
throw new UserException("user.not.exists", phone);
|
user = createNewUser(phone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查用户状态
|
||||||
if (SystemConstants.DISABLE.equals(user.getStatus())) {
|
if (SystemConstants.DISABLE.equals(user.getStatus())) {
|
||||||
log.error("用户已被停用: phone={}, userId={}", phone, user.getUserId());
|
log.error("用户已被停用: phone={}, userId={}", phone, user.getUserId());
|
||||||
throw new UserException("user.blocked", phone);
|
throw new UserException("user.blocked", phone);
|
||||||
@@ -133,4 +147,122 @@ public class WechatAuthStrategy implements IAuthStrategy {
|
|||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建新的系统用户
|
||||||
|
*
|
||||||
|
* @param phone 手机号
|
||||||
|
* @return 新创建的用户信息
|
||||||
|
*/
|
||||||
|
private SysUserVo createNewUser(String phone) {
|
||||||
|
try {
|
||||||
|
// 构建新用户对象
|
||||||
|
SysUserBo newUser = new SysUserBo();
|
||||||
|
// 使用手机号作为用户名
|
||||||
|
newUser.setUserName(phone);
|
||||||
|
// 使用手机号作为昵称
|
||||||
|
newUser.setNickName("用户" + phone.substring(phone.length() - 4));
|
||||||
|
// 设置手机号
|
||||||
|
newUser.setPhonenumber(phone);
|
||||||
|
// 设置用户类型为系统用户
|
||||||
|
newUser.setUserType("sys_user");
|
||||||
|
// 设置默认部门ID
|
||||||
|
newUser.setDeptId(SystemConstants.DEFAULT_DEPT_ID);
|
||||||
|
// 设置状态为正常
|
||||||
|
newUser.setStatus(SystemConstants.NORMAL);
|
||||||
|
// 设置性别为未知
|
||||||
|
newUser.setSex("2");
|
||||||
|
// 设置默认密码
|
||||||
|
newUser.setPassword(BCrypt.hashpw("yuceyun@123"));
|
||||||
|
// 设置创建人和更新人为系统
|
||||||
|
newUser.setCreateBy(0L);
|
||||||
|
newUser.setUpdateBy(0L);
|
||||||
|
|
||||||
|
// 调用用户服务创建用户
|
||||||
|
boolean success = userService.registerUser(newUser, LoginHelper.getTenantId());
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
log.error("创建新用户失败: phone={}", phone);
|
||||||
|
throw new ServiceException("创建用户失败,请联系管理员");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询刚创建的用户信息
|
||||||
|
SysUserVo createdUser = userMapper.selectVoOne(
|
||||||
|
new LambdaQueryWrapper<SysUser>()
|
||||||
|
.eq(SysUser::getPhonenumber, phone)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ObjectUtil.isNull(createdUser)) {
|
||||||
|
log.error("创建用户后查询失败: phone={}", phone);
|
||||||
|
throw new ServiceException("创建用户失败,请联系管理员");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("成功创建系统用户: phone={}, userId={}, userName={}",
|
||||||
|
phone, createdUser.getUserId(), createdUser.getUserName());
|
||||||
|
|
||||||
|
// 创建对应的鱼测云用户(AquUser)
|
||||||
|
createAquUser(createdUser);
|
||||||
|
|
||||||
|
return createdUser;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("创建新用户异常: phone={}, error={}", phone, e.getMessage(), e);
|
||||||
|
throw new ServiceException("创建用户失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建鱼测云用户(AquUser)
|
||||||
|
*
|
||||||
|
* @param sysUser 系统用户信息
|
||||||
|
*/
|
||||||
|
private void createAquUser(SysUserVo sysUser) {
|
||||||
|
try {
|
||||||
|
// 检查是否已存在鱼测云用户
|
||||||
|
AquUser existingAquUser = aquUserMapper.selectById(sysUser.getUserId());
|
||||||
|
if (existingAquUser != null) {
|
||||||
|
log.info("鱼测云用户已存在,跳过创建: userId={}", sysUser.getUserId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建报警电话列表(包含用户手机号)
|
||||||
|
List<String> warnPhoneList = new ArrayList<>();
|
||||||
|
if (StringUtils.isNotBlank(sysUser.getPhonenumber())) {
|
||||||
|
warnPhoneList.add(sysUser.getPhonenumber());
|
||||||
|
}
|
||||||
|
String warnPhoneJson = JsonUtils.toJsonString(warnPhoneList);
|
||||||
|
|
||||||
|
// 创建鱼测云用户对象
|
||||||
|
AquUserBo aquUserBo = new AquUserBo();
|
||||||
|
// 使用系统用户ID作为鱼测云用户ID,保持一致
|
||||||
|
aquUserBo.setId(sysUser.getUserId());
|
||||||
|
// 使用系统用户的昵称作为用户名
|
||||||
|
aquUserBo.setUserName(sysUser.getNickName());
|
||||||
|
// 设置手机号
|
||||||
|
aquUserBo.setMobilePhone(sysUser.getPhonenumber());
|
||||||
|
// 设置报警电话列表
|
||||||
|
aquUserBo.setWarnPhoneJson(warnPhoneJson);
|
||||||
|
// 非管理员
|
||||||
|
aquUserBo.setIsManager(0L);
|
||||||
|
// 没有大屏权限
|
||||||
|
aquUserBo.setHasScreen(0L);
|
||||||
|
// 备注
|
||||||
|
aquUserBo.setRemark("微信登录自动创建");
|
||||||
|
|
||||||
|
// 调用服务创建鱼测云用户
|
||||||
|
boolean success = aquUserService.insertByBo(aquUserBo);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
log.info("成功创建鱼测云用户: userId={}, userName={}, phone={}",
|
||||||
|
sysUser.getUserId(), aquUserBo.getUserName(), aquUserBo.getMobilePhone());
|
||||||
|
} else {
|
||||||
|
log.error("创建鱼测云用户失败: userId={}", sysUser.getUserId());
|
||||||
|
// 不抛异常,不影响登录流程
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("创建鱼测云用户异常: userId={}, error={}", sysUser.getUserId(), e.getMessage(), e);
|
||||||
|
// 不抛异常,不影响登录流程
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user