353 lines
8.4 KiB
TypeScript
353 lines
8.4 KiB
TypeScript
import Taro from '@tarojs/taro';
|
||
import httpService, { ApiResponse } from './httpService';
|
||
import tokenManager from '../utils/tokenManager';
|
||
|
||
// 微信用户信息接口
|
||
export interface WechatUserInfo {
|
||
id: string;
|
||
nickname: string;
|
||
avatar: string;
|
||
gender: number;
|
||
city: string;
|
||
province: string;
|
||
country: string;
|
||
}
|
||
|
||
// 登录响应接口
|
||
export interface LoginResponse {
|
||
success: boolean;
|
||
message: string;
|
||
token?: string;
|
||
user_info?: WechatUserInfo;
|
||
}
|
||
|
||
// 发送短信响应接口
|
||
export interface SmsResponse {
|
||
success: boolean;
|
||
message: string;
|
||
}
|
||
|
||
// 验证验证码响应接口
|
||
export interface VerifyCodeResponse {
|
||
success: boolean;
|
||
message: string;
|
||
token?: string;
|
||
user_info?: WechatUserInfo;
|
||
}
|
||
// 用户详细信息
|
||
export interface UserInfoType {
|
||
id: number
|
||
openid: string
|
||
unionid: string
|
||
session_key: string
|
||
nickname: string
|
||
avatar_url: string
|
||
gender: string
|
||
country: string
|
||
province: string
|
||
city: string
|
||
language: string
|
||
phone: string
|
||
is_subscribed: string
|
||
latitude: number
|
||
longitude: number
|
||
subscribe_time: string
|
||
last_login_time: string
|
||
}
|
||
|
||
|
||
// 微信授权登录
|
||
export const wechat_auth_login = async (phone_code?: string): Promise<LoginResponse> => {
|
||
try {
|
||
// 先进行微信登录获取code
|
||
const login_result = await Taro.login();
|
||
|
||
if (!login_result.code) {
|
||
return {
|
||
success: false,
|
||
message: '微信登录失败'
|
||
};
|
||
}
|
||
|
||
// 使用 httpService 调用微信授权接口,传递手机号code
|
||
const auth_response = await httpService.post('user/wx_auth', {
|
||
code: login_result.code,
|
||
phone_code: phone_code // 传递手机号加密code
|
||
});
|
||
|
||
if (auth_response.code === 0) {
|
||
return {
|
||
success: true,
|
||
message: '微信登录成功',
|
||
token: auth_response.data?.token || '',
|
||
user_info: auth_response.data?.userInfo
|
||
};
|
||
} else {
|
||
return {
|
||
success: false,
|
||
message: auth_response.message || '微信授权失败'
|
||
};
|
||
}
|
||
} catch (error) {
|
||
console.error('微信授权登录失败:', error);
|
||
return {
|
||
success: false,
|
||
message: '微信授权失败,请重试'
|
||
};
|
||
}
|
||
};
|
||
|
||
// 手机号验证码登录接口参数
|
||
export interface PhoneLoginParams {
|
||
phone: string;
|
||
verification_code: string;
|
||
user_code: string
|
||
}
|
||
|
||
// 手机号验证码登录
|
||
export const phone_auth_login = async (params: PhoneLoginParams): Promise<LoginResponse> => {
|
||
try {
|
||
// 使用 httpService 调用验证验证码接口
|
||
const verify_response = await httpService.post('user/sms/verify', {
|
||
phone: params.phone,
|
||
code: params.verification_code,
|
||
user_code: params.user_code
|
||
});
|
||
|
||
|
||
if (verify_response.code === 0) {
|
||
return {
|
||
success: true,
|
||
message: '登录成功',
|
||
token: verify_response.data?.token,
|
||
user_info: verify_response.data?.userInfo
|
||
};
|
||
} else {
|
||
return {
|
||
success: false,
|
||
message: verify_response.message || '验证码错误'
|
||
};
|
||
}
|
||
} catch (error) {
|
||
console.error('手机号登录失败:', error);
|
||
return {
|
||
success: false,
|
||
message: error.message
|
||
};
|
||
}
|
||
};
|
||
|
||
// 发送短信验证码
|
||
export const send_sms_code = async (phone: string): Promise<SmsResponse> => {
|
||
try {
|
||
const response = await httpService.post('user/sms/send', {
|
||
phone: phone
|
||
});
|
||
|
||
// 修复响应检查逻辑:检查 code === 0 或 success === true
|
||
if (response.code === 0 || response.success === true) {
|
||
return {
|
||
success: true,
|
||
message: '验证码发送成功'
|
||
};
|
||
} else {
|
||
return {
|
||
success: false,
|
||
message: response.message || '验证码发送失败'
|
||
};
|
||
}
|
||
} catch (error) {
|
||
console.error('发送短信失败:', error);
|
||
return {
|
||
success: false,
|
||
message: error.message
|
||
};
|
||
}
|
||
};
|
||
|
||
// 验证短信验证码
|
||
export const verify_sms_code = async (phone: string, code: string): Promise<VerifyCodeResponse> => {
|
||
try {
|
||
const response = await httpService.post('user/sms/verify', {
|
||
phone: phone,
|
||
code: code
|
||
});
|
||
|
||
return {
|
||
success: response.success,
|
||
message: response.message || '验证失败',
|
||
token: response.data?.token,
|
||
user_info: response.data?.userInfo
|
||
};
|
||
} catch (error) {
|
||
console.error('验证验证码失败:', error);
|
||
return {
|
||
success: false,
|
||
message: error.message
|
||
};
|
||
}
|
||
};
|
||
|
||
|
||
// 保存用户登录状态
|
||
export const save_login_state = (token: string, user_info: WechatUserInfo) => {
|
||
try {
|
||
// 使用 tokenManager 保存令牌信息,设置24小时过期
|
||
const expires_at = Date.now() + 24 * 60 * 60 * 1000; // 24小时后过期
|
||
tokenManager.setToken({
|
||
accessToken: token,
|
||
expiresAt: expires_at
|
||
});
|
||
|
||
|
||
// 保存用户信息
|
||
Taro.setStorageSync('user_info', JSON.stringify(user_info));
|
||
Taro.setStorageSync('is_logged_in', true);
|
||
Taro.setStorageSync('login_time', Date.now());
|
||
} catch (error) {
|
||
console.error('保存登录状态失败:', error);
|
||
}
|
||
};
|
||
|
||
// 清除登录状态
|
||
export const clear_login_state = () => {
|
||
try {
|
||
// 使用 tokenManager 清除令牌
|
||
tokenManager.clearTokens();
|
||
|
||
// 清除其他登录状态
|
||
Taro.removeStorageSync('user_info');
|
||
Taro.removeStorageSync('is_logged_in');
|
||
Taro.removeStorageSync('login_time');
|
||
} catch (error) {
|
||
console.error('清除登录状态失败:', error);
|
||
}
|
||
};
|
||
|
||
// 检查是否已登录
|
||
export const check_login_status = (): boolean => {
|
||
try {
|
||
// 使用 tokenManager 检查令牌有效性
|
||
|
||
|
||
if (!tokenManager.hasValidToken()) {
|
||
clear_login_state();
|
||
return false;
|
||
}
|
||
|
||
const is_logged_in = Taro.getStorageSync('is_logged_in');
|
||
return !!is_logged_in;
|
||
} catch (error) {
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// 检查令牌是否需要刷新(剩余时间少于1小时时)
|
||
export const should_refresh_token = (): boolean => {
|
||
try {
|
||
const remaining_time = tokenManager.getTokenRemainingTime();
|
||
const one_hour = 60 * 60 * 1000; // 1小时
|
||
return remaining_time > 0 && remaining_time < one_hour;
|
||
} catch (error) {
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// 获取令牌状态信息
|
||
export const get_token_status = () => {
|
||
try {
|
||
const is_valid = tokenManager.hasValidToken();
|
||
const remaining_time = tokenManager.getTokenRemainingTime();
|
||
const is_expired = tokenManager.isTokenExpired();
|
||
|
||
return {
|
||
is_valid,
|
||
remaining_time,
|
||
is_expired,
|
||
expires_in_minutes: Math.floor(remaining_time / (60 * 1000))
|
||
};
|
||
} catch (error) {
|
||
return {
|
||
is_valid: false,
|
||
remaining_time: 0,
|
||
is_expired: true,
|
||
expires_in_minutes: 0
|
||
};
|
||
}
|
||
};
|
||
|
||
// 获取用户信息
|
||
export const get_user_info = (): WechatUserInfo | null => {
|
||
try {
|
||
let userinfo = Taro.getStorageSync('user_info')
|
||
if (userinfo) {
|
||
return JSON.parse(userinfo)
|
||
}
|
||
return null;
|
||
} catch (error) {
|
||
return null;
|
||
}
|
||
};
|
||
|
||
// 获取用户token
|
||
export const get_user_token = (): string | null => {
|
||
try {
|
||
// 使用 tokenManager 获取令牌
|
||
return tokenManager.getAccessToken();
|
||
} catch (error) {
|
||
return null;
|
||
}
|
||
};
|
||
|
||
// 检查微信登录状态
|
||
export const check_wechat_login = async (): Promise<boolean> => {
|
||
try {
|
||
const check_result = await Taro.checkSession();
|
||
// Taro.checkSession 返回的是 { errMsg: string }
|
||
return check_result.errMsg === 'checkSession:ok';
|
||
} catch (error) {
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// 刷新登录状态
|
||
export const refresh_login_status = async (): Promise<boolean> => {
|
||
try {
|
||
// 检查微信登录状态
|
||
const is_valid = await check_wechat_login();
|
||
|
||
if (!is_valid) {
|
||
// 微信登录已过期,需要重新登录
|
||
clear_login_state();
|
||
return false;
|
||
}
|
||
|
||
// 检查本地存储的登录状态
|
||
return check_login_status();
|
||
} catch (error) {
|
||
console.error('刷新登录状态失败:', error);
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// 获取用户详细信息
|
||
export const fetchUserProfile = async (): Promise<ApiResponse<UserInfoType>> => {
|
||
try {
|
||
const response = await httpService.post('user/detail');
|
||
return response;
|
||
} catch (error) {
|
||
console.error('获取用户信息失败:', error);
|
||
throw error;
|
||
}
|
||
};
|
||
|
||
// 更新用户信息
|
||
export const updateUserProfile = async (payload: Partial<UserInfoType>) => {
|
||
try {
|
||
const response = await httpService.post('/user/update', payload);
|
||
return response;
|
||
} catch (error) {
|
||
console.error('更新用户信息失败:', error);
|
||
throw error;
|
||
}
|
||
}; |