| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- export const initialBindingState = () => ({
- ready: false, enabled: false, bound: false, subscribed: false, busy: false,
- sessionId: '', sessionStatus: '', sessionSubscribed: false, verificationCode: '', error: ''
- })
- export function createWechatBindingFlow({ state, api, getSessionKey, isActive, openAuthorization }) {
- let owner = '', revision = 0
- const cancel = () => { revision++; state.busy = false }
- const clearSession = () => {
- state.sessionId = ''; state.sessionStatus = ''; state.sessionSubscribed = false; state.verificationCode = ''
- }
- const run = async (operation) => {
- const key = getSessionKey()
- if (owner !== key) {
- cancel()
- Object.assign(state, initialBindingState())
- owner = key
- }
- if (!key || !isActive() || state.busy) return
- const version = ++revision
- const current = () => version === revision && isActive() && getSessionKey() === key
- state.busy = true
- state.error = ''
- try { await operation(current) } catch (error) {
- if (current()) state.error = error?.message || '绑定操作失败,请重试'
- } finally {
- if (current()) state.busy = false
- }
- }
- const refresh = () => run(async (current) => {
- state.ready = false
- const status = await api.status()
- if (!current()) return
- Object.assign(state, status, { ready: true })
- if (!status.enabled || status.bound) { clearSession(); return }
- if (!state.sessionId) return
- const session = await api.session(state.sessionId)
- if (!current()) return
- if (session.status === 'expired') {
- clearSession()
- state.error = '授权会话已过期,请重新绑定'
- return
- }
- state.sessionStatus = session.status
- state.sessionSubscribed = session.subscribed
- state.verificationCode = session.verificationCode || ''
- if (session.status !== 'scanned') return
- if (!session.subscribed) {
- state.error = '请先关注服务号,再重新授权绑定'
- return
- }
- // 仅确认本页面由当前登录用户主动发起的会话;回调网页不持有登录令牌。
- const result = await api.confirm(state.sessionId)
- if (!current()) return
- if (!result.bound || !result.subscribed) throw new Error('绑定未完成,请刷新状态后重试')
- Object.assign(state, result)
- clearSession()
- })
- const start = () => run(async (current) => {
- if (!state.ready || !state.enabled || state.bound) return
- clearSession()
- const session = await api.start()
- if (!current()) return
- state.sessionId = session.sessionId
- state.sessionStatus = 'waiting'
- await openAuthorization(session.authorizeUrl)
- })
- return { refresh, start, cancel }
- }
|