pet/utils/loginState.js

243 lines
6.7 KiB
JavaScript
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.

/**
* 登录状态管理工具
* 用于管理用户登录流程中的状态和数据传递
*/
// 登录步骤常量
export const LOGIN_STEPS = {
NOT_LOGGED: 'not_logged', // 未登录
WX_LOGGED: 'wx_logged', // 微信登录完成
PHONE_AUTHED: 'phone_authed', // 手机号授权完成
PHONE_SKIPPED: 'phone_skipped', // 跳过手机号授权
PROFILE_COMPLETED: 'profile_completed' // 个人信息完善完成
}
// 存储键名常量
export const STORAGE_KEYS = {
LOGIN_STEP: 'loginStep',
WX_LOGIN_CODE: 'wxLoginCode',
TOKEN: 'token',
PHONE_NUMBER: 'phoneNumber',
WX_USER_INFO: 'wxUserInfo',
USER_INFO: 'userInfo',
LOGIN_DATE: 'loginDate'
}
/**
* 获取当前登录步骤
* @returns {string} 当前登录步骤
*/
export const getCurrentLoginStep = () => {
return uni.getStorageSync(STORAGE_KEYS.LOGIN_STEP) || LOGIN_STEPS.NOT_LOGGED
}
/**
* 设置登录步骤
* @param {string} step 登录步骤
*/
export const setLoginStep = (step) => {
console.log('设置登录步骤:', step)
uni.setStorageSync(STORAGE_KEYS.LOGIN_STEP, step)
}
/**
* 检查用户是否已完成登录流程
* @returns {boolean} 是否已完成登录
*/
export const isLoginCompleted = () => {
const step = getCurrentLoginStep()
return step === LOGIN_STEPS.PROFILE_COMPLETED
}
/**
* 检查用户是否需要继续登录流程
* @returns {boolean} 是否需要继续登录
*/
export const needsContinueLogin = () => {
const step = getCurrentLoginStep()
return step !== LOGIN_STEPS.NOT_LOGGED && step !== LOGIN_STEPS.PROFILE_COMPLETED
}
/**
* 获取下一个应该跳转的页面
* @returns {string|null} 页面路径如果不需要跳转则返回null
*/
export const getNextPage = () => {
const step = getCurrentLoginStep()
switch (step) {
case LOGIN_STEPS.WX_LOGGED:
return '/pages/auth/phone-auth'
case LOGIN_STEPS.PHONE_AUTHED:
case LOGIN_STEPS.PHONE_SKIPPED:
return '/pages/profile/user-info?mode=setup'
case LOGIN_STEPS.PROFILE_COMPLETED:
return '/pages/profile/profile'
default:
return null
}
}
/**
* 保存微信登录信息
* @param {Object} loginData 登录数据
*/
export const saveWxLoginData = (loginData) => {
const { code } = loginData
uni.setStorageSync(STORAGE_KEYS.WX_LOGIN_CODE, code)
uni.setStorageSync(STORAGE_KEYS.LOGIN_DATE, new Date().toISOString())
setLoginStep(LOGIN_STEPS.WX_LOGGED)
console.log('保存微信登录数据:', { code, step: LOGIN_STEPS.WX_LOGGED })
}
/**
* 保存手机号授权信息
* @param {Object} phoneData 手机号数据
*/
export const savePhoneAuthData = (phoneData) => {
const { token, userInfo } = phoneData
if (token) {
uni.setStorageSync(STORAGE_KEYS.TOKEN, token)
}
if (userInfo) {
if (userInfo.phoneNumber) {
uni.setStorageSync(STORAGE_KEYS.PHONE_NUMBER, userInfo.phoneNumber)
}
// 保存微信用户信息供后续使用
const wxUserInfo = {
phoneNumber: userInfo.phoneNumber || '',
openid: userInfo.openid || '',
nickName: userInfo.nickName || '',
avatarUrl: userInfo.avatarUrl || ''
}
uni.setStorageSync(STORAGE_KEYS.WX_USER_INFO, wxUserInfo)
}
setLoginStep(LOGIN_STEPS.PHONE_AUTHED)
console.log('保存手机号授权数据:', { token: !!token, userInfo: !!userInfo })
}
/**
* 标记手机号授权被跳过
*/
export const markPhoneSkipped = () => {
setLoginStep(LOGIN_STEPS.PHONE_SKIPPED)
console.log('标记手机号授权被跳过')
}
/**
* 保存用户信息完善数据
* @param {Object} profileData 用户信息数据
*/
export const saveProfileData = (profileData) => {
uni.setStorageSync(STORAGE_KEYS.USER_INFO, profileData)
setLoginStep(LOGIN_STEPS.PROFILE_COMPLETED)
console.log('保存用户信息完善数据:', profileData)
}
/**
* 清理登录流程中的临时数据
*/
export const clearTempLoginData = () => {
// 清理临时数据,保留重要的用户信息
uni.removeStorageSync(STORAGE_KEYS.WX_LOGIN_CODE)
console.log('清理临时登录数据')
}
/**
* 完全重置登录状态(用于登出)
*/
export const resetLoginState = () => {
uni.removeStorageSync(STORAGE_KEYS.LOGIN_STEP)
uni.removeStorageSync(STORAGE_KEYS.WX_LOGIN_CODE)
uni.removeStorageSync(STORAGE_KEYS.TOKEN)
uni.removeStorageSync(STORAGE_KEYS.PHONE_NUMBER)
uni.removeStorageSync(STORAGE_KEYS.WX_USER_INFO)
uni.removeStorageSync(STORAGE_KEYS.USER_INFO)
uni.removeStorageSync(STORAGE_KEYS.LOGIN_DATE)
console.log('重置登录状态')
}
/**
* 获取登录流程的状态信息(用于内部检查)
* @returns {Object} 状态信息
*/
const getLoginStateInfo = () => {
return {
currentStep: getCurrentLoginStep(),
wxLoginCode: uni.getStorageSync(STORAGE_KEYS.WX_LOGIN_CODE),
hasToken: !!uni.getStorageSync(STORAGE_KEYS.TOKEN),
hasPhoneNumber: !!uni.getStorageSync(STORAGE_KEYS.PHONE_NUMBER),
hasWxUserInfo: !!uni.getStorageSync(STORAGE_KEYS.WX_USER_INFO),
hasUserInfo: !!uni.getStorageSync(STORAGE_KEYS.USER_INFO),
loginDate: uni.getStorageSync(STORAGE_KEYS.LOGIN_DATE)
}
}
/**
* 检查并处理登录流程的断点续传
* @returns {string|null} 需要跳转的页面路径如果不需要跳转则返回null
*/
export const checkAndResumeLogin = () => {
const currentStep = getCurrentLoginStep()
// 如果已完成登录或未开始登录,不需要续传
if (currentStep === LOGIN_STEPS.PROFILE_COMPLETED || currentStep === LOGIN_STEPS.NOT_LOGGED) {
return null
}
// 检查数据完整性
const stateInfo = getLoginStateInfo()
console.log('检查登录断点续传:', stateInfo)
// 根据当前步骤和数据完整性决定下一步
switch (currentStep) {
case LOGIN_STEPS.WX_LOGGED:
// 检查是否有微信登录凭证
if (!stateInfo.wxLoginCode) {
console.warn('微信登录凭证丢失,重置登录状态')
setLoginStep(LOGIN_STEPS.NOT_LOGGED)
return null
}
// 检查登录凭证是否过期超过30分钟
const loginDate = uni.getStorageSync(STORAGE_KEYS.LOGIN_DATE)
if (loginDate) {
const loginTime = new Date(loginDate).getTime()
const now = new Date().getTime()
const timeDiff = now - loginTime
// 如果超过30分钟认为登录凭证过期
if (timeDiff > 30 * 60 * 1000) {
console.warn('微信登录凭证已过期,重置登录状态')
setLoginStep(LOGIN_STEPS.NOT_LOGGED)
return null
}
}
return '/pages/auth/phone-auth'
case LOGIN_STEPS.PHONE_AUTHED:
// 检查是否有token
if (!stateInfo.hasToken) {
console.warn('Token丢失回退到手机号授权')
setLoginStep(LOGIN_STEPS.WX_LOGGED)
return '/pages/auth/phone-auth'
}
return '/pages/profile/user-info?mode=setup'
case LOGIN_STEPS.PHONE_SKIPPED:
return '/pages/profile/user-info?mode=setup&phoneSkipped=true'
default:
console.warn('未知的登录步骤:', currentStep)
setLoginStep(LOGIN_STEPS.NOT_LOGGED)
return null
}
}