feat(record): 留痕详情照片预览
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2ae7aec861
commit
b21d7fb163
@ -122,6 +122,11 @@ export function getRecord(id: string): Promise<ServiceRecordDetail> {
|
||||
return http.get<ServiceRecordDetail>(`/record/${id}`)
|
||||
}
|
||||
|
||||
/** 照片 GET 预签名 URL(临时预览/下载,默认 1 小时有效)。 */
|
||||
export function getPhotoUrl(photoId: string): Promise<{ url: string }> {
|
||||
return http.get<{ url: string }>(`/record/photo/${photoId}/url`)
|
||||
}
|
||||
|
||||
/** 垫付台账:某老人 is_prepaid=1 的留痕列表。 */
|
||||
export function listPrepaidRecords(elderId: string): Promise<ServiceRecord[]> {
|
||||
return http.get<ServiceRecord[]>('/record/prepaid-list', { params: { elderId } })
|
||||
|
||||
@ -70,7 +70,21 @@
|
||||
|
||||
<el-divider content-position="left">照片</el-divider>
|
||||
<el-table v-if="detail.photos.length > 0" :data="detail.photos" border size="small">
|
||||
<el-table-column prop="filePath" label="文件 Key(MinIO)" min-width="280" />
|
||||
<el-table-column label="预览" min-width="140" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip v-if="photoUrlOf(row.id)" :content="row.filePath" placement="top">
|
||||
<el-image
|
||||
:src="photoUrlOf(row.id)"
|
||||
:preview-src-list="[photoUrlOf(row.id)]"
|
||||
preview-teleported
|
||||
fit="cover"
|
||||
class="record-page__photo"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<span v-else-if="photoFailed(row.id)" class="text-xs text-text-placeholder">获取失败</span>
|
||||
<span v-else class="text-xs text-text-placeholder">加载中…</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="fileSize" label="大小(字节)" width="120" align="right" />
|
||||
<el-table-column label="上传时间" width="160">
|
||||
<template #default="{ row }">{{ formatDateTime(row.createdAt) }}</template>
|
||||
@ -115,6 +129,7 @@ import {
|
||||
EXEC_RESULT_TAG_MAP,
|
||||
LOCATE_STATUS_TAG_MAP,
|
||||
RECORD_STATUS_TAG_MAP,
|
||||
getPhotoUrl,
|
||||
getRecord,
|
||||
listRecords,
|
||||
type ServiceRecord,
|
||||
@ -177,6 +192,8 @@ const list = ref<ServiceRecord[]>([])
|
||||
const detailVisible = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
const detail = ref<ServiceRecordDetail | null>(null)
|
||||
/** photoId → presigned url;null 表示获取失败,缺失表示加载中。 */
|
||||
const photoUrls = ref<Record<string, string | null>>({})
|
||||
|
||||
const str = (v: unknown): string | undefined => (typeof v === 'string' && v !== '' ? v : undefined)
|
||||
|
||||
@ -246,9 +263,11 @@ async function loadMaps(): Promise<void> {
|
||||
async function openDetail(row: Record<string, any>): Promise<void> {
|
||||
detailVisible.value = true
|
||||
detail.value = null
|
||||
photoUrls.value = {}
|
||||
detailLoading.value = true
|
||||
try {
|
||||
detail.value = await getRecord(String(row.id))
|
||||
if (detail.value) void loadPhotoUrls(detail.value.photos)
|
||||
} catch (e) {
|
||||
if (e instanceof ApiError) ElMessage.error(e.message)
|
||||
} finally {
|
||||
@ -256,6 +275,30 @@ async function openDetail(row: Record<string, any>): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
/** 为每张照片并发取 presigned url;失败置 null → 模板显示「获取失败」。 */
|
||||
async function loadPhotoUrls(photos: ServiceRecordDetail['photos']): Promise<void> {
|
||||
const next: Record<string, string | null> = {}
|
||||
await Promise.all(
|
||||
photos.map(async (p) => {
|
||||
try {
|
||||
const { url } = await getPhotoUrl(p.id)
|
||||
next[p.id] = url
|
||||
} catch {
|
||||
next[p.id] = null
|
||||
}
|
||||
}),
|
||||
)
|
||||
photoUrls.value = next
|
||||
}
|
||||
|
||||
function photoUrlOf(id: string): string {
|
||||
return photoUrls.value[id] ?? ''
|
||||
}
|
||||
|
||||
function photoFailed(id: string): boolean {
|
||||
return photoUrls.value[id] === null
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void loadMaps()
|
||||
fetchList()
|
||||
@ -278,4 +321,8 @@ onMounted(() => {
|
||||
.record-page__detail {
|
||||
@apply max-h-[60vh] overflow-auto;
|
||||
}
|
||||
|
||||
.record-page__photo {
|
||||
@apply block h-16 w-16 cursor-zoom-in rounded object-cover;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user