import request from '@/utils/request'; import type { ApiResult } from '@/api'; import Taro from '@tarojs/taro'; import {SERVER_API_URL} from "@/utils/server"; import {getUserInfo} from "@/api/layout"; /** * 扫码登录相关接口 */ // 生成扫码token请求参数 export interface GenerateQRTokenParam { // 客户端类型:web, app, wechat clientType?: string; // 设备信息 deviceInfo?: string; // 过期时间(分钟) expireMinutes?: number; } // 生成扫码token响应 export interface GenerateQRTokenResult { // 扫码token token: string; // 二维码内容(通常是包含token的URL或JSON) qrContent: string; // 过期时间戳 expireTime: number; // 二维码图片URL(可选) qrImageUrl?: string; } // 扫码状态枚举 export enum QRLoginStatus { PENDING = 'pending', // 等待扫码 SCANNED = 'scanned', // 已扫码,等待确认 CONFIRMED = 'confirmed', // 已确认登录 EXPIRED = 'expired', // 已过期 CANCELLED = 'cancelled' // 已取消 } // 检查扫码状态响应 export interface QRLoginStatusResult { // 当前状态 status: QRLoginStatus; // 状态描述 message?: string; // 如果已确认登录,返回JWT token accessToken?: string; // 用户信息 userInfo?: { userId: number; nickname?: string; avatar?: string; phone?: string; }; // 剩余有效时间(秒) remainingTime?: number; } // 确认登录请求参数 export interface ConfirmLoginParam { // 扫码token token: string; // 用户ID userId: number; // 登录平台:web, app, wechat platform?: string; // 微信用户信息(当platform为wechat时) wechatInfo?: { openid?: string; unionid?: string; nickname?: string; avatar?: string; gender?: string; }; // 设备信息 deviceInfo?: string; } // 确认登录响应 export interface ConfirmLoginResult { // 是否成功 success: boolean; // 消息 message: string; // 登录用户信息 userInfo?: { userId: number; nickname?: string; avatar?: string; phone?: string; }; } /** * 生成扫码登录token */ export async function generateQRToken(data?: GenerateQRTokenParam) { const res = await request.post>( SERVER_API_URL + '/qr-login/generate', { clientType: 'wechat', expireMinutes: 5, ...data } ); if (res.code === 0 && res.data) { return res.data; } return Promise.reject(new Error(res.message)); } /** * 检查扫码登录状态 */ export async function checkQRLoginStatus(token: string) { const res = await request.get>( SERVER_API_URL + `/qr-login/status/${token}` ); if (res.code === 0 && res.data) { return res.data; } return Promise.reject(new Error(res.message)); } /** * 确认扫码登录(通用接口) */ export async function confirmQRLogin(data: ConfirmLoginParam) { const res = await request.post>( SERVER_API_URL + '/qr-login/confirm', data ); if (res.code === 0 && res.data) { return res.data; } return Promise.reject(new Error(res.message)); } /** * 微信小程序扫码登录确认(便捷接口) */ export async function confirmWechatQRLogin(token: string, userId: number) { try { // 获取微信用户信息 const userInfo = await getUserInfo(); console.log('获取微信用户信息3:', userInfo) const data: ConfirmLoginParam = { token, userId, platform: 'wechat', wechatInfo: { nickname: userInfo?.nickname, avatar: userInfo?.avatar, gender: userInfo?.sex }, deviceInfo: await getDeviceInfo() }; const res = await request.post>( SERVER_API_URL + '/qr-login/confirm', data ); console.log(res,'ConfirmLoginParamResult>') if (res.code === 0 && res.data) { return res.data; } return Promise.reject(new Error(res.message)); } catch (error: any) { return Promise.reject(new Error(error.message || '确认登录失败')); } } /** * 获取微信用户信息 */ async function getUserProfile() { return new Promise((resolve, reject) => { Taro.getUserProfile({ desc: '用于扫码登录身份确认', success: (res) => { resolve(res.userInfo); }, fail: (err) => { // 如果获取失败,尝试使用已存储的用户信息 const storedUser = Taro.getStorageSync('User'); if (storedUser) { resolve({ nickName: storedUser.nickname, avatarUrl: storedUser.avatar, gender: storedUser.gender }); } else { reject(err); } } }); }); } /** * 获取设备信息 */ async function getDeviceInfo() { return new Promise((resolve) => { Taro.getSystemInfo({ success: (res) => { const deviceInfo = { platform: res.platform, system: res.system, version: res.version, model: res.model, brand: res.brand, screenWidth: res.screenWidth, screenHeight: res.screenHeight }; resolve(JSON.stringify(deviceInfo)); }, fail: () => { resolve('unknown'); } }); }); } /** * 解析二维码内容,提取token */ export function parseQRContent(qrContent: string): string | null { try { console.log('解析二维码内容1:', qrContent); // 尝试解析JSON格式 if (qrContent.startsWith('{')) { const parsed = JSON.parse(qrContent); return parsed.token || parsed.qrCodeKey || null; } // 尝试解析URL格式 if (qrContent.includes('http')) { const url = new URL(qrContent); // 支持多种参数名 return url.searchParams.get('token') || url.searchParams.get('qrCodeKey') || url.searchParams.get('qr_code_key') || null; } // 尝试解析简单的key=value格式 if (qrContent.includes('=')) { const params = new URLSearchParams(qrContent); return params.get('token') || params.get('qrCodeKey') || params.get('qr_code_key') || null; } // 如果是以qr-login:开头的格式 if (qrContent.startsWith('qr-login:')) { return qrContent.replace('qr-login:', ''); } // 直接返回内容作为token(如果是32位以上的字符串) if (qrContent.length >= 32) { return qrContent; } return null; } catch (error) { console.error('解析二维码内容失败:', error); return null; } }