Files
admin-web/src/modules/inbounds/weight/components/WeightImageThumbnail.vue
T
2026-08-07 20:07:37 +08:00

65 lines
2.1 KiB
Vue

<script setup lang="ts">
import { onBeforeUnmount, ref, watch } from 'vue'
import { ImageOff } from '@lucide/vue'
import { downloadWeightThumbnail } from '../api/weightOcr'
const props = defineProps<{
customerId: string
inboundId: string
fileId: string
alt: string
}>()
defineEmits<{ open: [] }>()
const imageUrl = ref('')
const loading = ref(false)
const failed = ref(false)
let requestId = 0
function releaseImage() {
if (imageUrl.value) URL.revokeObjectURL(imageUrl.value)
imageUrl.value = ''
}
async function load() {
const currentRequest = ++requestId
releaseImage()
failed.value = false
loading.value = true
try {
const blob = await downloadWeightThumbnail(props.customerId, props.inboundId, props.fileId)
if (currentRequest !== requestId) return
imageUrl.value = URL.createObjectURL(blob)
} catch {
if (currentRequest === requestId) failed.value = true
} finally {
if (currentRequest === requestId) loading.value = false
}
}
watch(() => [props.customerId, props.inboundId, props.fileId], load, { immediate: true })
onBeforeUnmount(() => {
requestId += 1
releaseImage()
})
</script>
<template>
<button class="weight-thumb" type="button" :aria-label="`查看${alt}`" @click="$emit('open')">
<img v-if="imageUrl" :src="imageUrl" :alt="alt" loading="lazy" />
<span v-else class="weight-thumb__state" :class="{ 'is-loading': loading }">
<ImageOff v-if="failed" :size="22" aria-hidden="true" />
<span>{{ failed ? '图片加载失败' : '图片加载中' }}</span>
</span>
</button>
</template>
<style scoped>
.weight-thumb { display: block; width: 100%; aspect-ratio: 4 / 3; overflow: hidden; padding: 0; border: 0; border-radius: 6px 6px 0 0; background: #f2f4f7; cursor: zoom-in; }
.weight-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.weight-thumb__state { display: grid; width: 100%; height: 100%; place-items: center; align-content: center; gap: 7px; color: #667085; font-size: 12px; }
.weight-thumb__state.is-loading { color: #98a2b3; }
.weight-thumb:focus-visible { outline: 2px solid var(--cc-primary); outline-offset: 2px; }
</style>