fix(pda): leave expired sessions and clarify dispatch navigation
This commit is contained in:
+40
-13
@@ -1,7 +1,18 @@
|
||||
import { refresh } from './auth.js'
|
||||
import { session, replaceTokens, signOut } from '../stores/session.js'
|
||||
import { session, replaceTokens, signOut, getSessionRevision } from '../stores/session.js'
|
||||
|
||||
let refreshPromise = null
|
||||
let refreshRevision = -1
|
||||
|
||||
function requireCurrentSession(revision) {
|
||||
if (revision !== getSessionRevision()) throw new Error('登录会话已变更,请重新操作')
|
||||
}
|
||||
|
||||
function expireSession(revision) {
|
||||
if (revision !== getSessionRevision()) return
|
||||
signOut()
|
||||
uni.reLaunch({ url: '/pages/login/login' })
|
||||
}
|
||||
|
||||
function errorFrom(response, fallback) {
|
||||
const body = response?.data || {}
|
||||
@@ -21,23 +32,27 @@ function successful(response, body) {
|
||||
return response?.statusCode === 200 && ['00000', '200'].includes(String(body?.code))
|
||||
}
|
||||
|
||||
async function refreshOverseasToken() {
|
||||
async function refreshOverseasToken(revision) {
|
||||
requireCurrentSession(revision)
|
||||
if (!session.refreshToken) {
|
||||
signOut()
|
||||
expireSession(revision)
|
||||
throw new Error('登录状态已过期,请重新登录')
|
||||
}
|
||||
if (!refreshPromise) {
|
||||
refreshPromise = refresh(session.refreshToken)
|
||||
.then((tokens) => { replaceTokens(tokens); return session.token })
|
||||
.catch((error) => { signOut(); throw error })
|
||||
.finally(() => { refreshPromise = null })
|
||||
if (!refreshPromise || refreshRevision !== revision) {
|
||||
refreshRevision = revision
|
||||
const pending = refresh(session.refreshToken)
|
||||
.then((tokens) => { requireCurrentSession(revision); replaceTokens(tokens); return session.token })
|
||||
.catch((error) => { expireSession(revision); throw error })
|
||||
.finally(() => { if (refreshPromise === pending) refreshPromise = null })
|
||||
refreshPromise = pending
|
||||
}
|
||||
return refreshPromise
|
||||
}
|
||||
|
||||
async function tokenAfterUnauthorized(failedToken) {
|
||||
async function tokenAfterUnauthorized(failedToken, revision) {
|
||||
requireCurrentSession(revision)
|
||||
if (session.token && session.token !== failedToken) return session.token
|
||||
return refreshOverseasToken()
|
||||
return refreshOverseasToken(revision)
|
||||
}
|
||||
|
||||
function overseasUrl(path) {
|
||||
@@ -70,13 +85,17 @@ function rawRequest(method, path, data, token) {
|
||||
}
|
||||
|
||||
export async function overseasRequest(method, path, data, retry = true) {
|
||||
const revision = getSessionRevision()
|
||||
console.info('[Overseas PDA API] request', { method, path })
|
||||
const attemptedToken = session.token
|
||||
let response = await rawRequest(method, path, data, attemptedToken)
|
||||
requireCurrentSession(revision)
|
||||
if (retry && unauthorized(response)) {
|
||||
const replacementToken = await tokenAfterUnauthorized(attemptedToken)
|
||||
const replacementToken = await tokenAfterUnauthorized(attemptedToken, revision)
|
||||
response = await rawRequest(method, path, data, replacementToken)
|
||||
}
|
||||
requireCurrentSession(revision)
|
||||
if (unauthorized(response)) expireSession(revision)
|
||||
const body = response?.data || {}
|
||||
console.info('[Overseas PDA API] response', { method, path, statusCode: response?.statusCode, code: body?.code,
|
||||
message: body?.message, requestId: body?.requestId || response?.header?.['x-request-id'] || response?.header?.['X-Request-Id'],
|
||||
@@ -149,27 +168,35 @@ function rawDownload(path, token) {
|
||||
}
|
||||
|
||||
export async function overseasUpload(path, filePath, name = 'file', retry = true) {
|
||||
const revision = getSessionRevision()
|
||||
const attemptedToken = session.token
|
||||
let response = await rawUpload(path, filePath, name, attemptedToken)
|
||||
requireCurrentSession(revision)
|
||||
let body = null
|
||||
try { body = JSON.parse(response.data || '{}') } catch (_) { /* handled below */ }
|
||||
if (retry && unauthorized({ ...response, data: body })) {
|
||||
const replacementToken = await tokenAfterUnauthorized(attemptedToken)
|
||||
const replacementToken = await tokenAfterUnauthorized(attemptedToken, revision)
|
||||
response = await rawUpload(path, filePath, name, replacementToken)
|
||||
try { body = JSON.parse(response.data || '{}') } catch (_) { body = null }
|
||||
}
|
||||
requireCurrentSession(revision)
|
||||
if (unauthorized({ ...response, data: body })) expireSession(revision)
|
||||
if (!successful(response, body)) throw errorFrom({ ...response, data: body }, '海外作业文件上传失败')
|
||||
return body.data
|
||||
}
|
||||
|
||||
export async function overseasDownload(path, options = {}) {
|
||||
const revision = getSessionRevision()
|
||||
const { retry = true, expectedContentTypePrefix = '' } = options
|
||||
const attemptedToken = session.token
|
||||
let response = await rawDownload(path, attemptedToken)
|
||||
requireCurrentSession(revision)
|
||||
if (retry && unauthorized(response)) {
|
||||
const replacementToken = await tokenAfterUnauthorized(attemptedToken)
|
||||
const replacementToken = await tokenAfterUnauthorized(attemptedToken, revision)
|
||||
response = await rawDownload(path, replacementToken)
|
||||
}
|
||||
requireCurrentSession(revision)
|
||||
if (unauthorized(response)) expireSession(revision)
|
||||
if (response?.statusCode !== 200 || !response?.tempFilePath) {
|
||||
throw errorFrom({ ...response, data: {} }, '签收照片下载失败')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user