fix:图片访问
fix:权限修改
This commit is contained in:
1 parent
dec9fd96e3
commit
d86bc810cc
69 files changed
+1264
-458
No files matched your search
@@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { shallowRef, watch } from 'vue'
|
||||
import { ElImage } from 'element-plus'
|
||||
import { accessFileUrl, fileUrls, originalFileUrl, resolveFileUrl, fileAccessRevision, retryFileAccess } from '/@/utils/file-access'
|
||||
|
||||
defineOptions({ inheritAttrs: false })
|
||||
const props = withDefaults(defineProps<{ src?: string; previewSrcList?: string[] }>(), {
|
||||
src: '', previewSrcList: () => [],
|
||||
})
|
||||
const emit = defineEmits<{
|
||||
load: [event: Event]
|
||||
error: [event: Event]
|
||||
show: []
|
||||
switch: [index: number]
|
||||
close: []
|
||||
}>()
|
||||
const displaySrc = shallowRef('')
|
||||
const previewSources = shallowRef<string[]>([])
|
||||
let generation = 0
|
||||
let loaded = false
|
||||
let failed = false
|
||||
let pending = false
|
||||
let lastError: Event
|
||||
|
||||
const identity = (source: string) => resolveFileUrl(originalFileUrl(source))
|
||||
const refreshPreview = () => { previewSources.value = fileUrls(props.previewSrcList) }
|
||||
|
||||
// An already decoded image remains visible after its request signature expires.
|
||||
// Only a changed business reference or a failed request needs a new thumbnail request.
|
||||
watch(() => identity(props.src), () => {
|
||||
generation++
|
||||
loaded = failed = pending = false
|
||||
displaySrc.value = accessFileUrl(props.src)
|
||||
}, { immediate: true })
|
||||
watch(() => JSON.stringify(props.previewSrcList.map(identity)), refreshPreview, { immediate: true })
|
||||
|
||||
function onLoad(event: Event) { loaded = true; failed = false; emit('load', event) }
|
||||
async function onError(event: Event) {
|
||||
failed = true
|
||||
lastError = event
|
||||
if (pending) return
|
||||
const current = generation
|
||||
pending = true
|
||||
try {
|
||||
const retried = await retryFileAccess(props.src)
|
||||
if (current !== generation) return
|
||||
if (retried) {
|
||||
failed = false
|
||||
displaySrc.value = accessFileUrl(props.src)
|
||||
} else emit('error', event)
|
||||
} finally { if (current === generation) pending = false }
|
||||
}
|
||||
watch(fileAccessRevision, () => {
|
||||
if (loaded || pending) return
|
||||
const renewed = accessFileUrl(props.src)
|
||||
if (renewed !== displaySrc.value) {
|
||||
failed = false
|
||||
displaySrc.value = renewed
|
||||
} else if (failed) void onError(lastError)
|
||||
})
|
||||
function onShow() { refreshPreview(); emit('show') }
|
||||
function onSwitch(index: number) { refreshPreview(); emit('switch', index) }
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ElImage v-bind="$attrs" :src="displaySrc" :preview-src-list="previewSources"
|
||||
@load="onLoad" @error="onError" @show="onShow" @switch="onSwitch" @close="emit('close')">
|
||||
<template v-for="(_, name) in $slots" #[name]="scope">
|
||||
<slot :name="name" v-bind="scope || {}" />
|
||||
</template>
|
||||
</ElImage>
|
||||
</template>
|
||||
Reference in new issue
Block a user