package com.ruoyi.framework.web.service; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.utils.MessageUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.framework.security.WechatAuthenticationToken; import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.IWechatLoginService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; /** * 微信登录校验方法 * 类似于SysLoginService * * @author ruoyi */ @Component public class WechatLoginService { @Autowired private TokenService tokenService; @Autowired private AuthenticationManager authenticationManager; @Autowired private SysLoginService sysLoginService; @Autowired private ISysUserService userService; @Autowired private IWechatLoginService wechatApiService; /** * 微信OpenID登录验证 * * @param openId 微信OpenID * @param unionId 微信UnionID(可选) * @return token */ public String loginByOpenId(String openId, String unionId) { try { // 创建微信认证Token WechatAuthenticationToken authenticationToken = new WechatAuthenticationToken(openId, unionId); // 使用AuthenticationManager进行认证 Authentication authentication = authenticationManager.authenticate(authenticationToken); // 认证成功,获取LoginUser LoginUser loginUser = (LoginUser) authentication.getPrincipal(); // 记录登录成功日志 AsyncManager.me().execute(AsyncFactory.recordLogininfor( loginUser.getUsername(), Constants.LOGIN_SUCCESS, "微信OpenID登录成功")); // 记录登录信息(IP和时间) sysLoginService.recordLoginInfo(loginUser.getUserId()); // 生成token return tokenService.createToken(loginUser); } catch (BadCredentialsException e) { // 记录登录失败日志 AsyncManager.me().execute(AsyncFactory.recordLogininfor( openId, Constants.LOGIN_FAIL, e.getMessage())); throw e; } catch (Exception e) { // 记录登录失败日志 AsyncManager.me().execute(AsyncFactory.recordLogininfor( openId, Constants.LOGIN_FAIL, e.getMessage())); throw new BadCredentialsException(e.getMessage()); } } /** * 微信手机号登录验证 * 通过微信API获取手机号后进行登录 * * @param loginCode 微信登录code * @param phoneCode 手机号授权code * @return 包含token、openId、unionId的Map */ public Map loginByWechatPhone(String loginCode, String phoneCode) { Map loginResult = new HashMap<>(); try { // 1. 调用微信API服务获取用户信息 Map result = wechatApiService.loginByWechatPhone(loginCode, phoneCode); if (!(Boolean)result.get("success")) { String errorMsg = (String)result.get("message"); AsyncManager.me().execute(AsyncFactory.recordLogininfor( "微信用户", Constants.LOGIN_FAIL, errorMsg)); throw new BadCredentialsException(errorMsg); } // 2. 获取用户信息和openId SysUser user = (SysUser) result.get("user"); String openId = (String) result.get("openId"); String unionId = (String) result.get("unionId"); // 3. 使用openId和unionId进行认证 WechatAuthenticationToken authenticationToken = new WechatAuthenticationToken(openId, unionId); Authentication authentication = authenticationManager.authenticate(authenticationToken); // 4. 认证成功,获取LoginUser LoginUser loginUser = (LoginUser) authentication.getPrincipal(); // 5. 记录登录成功日志 AsyncManager.me().execute(AsyncFactory.recordLogininfor( loginUser.getUsername(), Constants.LOGIN_SUCCESS, "微信手机号登录成功")); // 6. 记录登录信息(IP和时间) sysLoginService.recordLoginInfo(loginUser.getUserId()); // 7. 生成token String token = tokenService.createToken(loginUser); // 8. 返回结果(包含token、openId、unionId) loginResult.put("token", token); loginResult.put("openId", openId); if (StringUtils.isNotEmpty(unionId)) { loginResult.put("unionId", unionId); } return loginResult; } catch (BadCredentialsException e) { AsyncManager.me().execute(AsyncFactory.recordLogininfor( "微信用户", Constants.LOGIN_FAIL, e.getMessage())); throw e; } catch (Exception e) { AsyncManager.me().execute(AsyncFactory.recordLogininfor( "微信用户", Constants.LOGIN_FAIL, e.getMessage())); throw new BadCredentialsException(e.getMessage()); } } }