完善掉线诊断并优化二维码加载
This commit is contained in:
@@ -35,6 +35,10 @@ const previewURLs = ref<string[]>([])
|
||||
const failed = ref(false)
|
||||
const createdURLs: string[] = []
|
||||
|
||||
const maxConcurrentAuthImageLoads = 6
|
||||
let activeAuthImageLoads = 0
|
||||
const authImageLoadQueue: Array<() => void> = []
|
||||
|
||||
const usePreview = computed(() => !!props.previewSrcList?.length)
|
||||
const effectiveAdmin = computed(() => props.admin || isAdminPath(window.location.pathname))
|
||||
const fallbackText = computed(() => (failed.value ? '图片加载失败' : '图片加载中'))
|
||||
@@ -42,6 +46,26 @@ const imageStyleValue = computed(() => {
|
||||
if (!props.fit) return props.imageStyle
|
||||
return [props.imageStyle, { objectFit: props.fit }]
|
||||
})
|
||||
const previewSignature = computed(() => props.previewSrcList?.join('\u0000') || '')
|
||||
|
||||
function withAuthImageLoadSlot<T>(task: () => Promise<T>): Promise<T> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const run = () => {
|
||||
activeAuthImageLoads++
|
||||
task()
|
||||
.then(resolve, reject)
|
||||
.finally(() => {
|
||||
activeAuthImageLoads--
|
||||
authImageLoadQueue.shift()?.()
|
||||
})
|
||||
}
|
||||
if (activeAuthImageLoads < maxConcurrentAuthImageLoads) {
|
||||
run()
|
||||
return
|
||||
}
|
||||
authImageLoadQueue.push(run)
|
||||
})
|
||||
}
|
||||
|
||||
function extractObjectKey(value: string) {
|
||||
try {
|
||||
@@ -63,8 +87,9 @@ function shouldFetchAsAdmin(value: string) {
|
||||
async function resolveURL(url: string): Promise<string> {
|
||||
if (!url || !shouldFetchWithAuth(url)) return url
|
||||
const key = extractObjectKey(url)
|
||||
const blob =
|
||||
shouldFetchAsAdmin(url) && key ? await fetchAdminFileBlob(key) : await fetchFileBlobByURL(url)
|
||||
const blob = await withAuthImageLoadSlot(() =>
|
||||
shouldFetchAsAdmin(url) && key ? fetchAdminFileBlob(key) : fetchFileBlobByURL(url)
|
||||
)
|
||||
const blobURL = URL.createObjectURL(blob)
|
||||
createdURLs.push(blobURL)
|
||||
return blobURL
|
||||
@@ -87,18 +112,20 @@ async function loadImage() {
|
||||
}
|
||||
|
||||
try {
|
||||
imageURL.value = await resolveURL(props.source)
|
||||
const sourceURL = await resolveURL(props.source)
|
||||
imageURL.value = sourceURL
|
||||
if (props.previewSrcList?.length) {
|
||||
previewURLs.value = await Promise.all(props.previewSrcList.map(resolveURL))
|
||||
previewURLs.value = await Promise.all(
|
||||
props.previewSrcList.map(url => (url === props.source ? sourceURL : resolveURL(url)))
|
||||
)
|
||||
}
|
||||
} catch {
|
||||
failed.value = true
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => [props.source, effectiveAdmin.value, props.previewSrcList] as const, loadImage, {
|
||||
watch(() => [props.source, effectiveAdmin.value, previewSignature.value] as const, loadImage, {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
})
|
||||
|
||||
onBeforeUnmount(cleanup)
|
||||
|
||||
Reference in New Issue
Block a user