Files
shanxia2.0/web-admin/src/api/mp-webview.ts
T
2026-09-17 09:10:10 +08:00

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
}
}