73 lines
1.9 KiB
TypeScript
73 lines
1.9 KiB
TypeScript
import request from '@/utils/http'
|
|
|
|
type ExchangeResult = {
|
|
token: string
|
|
refreshToken: string
|
|
expiresIn: number
|
|
userInfo: Api.Auth.UserInfo
|
|
}
|
|
|
|
const SS_PREFIX = 'mp_wv_ex:'
|
|
|
|
/** 同一 ticket 只兑换一次,避免 Shell 重复挂载 / web-view 二次加载把一次性票用掉 */
|
|
const exchangeInflight = new Map<string, Promise<ExchangeResult>>()
|
|
const exchangeDone = new Map<string, ExchangeResult>()
|
|
|
|
function readSessionCache(key: string): ExchangeResult | null {
|
|
if (typeof sessionStorage === 'undefined') return null
|
|
try {
|
|
const raw = sessionStorage.getItem(SS_PREFIX + key)
|
|
if (!raw) return null
|
|
const data = JSON.parse(raw) as ExchangeResult
|
|
if (!data?.token || !data?.refreshToken) return null
|
|
return data
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
function writeSessionCache(key: string, data: ExchangeResult) {
|
|
if (typeof sessionStorage === 'undefined') return
|
|
try {
|
|
sessionStorage.setItem(SS_PREFIX + key, JSON.stringify(data))
|
|
} catch {
|
|
/* quota / private mode */
|
|
}
|
|
}
|
|
|
|
export const mpWebviewApi = {
|
|
exchange: (ticket: string) => {
|
|
const key = String(ticket || '').trim()
|
|
if (!key) {
|
|
return Promise.reject(new Error('ticket不能为空'))
|
|
}
|
|
const mem = exchangeDone.get(key)
|
|
if (mem) return Promise.resolve(mem)
|
|
const ss = readSessionCache(key)
|
|
if (ss) {
|
|
exchangeDone.set(key, ss)
|
|
return Promise.resolve(ss)
|
|
}
|
|
const pending = exchangeInflight.get(key)
|
|
if (pending) return pending
|
|
const req = request
|
|
.post<ExchangeResult>({
|
|
url: '/web/auth/mp-webview-exchange',
|
|
data: { ticket: key },
|
|
showErrorMessage: false
|
|
})
|
|
.then((data) => {
|
|
exchangeDone.set(key, data)
|
|
writeSessionCache(key, data)
|
|
exchangeInflight.delete(key)
|
|
return data
|
|
})
|
|
.catch((err) => {
|
|
exchangeInflight.delete(key)
|
|
throw err
|
|
})
|
|
exchangeInflight.set(key, req)
|
|
return req
|
|
}
|
|
}
|