前端热更新
This commit is contained in:
1 parent
af88732a07
commit
5b95fe8f40
3 files changed
+19
-16
No files matched your search
+11
-4
@@ -8,6 +8,13 @@ import {
|
||||
refreshIfNeeded,
|
||||
} from '../auth/session'
|
||||
|
||||
declare module 'axios' {
|
||||
export interface AxiosRequestConfig {
|
||||
// Public kiosk pages must remain usable when this browser has an expired login session.
|
||||
skipAuthSession?: boolean
|
||||
}
|
||||
}
|
||||
|
||||
const http = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE_URL ?? '/api',
|
||||
timeout: 15000,
|
||||
@@ -20,12 +27,12 @@ http.interceptors.request.use(async (config) => {
|
||||
config.url?.endsWith('/auth/logout') ||
|
||||
config.url?.endsWith('/auth/sso/exchange') ||
|
||||
config.url?.endsWith('/auth/sso/bind')
|
||||
if (!isAuthenticationRequest) {
|
||||
if (!isAuthenticationRequest && !config.skipAuthSession) {
|
||||
const activeToken = await refreshIfNeeded(true)
|
||||
if (activeToken) markActivity()
|
||||
}
|
||||
const token = localStorage.getItem(authStorageKeys.token)
|
||||
if (token) config.headers.Authorization = `Bearer ${token}`
|
||||
if (token && !config.skipAuthSession) config.headers.Authorization = `Bearer ${token}`
|
||||
return config
|
||||
})
|
||||
|
||||
@@ -40,7 +47,7 @@ http.interceptors.response.use(
|
||||
error.config?.url?.endsWith('/auth/sso/bind')
|
||||
const retryableConfig = error.config as
|
||||
(typeof error.config & { _jiaowuRetried?: boolean }) | undefined
|
||||
if (error.response?.status === 401 && !isAuthenticationRequest &&
|
||||
if (error.response?.status === 401 && !isAuthenticationRequest && !error.config?.skipAuthSession &&
|
||||
!retryableConfig?._jiaowuRetried) {
|
||||
const token = await refreshAuthSession()
|
||||
if (token && retryableConfig) {
|
||||
@@ -49,7 +56,7 @@ http.interceptors.response.use(
|
||||
return http.request(retryableConfig)
|
||||
}
|
||||
}
|
||||
if (error.response?.status === 401 && !isAuthenticationRequest) {
|
||||
if (error.response?.status === 401 && !isAuthenticationRequest && !error.config?.skipAuthSession) {
|
||||
clearAuthSession()
|
||||
goLogin(location.pathname + location.search + location.hash)
|
||||
}
|
||||
|
||||
@@ -18,10 +18,8 @@ interface AppUpdateCheckResponse {
|
||||
|
||||
const updateChannel =
|
||||
import.meta.env.VITE_APP_UPDATE_CHANNEL?.trim() || 'production'
|
||||
const foregroundCheckInterval = 5 * 60 * 1000
|
||||
|
||||
let checkInProgress: Promise<void> | undefined
|
||||
let lastCheckedAt = 0
|
||||
|
||||
function absoluteApiUrl(relativePath: string) {
|
||||
const configuredBase = String(http.defaults.baseURL ?? '/api')
|
||||
@@ -36,9 +34,7 @@ function absoluteApiUrl(relativePath: string) {
|
||||
|
||||
async function checkForAppUpdate() {
|
||||
if (checkInProgress) return checkInProgress
|
||||
if (!navigator.onLine || Date.now() - lastCheckedAt < foregroundCheckInterval) {
|
||||
return
|
||||
}
|
||||
if (!navigator.onLine) return
|
||||
|
||||
checkInProgress = (async () => {
|
||||
try {
|
||||
@@ -64,6 +60,9 @@ async function checkForAppUpdate() {
|
||||
nativeVersion: current.native,
|
||||
currentVersion,
|
||||
},
|
||||
// Update discovery is deliberately public. Do not delay startup for a
|
||||
// token refresh or send a stale Authorization header to this endpoint.
|
||||
skipAuthSession: true,
|
||||
timeout: 15000,
|
||||
},
|
||||
)
|
||||
@@ -96,7 +95,6 @@ async function checkForAppUpdate() {
|
||||
// OTA failure must never stop users from entering the bundled application.
|
||||
console.warn('[app-update] update check failed', error)
|
||||
} finally {
|
||||
lastCheckedAt = Date.now()
|
||||
checkInProgress = undefined
|
||||
}
|
||||
})()
|
||||
@@ -116,10 +114,8 @@ export async function initializeAppUpdates() {
|
||||
console.warn('[app-update] bundle readiness confirmation failed', error)
|
||||
}
|
||||
|
||||
// Every cold start checks the latest public release immediately. A bundle
|
||||
// downloaded here is activated when the app is next launched.
|
||||
void checkForAppUpdate()
|
||||
window.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
void checkForAppUpdate()
|
||||
}
|
||||
})
|
||||
window.addEventListener('online', () => void checkForAppUpdate())
|
||||
}
|
||||
@@ -23,7 +23,7 @@ async function load() {
|
||||
if (loading) return
|
||||
loading = true
|
||||
try {
|
||||
data.value = (await http.get(`/venue-displays/${type.value}s/${id.value}`)).data
|
||||
data.value = (await http.get(`/venue-displays/${type.value}s/${id.value}`, { skipAuthSession: true })).data
|
||||
await nextTick()
|
||||
fitPage()
|
||||
} finally {
|
||||
|
||||
Reference in new issue
Block a user