feat(passport): 优化扫码登录确认流程,改用 wx.login + loginByOpenId 验证身份
- 移除 useUser 依赖,采用微信 wx.login 获取 code 并调用 loginByOpenId 接口验证用户身份 - 登录流程调整为先通过 code 校验用户是否存在,存在则自动确认登录, 不存在跳转注册页面 - 增加用户信息本地缓存及优先使用 wx.login 返回的用户数据 - 修改二维码确认登录页面 UI,展示微信登录用户头像及昵称 - 新增 wx-login API 接口,实现通过 code 换取用户身份信息及 OpenId 获取接口 - 强化登录失败及用户未注册状态的提示和跳转逻辑
This commit is contained in:
123
src/api/passport/wx-login/index.ts
Normal file
123
src/api/passport/wx-login/index.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import request from '@/utils/request';
|
||||
import type { ApiResult } from '@/api';
|
||||
import { SERVER_API_URL } from '@/utils/server';
|
||||
|
||||
/**
|
||||
* 微信小程序登录相关接口
|
||||
*/
|
||||
|
||||
// 微信登录请求参数
|
||||
export interface WxLoginParam {
|
||||
// 微信登录凭证(wx.login() 获取)
|
||||
code: string;
|
||||
// 租户ID
|
||||
tenantId?: number;
|
||||
}
|
||||
|
||||
// 微信登录用户信息
|
||||
export interface WxLoginUserInfo {
|
||||
userId: number;
|
||||
username?: string;
|
||||
nickname?: string;
|
||||
avatar?: string;
|
||||
phone?: string;
|
||||
openid?: string;
|
||||
unionid?: string;
|
||||
tenantId: number;
|
||||
}
|
||||
|
||||
// 微信登录结果
|
||||
export interface WxLoginResult {
|
||||
// JWT 访问令牌
|
||||
access_token?: string;
|
||||
// 用户信息
|
||||
user?: WxLoginUserInfo;
|
||||
// 租户ID
|
||||
tenantId?: number;
|
||||
// 登录消息
|
||||
message?: string;
|
||||
// 用户ID
|
||||
userId?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信小程序登录(通过 openid)
|
||||
*
|
||||
* 流程:
|
||||
* 1. 调用 wx.login() 获取 code
|
||||
* 2. 用 code 调用此接口
|
||||
* 3. 后端用 code 换取 openid,查库返回用户信息
|
||||
* 4. 如果用户存在,返回登录 token
|
||||
* 5. 如果用户不存在,返回 "用户未注册" + openid
|
||||
*/
|
||||
export async function loginByOpenId(data: WxLoginParam): Promise<{
|
||||
success: boolean;
|
||||
message: string;
|
||||
data?: WxLoginResult;
|
||||
openid?: string;
|
||||
}> {
|
||||
const res = await request.post<ApiResult<WxLoginResult>>(
|
||||
SERVER_API_URL + '/wx-login/loginByOpenId',
|
||||
data
|
||||
);
|
||||
|
||||
console.log('[WxLogin] loginByOpenId 响应:', res);
|
||||
|
||||
// 成功:用户已注册
|
||||
if ((res.code === 0 || res.code === 200) && res.data) {
|
||||
return {
|
||||
success: true,
|
||||
message: res.message || '登录成功',
|
||||
data: res.data
|
||||
};
|
||||
}
|
||||
|
||||
// 失败:用户未注册或登录失败
|
||||
// 后端返回 "用户未注册" 时,data 字段是 openid
|
||||
if (res.message === '用户未注册' || res.message?.includes('用户未注册')) {
|
||||
return {
|
||||
success: false,
|
||||
message: '用户未注册',
|
||||
openid: res.data as unknown as string
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
message: res.message || '登录失败'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信 OpenId(仅获取,不登录)
|
||||
*/
|
||||
export async function getOpenId(code: string): Promise<{
|
||||
success: boolean;
|
||||
openid?: string;
|
||||
unionid?: string;
|
||||
session_key?: string;
|
||||
message?: string;
|
||||
}> {
|
||||
const res = await request.post<ApiResult<{
|
||||
openid: string;
|
||||
unionid?: string;
|
||||
session_key?: string;
|
||||
}>>(
|
||||
SERVER_API_URL + '/wx-login/getOpenId',
|
||||
{ code }
|
||||
);
|
||||
|
||||
if ((res.code === 0 || res.code === 200) && res.data) {
|
||||
return {
|
||||
success: true,
|
||||
openid: res.data.openid,
|
||||
unionid: res.data.unionid,
|
||||
session_key: res.data.session_key
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
message: res.message || '获取 OpenId 失败'
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user