refactor: 微信小程序授权登录重构
This commit is contained in:
@@ -165,18 +165,18 @@ public interface UserService extends IService<User> {
|
||||
/**
|
||||
* 根据 openid 获取用户认证信息
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param openId 用户名
|
||||
* @return {@link UserAuthCredentials}
|
||||
*/
|
||||
|
||||
UserAuthCredentials getAuthCredentialsByOpenId(String username);
|
||||
UserAuthCredentials getAuthCredentialsByOpenId(String openId);
|
||||
|
||||
/**
|
||||
* 根据微信 OpenID 注册或绑定用户
|
||||
*
|
||||
* @param openId 微信 OpenID
|
||||
*/
|
||||
void registerOrBindWechatUser(String openId);
|
||||
boolean registerOrBindWechatUser(String openId);
|
||||
|
||||
/**
|
||||
* 根据手机号获取用户认证信息
|
||||
@@ -186,5 +186,22 @@ public interface UserService extends IService<User> {
|
||||
*/
|
||||
UserAuthCredentials getAuthCredentialsByMobile(String mobile);
|
||||
|
||||
/**
|
||||
* 根据手机号和OpenID注册用户
|
||||
*
|
||||
* @param mobile 手机号
|
||||
* @param openId 微信OpenID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean registerUserByMobileAndOpenId(String mobile, String openId);
|
||||
|
||||
/**
|
||||
* 绑定用户微信OpenID
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param openId 微信OpenID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean bindUserOpenId(Long userId, String openId);
|
||||
|
||||
}
|
||||
|
||||
@@ -34,11 +34,13 @@ import com.youlai.boot.system.model.vo.UserPageVO;
|
||||
import com.youlai.boot.system.model.vo.UserProfileVO;
|
||||
import com.youlai.boot.system.service.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -51,6 +53,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
@@ -207,14 +210,17 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 openid 获取用户认证信息
|
||||
* 根据OpenID获取用户认证信息
|
||||
*
|
||||
* @param openid 微信 OpenId
|
||||
* @return {@link UserAuthCredentials}
|
||||
* @param openId 微信OpenID
|
||||
* @return 用户认证信息
|
||||
*/
|
||||
@Override
|
||||
public UserAuthCredentials getAuthCredentialsByOpenId(String openid) {
|
||||
UserAuthCredentials userAuthCredentials = this.baseMapper.getAuthCredentialsByOpenId(openid);
|
||||
public UserAuthCredentials getAuthCredentialsByOpenId(String openId) {
|
||||
if (StrUtil.isBlank(openId)) {
|
||||
return null;
|
||||
}
|
||||
UserAuthCredentials userAuthCredentials = this.baseMapper.getAuthCredentialsByOpenId(openId);
|
||||
if (userAuthCredentials != null) {
|
||||
Set<String> roles = userAuthCredentials.getRoles();
|
||||
// 获取最大范围的数据权限
|
||||
@@ -225,13 +231,16 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机号获取用户认证凭证信息
|
||||
* 根据手机号获取用户认证信息
|
||||
*
|
||||
* @param mobile 手机号
|
||||
* @return {@link UserAuthCredentials}
|
||||
* @return 用户认证信息
|
||||
*/
|
||||
@Override
|
||||
public UserAuthCredentials getAuthCredentialsByMobile(String mobile) {
|
||||
if (StrUtil.isBlank(mobile)) {
|
||||
return null;
|
||||
}
|
||||
UserAuthCredentials userAuthCredentials = this.baseMapper.getAuthCredentialsByMobile(mobile);
|
||||
if (userAuthCredentials != null) {
|
||||
Set<String> roles = userAuthCredentials.getRoles();
|
||||
@@ -242,34 +251,135 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
return userAuthCredentials;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据微信 OpenID 注册或绑定用户
|
||||
* <p>
|
||||
* TODO 根据手机号绑定用户
|
||||
* 注册或绑定微信用户
|
||||
*
|
||||
* @param openId 微信 OpenID
|
||||
* @param openId 微信OpenID
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public void registerOrBindWechatUser(String openId) {
|
||||
User user = this.getOne(
|
||||
new LambdaQueryWrapper<User>().eq(User::getOpenid, openId)
|
||||
);
|
||||
if (user == null) {
|
||||
user = new User();
|
||||
user.setNickname("微信用户"); // 默认昵称
|
||||
user.setUsername(openId); // TODO 后续替换为手机号
|
||||
user.setOpenid(openId);
|
||||
user.setGender(0); // 保密
|
||||
user.setUpdateBy(SecurityUtils.getUserId());
|
||||
user.setPassword(SystemConstants.DEFAULT_PASSWORD);
|
||||
this.save(user);
|
||||
// 为了默认系统管理员角色,这里按需调整,实际情况绑定已存在的系统用户,另一种情况是给默认游客角色,然后由系统管理员设置用户的角色
|
||||
UserRole userRole = new UserRole();
|
||||
userRole.setUserId(user.getId());
|
||||
userRole.setRoleId(1L); // TODO 系统管理员
|
||||
userRoleService.save(userRole);
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean registerOrBindWechatUser(String openId) {
|
||||
if (StrUtil.isBlank(openId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 查询是否已存在该openId的用户
|
||||
User existUser = this.getOne(
|
||||
new LambdaQueryWrapper<User>()
|
||||
.eq(User::getOpenid, openId)
|
||||
);
|
||||
|
||||
if (existUser != null) {
|
||||
// 用户已存在,不需要注册
|
||||
return true;
|
||||
}
|
||||
|
||||
// 创建新用户
|
||||
User newUser = new User();
|
||||
newUser.setNickname("微信用户"); // 默认昵称
|
||||
newUser.setUsername(openId); // TODO 后续替换为手机号
|
||||
newUser.setOpenid(openId);
|
||||
newUser.setGender(0); // 保密
|
||||
newUser.setUpdateBy(SecurityUtils.getUserId());
|
||||
newUser.setPassword(SystemConstants.DEFAULT_PASSWORD);
|
||||
newUser.setCreateTime(LocalDateTime.now());
|
||||
newUser.setUpdateTime(LocalDateTime.now());
|
||||
this.save(newUser);
|
||||
// 为了默认系统管理员角色,这里按需调整,实际情况绑定已存在的系统用户,另一种情况是给默认游客角色,然后由系统管理员设置用户的角色
|
||||
UserRole userRole = new UserRole();
|
||||
userRole.setUserId(newUser.getId());
|
||||
userRole.setRoleId(1L); // TODO 系统管理员
|
||||
userRoleService.save(userRole);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机号和OpenID注册用户
|
||||
*
|
||||
* @param mobile 手机号
|
||||
* @param openId 微信OpenID
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean registerUserByMobileAndOpenId(String mobile, String openId) {
|
||||
if (StrUtil.isBlank(mobile) || StrUtil.isBlank(openId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 先查询是否已存在手机号对应的用户
|
||||
User existingUser = this.getOne(
|
||||
new LambdaQueryWrapper<User>()
|
||||
.eq(User::getMobile, mobile)
|
||||
);
|
||||
|
||||
if (existingUser != null) {
|
||||
// 如果存在用户但没绑定openId,则绑定openId
|
||||
if (StrUtil.isBlank(existingUser.getOpenid())) {
|
||||
return bindUserOpenId(existingUser.getId(), openId);
|
||||
}
|
||||
// 如果已经绑定了其他openId,则判断是否需要更新
|
||||
else if (!openId.equals(existingUser.getOpenid())) {
|
||||
return bindUserOpenId(existingUser.getId(), openId);
|
||||
}
|
||||
// 如果已经绑定了相同的openId,则不需要任何操作
|
||||
return true;
|
||||
}
|
||||
|
||||
// 不存在用户,创建新用户
|
||||
User newUser = new User();
|
||||
newUser.setMobile(mobile);
|
||||
newUser.setOpenid(openId);
|
||||
newUser.setUsername(mobile); // 使用手机号作为用户名
|
||||
newUser.setNickname("微信用户_" + mobile.substring(mobile.length() - 4)); // 使用手机号后4位作为昵称
|
||||
newUser.setPassword(SystemConstants.DEFAULT_PASSWORD); // 使用加密的openId作为初始密码
|
||||
newUser.setGender(0); // 保密
|
||||
newUser.setCreateTime(LocalDateTime.now());
|
||||
newUser.setUpdateTime(LocalDateTime.now());
|
||||
this.save(newUser);
|
||||
// 为了默认系统管理员角色,这里按需调整,实际情况绑定已存在的系统用户,另一种情况是给默认游客角色,然后由系统管理员设置用户的角色
|
||||
UserRole userRole = new UserRole();
|
||||
userRole.setUserId(newUser.getId());
|
||||
userRole.setRoleId(1L); // TODO 系统管理员
|
||||
userRoleService.save(userRole);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定用户微信OpenID
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param openId 微信OpenID
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean bindUserOpenId(Long userId, String openId) {
|
||||
if (userId == null || StrUtil.isBlank(openId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否已有其他用户绑定了此openId
|
||||
User existingUser = this.getOne(
|
||||
new LambdaQueryWrapper<User>()
|
||||
.eq(User::getOpenid, openId)
|
||||
.ne(User::getId, userId)
|
||||
);
|
||||
|
||||
if (existingUser != null) {
|
||||
log.warn("OpenID {} 已被用户 {} 绑定,无法为用户 {} 绑定", openId, existingUser.getId(), userId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 更新用户openId
|
||||
boolean updated = this.update(
|
||||
new LambdaUpdateWrapper<User>()
|
||||
.eq(User::getId, userId)
|
||||
.set(User::getOpenid, openId)
|
||||
.set(User::getUpdateTime, LocalDateTime.now())
|
||||
);
|
||||
return updated ;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user