javacodeadmin/ruoyi-system/src/main/java/com/ruoyi/system/controllerUtil/AppletLoginUtil.java

375 lines
13 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.ruoyi.system.ControllerUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.domain.Users;
import com.ruoyi.system.service.IUsersService;
import java.util.HashMap;
import java.util.Map;
import static com.ruoyi.common.core.domain.AjaxResult.error;
import static com.ruoyi.common.core.domain.AjaxResult.success;
/**
* 小程序登录工具类
*
* 提供微信小程序登录相关的工具方法
* 主要功能:
* 1. 参数验证和提取
* 2. 微信openid获取
* 3. 用户手机号获取
* 4. 用户创建和更新
* 5. 登录响应构建
*
* @author Mr. Zhang Pan
* @date 2025-01-03
* @version 1.0
*/
public class AppletLoginUtil {
/**
* 执行微信登录完整流程
*
* @param params 登录参数
* @param usersService 用户服务
* @return 登录结果
*/
public static AjaxResult executeWechatLogin(Map<String, Object> params, IUsersService usersService) {
try {
// 1. 参数验证
String jsCode = validateAndExtractParam(params, "usercode", "微信登录code不能为空");
String phoneCode = validateAndExtractParam(params, "code", "手机号授权code不能为空");
// 2. 获取微信openid
String openid = getWechatOpenid(jsCode);
if (openid == null) {
return error("获取微信openid失败请重试");
}
// 3. 检查用户是否已存在
Users existingUser = usersService.selectUsersByOpenid(openid);
if (existingUser != null) {
existingUser.setRemember_token(existingUser.getRememberToken());
return buildSuccessResponse(existingUser, false);
}
// 4. 新用户处理:获取手机号并创建用户
String phoneNumber = getPhoneNumber(phoneCode);
if (phoneNumber == null) {
return error("获取手机号失败,请重新授权");
}
// 5. 创建或更新用户
Users user = createOrUpdateUser(openid, phoneNumber, usersService);
user.setRemember_token(user.getRememberToken());
return buildSuccessResponse(user, true);
} catch (IllegalArgumentException e) {
return error(e.getMessage());
} catch (Exception e) {
System.err.println("微信登录异常:" + e.getMessage());
e.printStackTrace();
return error("微信登录失败,请稍后重试");
}
}
/**
* 验证并提取请求参数
*
* @param params 参数Map
* @param key 参数键
* @param errorMessage 错误信息
* @return 参数值
* @throws IllegalArgumentException 参数无效时抛出
*/
public static String validateAndExtractParam(Map<String, Object> params, String key, String errorMessage) {
Object value = params.get(key);
if (value == null || value.toString().trim().isEmpty()) {
throw new IllegalArgumentException(errorMessage);
}
return value.toString().trim();
}
/**
* 获取微信openid
*
* @param jsCode 微信小程序登录code
* @return openid或null
*/
public static String getWechatOpenid(String jsCode) {
try {
Map<String, Object> openidResult = WechatApiUtil.getWechatUserOpenidInfo(jsCode);
if (!(Boolean) openidResult.get("success")) {
System.err.println("获取openid失败" + openidResult.get("errorMsg"));
return null;
}
String openid = (String) openidResult.get("openid");
if (openid == null || openid.trim().isEmpty()) {
System.err.println("微信API返回的openid为空");
return null;
}
System.out.println("成功获取微信openid" + openid.substring(0, 8) + "...");
return openid;
} catch (Exception e) {
System.err.println("获取微信openid异常" + e.getMessage());
return null;
}
}
/**
* 获取用户手机号
*
* @param phoneCode 手机号授权code
* @return 手机号或null
*/
public static String getPhoneNumber(String phoneCode) {
try {
Map<String, Object> phoneResult = WechatApiUtil.getPhoneNumberByCode(phoneCode);
if (!(Boolean) phoneResult.get("success")) {
System.err.println("获取手机号失败:" + phoneResult.get("errorMsg"));
return null;
}
Map<String, Object> phoneInfo = (Map<String, Object>) phoneResult.get("phone_info");
if (phoneInfo == null) {
System.err.println("微信API返回的手机号信息为空");
return null;
}
String phoneNumber = (String) phoneInfo.get("phoneNumber");
if (phoneNumber == null || phoneNumber.trim().isEmpty()) {
System.err.println("微信API返回的手机号为空");
return null;
}
System.out.println("成功获取用户手机号:" + phoneNumber.substring(0, 3) + "****" + phoneNumber.substring(7));
return phoneNumber;
} catch (Exception e) {
System.err.println("获取用户手机号异常:" + e.getMessage());
return null;
}
}
/**
* 创建或更新用户
*
* @param openid 微信openid
* @param phoneNumber 手机号
* @param usersService 用户服务
* @return 用户对象
* @throws Exception 操作失败时抛出
*/
public static Users createOrUpdateUser(String openid, String phoneNumber, IUsersService usersService) throws Exception {
// 1. 生成用户token
String token = WechatApiUtil.generateUserToken(openid);
if (token == null || token.trim().isEmpty()) {
throw new Exception("生成用户token失败");
}
// 2. 检查手机号是否已存在
Users existingUserByPhone = usersService.selectUsersByPhone(phoneNumber);
if (existingUserByPhone != null) {
// 3. 更新已有用户的openid和token
return updateExistingUser(existingUserByPhone, openid, token, usersService);
} else {
// 4. 创建新用户
return createNewUser(openid, phoneNumber, token, usersService);
}
}
/**
* 更新已有用户信息
*
* @param user 已有用户
* @param openid 微信openid
* @param token 新token
* @param usersService 用户服务
* @return 更新后的用户
* @throws Exception 更新失败时抛出
*/
public static Users updateExistingUser(Users user, String openid, String token, IUsersService usersService) throws Exception {
try {
user.setOpenid(openid);
user.setRememberToken(token);
int updateResult = usersService.updateUsers(user);
if (updateResult <= 0) {
throw new Exception("更新用户信息失败");
}
System.out.println("成功更新用户信息用户ID" + user.getId());
return user;
} catch (Exception e) {
System.err.println("更新用户信息异常:" + e.getMessage());
throw new Exception("更新用户信息失败:" + e.getMessage());
}
}
/**
* 创建新用户
*
* @param openid 微信openid
* @param phoneNumber 手机号
* @param token 用户token
* @param usersService 用户服务
* @return 新创建的用户
* @throws Exception 创建失败时抛出
*/
public static Users createNewUser(String openid, String phoneNumber, String token, IUsersService usersService) throws Exception {
try {
Users newUser = new Users();
newUser.setPhone(phoneNumber);
newUser.setRememberToken(token);
newUser.setName("微信用户");
newUser.setOpenid(openid);
newUser.setAvatar("/default/user_avatar.jpeg");
newUser.setType("1");
newUser.setStatus(1);
newUser.setIsWork(0);
int insertResult = usersService.insertUsers(newUser);
if (insertResult <= 0) {
throw new Exception("创建用户记录失败");
}
System.out.println("成功创建新用户,手机号:" + phoneNumber.substring(0, 3) + "****" + phoneNumber.substring(7));
return newUser;
} catch (Exception e) {
System.err.println("创建新用户异常:" + e.getMessage());
throw new Exception("创建用户失败:" + e.getMessage());
}
}
/**
* 构建成功响应
*
* @param user 用户对象
* @param isNewUser 是否为新用户
* @return 响应结果
*/
public static AjaxResult buildSuccessResponse(Users user, boolean isNewUser) {
try {
// 设置返回字段
user.setRemember_token(user.getRememberToken());
// 构建响应数据
Map<String, Object> responseData = new HashMap<>();
responseData.put("user", user);
responseData.put("isNewUser", isNewUser);
responseData.put("loginTime", System.currentTimeMillis());
responseData.put("message", isNewUser ? "注册成功" : "登录成功");
System.out.println((isNewUser ? "用户注册成功" : "用户登录成功") + "用户ID" + user.getId());
return success(responseData);
} catch (Exception e) {
System.err.println("构建响应数据异常:" + e.getMessage());
return error("登录成功但返回数据异常");
}
}
/**
* 验证用户token并获取用户信息
*
* @param token 用户token
* @param usersService 用户服务
* @return 验证结果
*/
public static Map<String, Object> validateUserToken(String token, IUsersService usersService) {
Map<String, Object> result = new HashMap<>();
try {
if (token == null || token.trim().isEmpty()) {
result.put("valid", false);
result.put("message", "token不能为空");
return result;
}
// 验证token格式
if (!WechatApiUtil.isValidTokenFormat(token.trim())) {
result.put("valid", false);
result.put("message", "token格式无效");
return result;
}
// 查询用户信息
Users user = usersService.selectUsersByRememberToken(token.trim());
if (user == null) {
result.put("valid", false);
result.put("message", "token无效或用户不存在");
return result;
}
// 检查用户状态
if (user.getStatus() == null || user.getStatus() != 1) {
result.put("valid", false);
result.put("message", "用户账号已被禁用");
return result;
}
// 设置返回字段并过滤敏感信息
user.setRemember_token(user.getRememberToken());
result.put("valid", true);
result.put("user", user);
result.put("message", "token验证成功");
} catch (Exception e) {
result.put("valid", false);
result.put("message", "token验证异常" + e.getMessage());
System.err.println("验证用户token异常" + e.getMessage());
}
return result;
}
/**
* 获取并验证请求头中的token
*
* @param authHeader Authorization请求头
* @param tokenHeader token请求头
* @return 提取的token或null
*/
public static String extractToken(String authHeader, String tokenHeader) {
String token = tokenHeader;
// 如果token头为空尝试从Authorization头获取
if (token == null || token.trim().isEmpty()) {
if (authHeader != null && authHeader.startsWith("Bearer ")) {
token = authHeader.substring(7);
}
}
return (token != null && !token.trim().isEmpty()) ? token.trim() : null;
}
/**
* 构建登录失败响应
*
* @param message 失败信息
* @return 失败响应
*/
public static AjaxResult buildFailureResponse(String message) {
return error("登录失败:" + message);
}
/**
* 构建参数错误响应
*
* @param paramName 参数名
* @return 错误响应
*/
public static AjaxResult buildParamErrorResponse(String paramName) {
return error("参数错误:" + paramName + " 不能为空或格式不正确");
}
}