useAuth.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import { IS_LOGIN_STORAGE_KEY } from '@/xiaolanbenlib/constant'
  2. import { ButtonProps } from '@tarojs/components'
  3. import Taro, { useDidShow } from '@tarojs/taro'
  4. import { useCallback, useEffect, useState } from 'react'
  5. import {
  6. loginWithoutAuthorize,
  7. loginWithoutAuthorizeProps,
  8. } from '../../api/auth'
  9. import { getNewCode, updateUserInfo } from '../../utils/auth'
  10. import { emitter } from '../../utils/event'
  11. export function onLogin() {
  12. Taro.setStorageSync(IS_LOGIN_STORAGE_KEY, '1')
  13. emitter.emit('login')
  14. }
  15. export function onLogout() {
  16. Taro.removeStorageSync(IS_LOGIN_STORAGE_KEY)
  17. emitter.emit('logout')
  18. }
  19. let pending = false
  20. // 拉起手机授权登录
  21. export function loginByMobile({
  22. res,
  23. sucMsg,
  24. failMsg,
  25. code,
  26. }): Promise<loginWithoutAuthorizeProps> {
  27. const detail = res.detail
  28. if (pending) {
  29. // 暂时只考虑用户多次快速点击的场景,在前一个请求没结束之前,直接返回一直pedding的promise
  30. return new Promise(() => ({}) as loginWithoutAuthorizeProps)
  31. }
  32. pending = true
  33. return new Promise((resolve, reject) => {
  34. loginWithoutAuthorize({
  35. code,
  36. mobileEncryptedData: detail.encryptedData,
  37. mobileIv: detail.iv,
  38. }).then(
  39. (data) => {
  40. pending = false
  41. Taro.showToast({
  42. title: sucMsg || '登录成功',
  43. icon: 'success',
  44. duration: 1500,
  45. })
  46. resolve(data)
  47. },
  48. (err) => {
  49. console.log(err)
  50. pending = false
  51. Taro.showToast({
  52. title: failMsg || '登录失败',
  53. icon: 'none',
  54. duration: 1500,
  55. })
  56. reject(err)
  57. },
  58. )
  59. })
  60. }
  61. export function useLogin(params?: {
  62. onConfirm?: () => void
  63. onSuccess?: () => void
  64. disabled?: boolean
  65. }) {
  66. const [code, setCode] = useState('')
  67. function onGetPhoneNumber(res) {
  68. params?.onConfirm?.()
  69. const detail: ButtonProps.onGetPhoneNumberEventDetail = res.detail
  70. if (detail.iv && detail.encryptedData) {
  71. loginByMobile({
  72. res,
  73. sucMsg: '登录成功',
  74. failMsg: '登录失败',
  75. code: code,
  76. }).then(
  77. async (data) => {
  78. updateUserInfo(data)
  79. onLogin()
  80. params?.onSuccess?.()
  81. },
  82. (err) => {
  83. console.log(err)
  84. Taro.showToast({
  85. title: '登录失败1',
  86. icon: 'none',
  87. duration: 1500,
  88. })
  89. },
  90. )
  91. }
  92. }
  93. function onClick() {
  94. getNewCode().then((res) => {
  95. setCode(res)
  96. })
  97. }
  98. function onError() {
  99. Taro.showToast({
  100. title: '登录失败3',
  101. icon: 'none',
  102. duration: 1500,
  103. })
  104. }
  105. return {
  106. onGetPhoneNumber,
  107. onError,
  108. onClick,
  109. openType: params?.disabled
  110. ? undefined
  111. : ('getPhoneNumber' as ButtonProps.OpenType),
  112. }
  113. }
  114. export function useIsLogin() {
  115. const [isLogin, setIsLogin] = useState(false)
  116. const updateLoginStateStable = useCallback(() => {
  117. const newState = Taro.getStorageSync('hasLogin') === '1'
  118. if (newState !== isLogin) {
  119. setIsLogin(newState)
  120. }
  121. }, [isLogin])
  122. useEffect(() => {
  123. emitter.on('login', () => {
  124. setIsLogin(true)
  125. })
  126. emitter.on('logout', () => {
  127. setIsLogin(false)
  128. })
  129. updateLoginStateStable()
  130. return () => {
  131. emitter.off('login')
  132. emitter.off('logout')
  133. }
  134. }, [])
  135. useDidShow(() => {
  136. updateLoginStateStable()
  137. })
  138. return isLogin
  139. }