pluginLogin.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import { doChangeTabActive } from '@/module-model/tab'
  2. import { openDialog, closeDialog, canShowDialog } from '@/module-model/dialog'
  3. import loginCookie from '@/module-model/loginCookies'
  4. import { ScanCodeLoginDetection } from '@/utils/Login'
  5. import { doSetPageShareId } from '@/module-model/wxQrcode'
  6. import { getADInfo } from '@/module-model/loginLeftAd'
  7. import { clearAllStorageOfReg, trackReport } from '@/utils/common'
  8. import { ajaxSetSignOut } from '@/api'
  9. import LoginAuth from '@/lib/pluginLoginAuth'
  10. import core from '@/lib/core'
  11. import { dispatchCallback, transformResponse } from '@/lib/module'
  12. import { shareState, updateShareState } from '@/module-model/globalState'
  13. class PluginLogin {
  14. hasInited: boolean
  15. options: Record<string, any>
  16. poll: any
  17. emitter: any
  18. constructor({ emitter }) {
  19. this.hasInited = false
  20. this.options = {}
  21. this.emitter = emitter
  22. this.poll = null
  23. this.addListener()
  24. }
  25. addListener () {
  26. // 登录成功后关闭轮询
  27. this.emitter.$on('user-login-success', this.stop.bind(this))
  28. // 更新全局用户状态
  29. this.emitter.$on('user-info-update', this.setState.bind(this))
  30. }
  31. init(options) {
  32. if (this.hasInited) {
  33. console.warn('pluginLogin hasInited')
  34. return
  35. }
  36. this.hasInited = true
  37. this.options = Object.assign(
  38. {
  39. // 立即获取当前登录信息
  40. preloadLoginState: true,
  41. // 页面 num
  42. pageNum: -1,
  43. // 立即预加载弹窗左侧广告图片
  44. preloadDialogImage: false,
  45. // 自动打开弹窗
  46. autoOpen: false,
  47. type: 'login-code',
  48. // 立即获取二维码并自动监听微信扫码登录
  49. preloadWeChatImage: false
  50. },
  51. options
  52. )
  53. this.poll = null
  54. if (this.options.preloadDialogImage) {
  55. this.preload()
  56. }
  57. if (this.options.preloadLoginState) {
  58. this.initPoll()
  59. this.poll.preload()
  60. }
  61. if (this.options.preloadWeChatImage) {
  62. this.start()
  63. }
  64. if (this.options.autoOpen) {
  65. this.open(this.options.type)
  66. }
  67. }
  68. /**
  69. * 预加载
  70. */
  71. preload() {
  72. // 预加载弹窗左侧广告
  73. getADInfo()
  74. }
  75. /**
  76. * 根据 type 打开弹窗并通知
  77. * @param type - 类型
  78. */
  79. open(type = 'login-code') {
  80. doChangeTabActive(type)
  81. openDialog()
  82. this.emit('open', type)
  83. }
  84. /**
  85. * 关闭弹窗并通知
  86. * @param type
  87. */
  88. close(type = '') {
  89. closeDialog()
  90. this.emit('close', type)
  91. }
  92. /**
  93. * 尝试调用 options 配置的公共回调函数
  94. * @param type - 函数名称
  95. * @param data - 参数
  96. */
  97. emit(type, data = null) {
  98. if (typeof this.options[type] === 'function') {
  99. this.options[type](data)
  100. } else {
  101. console.warn('[plugin-login]: not find emit function:', type)
  102. }
  103. }
  104. /**
  105. * 初始化登录检查轮询器
  106. */
  107. initPoll() {
  108. if (!this.poll) {
  109. this.poll = new ScanCodeLoginDetection({
  110. num: this.options.pageNum,
  111. update: (type, data) => {
  112. if (type === 'shareId') {
  113. const { kopShareId, shareId } = data
  114. doSetPageShareId(shareId, kopShareId)
  115. }
  116. if (type === 'login') {
  117. this.emit('update', data)
  118. this.handleUpdateInfo('poll', data)
  119. }
  120. },
  121. success: (data) => {
  122. this.emit('success', data)
  123. this.handleUpdateInfo('poll', data)
  124. this.handleSuccess('poll', data)
  125. }
  126. })
  127. }
  128. }
  129. /**
  130. * 开始轮询
  131. */
  132. start() {
  133. this.initPoll()
  134. this.poll.start()
  135. }
  136. /**
  137. * 停止轮询
  138. */
  139. stop() {
  140. this.poll?.stop()
  141. }
  142. /**
  143. * 获取全局状态
  144. */
  145. getState() {
  146. return shareState.value
  147. }
  148. setState ({ format }) {
  149. if (format) {
  150. updateShareState(format)
  151. }
  152. }
  153. /**
  154. * 退出登录
  155. */
  156. doSignOut() {
  157. return ajaxSetSignOut().then(({ data }) => {
  158. if (data === 'ok') {
  159. clearAllStorageOfReg(/-login-clear/)
  160. loginCookie.clear()
  161. this.emitUserSignOut()
  162. }
  163. })
  164. }
  165. /**
  166. * 处理信息相关更新
  167. * @param type - 类型
  168. * @param data
  169. */
  170. handleUpdateInfo (type, data) {
  171. this.emitUserInfoUpdate(transformResponse(type, data))
  172. }
  173. /**
  174. * 处理弹窗业务成功相关
  175. * @param type - 类型
  176. * @param data
  177. */
  178. handleSuccess (type, data) {
  179. dispatchCallback(type, data)
  180. }
  181. /**
  182. * 广播用户退出事件
  183. */
  184. emitUserSignOut () {
  185. this.emitter.$emit('user-sign-out', {}, {
  186. cross: true
  187. })
  188. }
  189. /**
  190. * 广播用户信息更新事件
  191. * @param data - 用户信息
  192. */
  193. emitUserInfoUpdate (data) {
  194. this.emitter.$emit('user-info-update', data, {
  195. cross: true,
  196. replay: true
  197. })
  198. }
  199. /**
  200. * 广播用户登录成功事件
  201. * @param data
  202. */
  203. emitUserLoginSuccess (data) {
  204. if (canShowDialog.value) {
  205. this.close('user-login-success')
  206. }
  207. this.emitter.$emit('user-login-success', data, {
  208. cross: true
  209. })
  210. }
  211. }
  212. const pluginLogin = new PluginLogin({
  213. emitter: core
  214. })
  215. function addHook (hook) {
  216. LoginAuth.register(hook, pluginLogin[hook].bind(pluginLogin))
  217. }
  218. // 注入 hooks
  219. ['open', 'doSignOut', 'close', 'init', 'getState'].forEach(hook => addHook(hook))
  220. export default pluginLogin