import { IS_LOGIN_STORAGE_KEY } from '@/xiaolanbenlib/constant' import { ButtonProps } from '@tarojs/components' import Taro, { useDidShow } from '@tarojs/taro' import { useCallback, useEffect, useState } from 'react' import { loginWithoutAuthorize, loginWithoutAuthorizeProps, } from '../../api/auth' import { getNewCode, updateUserInfo } from '../../utils/auth' import { emitter } from '../../utils/event' export function onLogin() { Taro.setStorageSync(IS_LOGIN_STORAGE_KEY, '1') emitter.emit('login') } export function onLogout() { Taro.removeStorageSync(IS_LOGIN_STORAGE_KEY) emitter.emit('logout') } let pending = false // 拉起手机授权登录 export function loginByMobile({ res, sucMsg, failMsg, code, }): Promise { const detail = res.detail if (pending) { // 暂时只考虑用户多次快速点击的场景,在前一个请求没结束之前,直接返回一直pedding的promise return new Promise(() => ({}) as loginWithoutAuthorizeProps) } pending = true return new Promise((resolve, reject) => { loginWithoutAuthorize({ code, mobileEncryptedData: detail.encryptedData, mobileIv: detail.iv, }).then( (data) => { pending = false Taro.showToast({ title: sucMsg || '登录成功', icon: 'success', duration: 1500, }) resolve(data) }, (err) => { console.log(err) pending = false Taro.showToast({ title: failMsg || '登录失败', icon: 'none', duration: 1500, }) reject(err) }, ) }) } export function useLogin(params?: { onConfirm?: () => void onSuccess?: () => void disabled?: boolean }) { const [code, setCode] = useState('') function onGetPhoneNumber(res) { params?.onConfirm?.() const detail: ButtonProps.onGetPhoneNumberEventDetail = res.detail if (detail.iv && detail.encryptedData) { loginByMobile({ res, sucMsg: '登录成功', failMsg: '登录失败', code: code, }).then( async (data) => { updateUserInfo(data) onLogin() params?.onSuccess?.() }, (err) => { console.log(err) Taro.showToast({ title: '登录失败1', icon: 'none', duration: 1500, }) }, ) } } function onClick() { getNewCode().then((res) => { setCode(res) }) } function onError() { Taro.showToast({ title: '登录失败3', icon: 'none', duration: 1500, }) } return { onGetPhoneNumber, onError, onClick, openType: params?.disabled ? undefined : ('getPhoneNumber' as ButtonProps.OpenType), } } export function useIsLogin() { const [isLogin, setIsLogin] = useState(false) const updateLoginStateStable = useCallback(() => { const newState = Taro.getStorageSync('hasLogin') === '1' if (newState !== isLogin) { setIsLogin(newState) } }, [isLogin]) useEffect(() => { emitter.on('login', () => { setIsLogin(true) }) emitter.on('logout', () => { setIsLogin(false) }) updateLoginStateStable() return () => { emitter.off('login') emitter.off('logout') } }, []) useDidShow(() => { updateLoginStateStable() }) return isLogin }