修复bug,第一次导出缩略图,后面有了高清图后再次导出应该覆盖

按原图、中图和缩略图对本地图片资源分级,始终优先选择高清变体。

增量导出仅复用满足清晰度要求的图片,重新探测旧缩略图并在高清图出现后替换;仅缩略图降级时显示提示。
This commit is contained in:
Nanin
2026-08-08 20:53:40 +08:00
parent 666d8896ee
commit 291c82f0e2
9 changed files with 185 additions and 32 deletions
+10 -3
View File
@@ -23,6 +23,7 @@ import { getImageExportAttempts } from '../shared/export-media'
import { FileAssetService } from './file-asset-service'
import { mergeCachedSelfInfo } from './services/bootstrap-cache'
import type { VoiceRecognitionUseCase } from './voice-pipeline/voice-recognition-use-case'
import { imageFileQuality } from '../shared/image-quality'
const jobs = new Set<string>()
const activeArchives = new Map<string, Archiver>()
@@ -250,6 +251,7 @@ const mergeArchiveMessage = (previous: Message, current: Message): Message => {
'exportMediaUrl',
'exportMediaType',
'exportMediaName',
'exportMediaQuality',
'exportAvatarUrl'
]
for (const key of preserveWhenMissing) {
@@ -706,6 +708,7 @@ export async function runExport(
message.exportMediaUrl = undefined
message.exportMediaType = undefined
message.exportMediaName = undefined
message.exportMediaQuality = undefined
message.exportMediaError = undefined
message.voiceDataUrl = undefined
message.voiceTranscript = undefined
@@ -1063,15 +1066,20 @@ export async function runExport(
: message.contentData.type === 'share' && message.contentData.typeVal === '6'
? 'file'
: null
const reusableImageQuality =
previous?.exportMediaQuality === 'original' ||
(request.preferOriginal === false && previous?.exportMediaQuality === 'thumbnail')
if (
reusableMediaType &&
previous?.exportMediaUrl &&
(!previous.exportMediaType || previous.exportMediaType === reusableMediaType) &&
(reusableMediaType !== 'image' || reusableImageQuality) &&
(await resourceExists(previous.exportMediaUrl))
) {
message.exportMediaUrl = previous.exportMediaUrl
message.exportMediaType = reusableMediaType
message.exportMediaName = previous.exportMediaName
message.exportMediaQuality = previous.exportMediaQuality
send({
jobId: request.jobId,
phase: 'media',
@@ -1087,7 +1095,6 @@ export async function runExport(
} else {
let fileFound = false
let decryptedImage: { data: string; filePath: string } | null = null
let usedFallback = false
for (const attempt of getImageExportAttempts(request)) {
const file = await imageService.findImageFileAsync(
message.contentData.md5,
@@ -1116,7 +1123,6 @@ export async function runExport(
}
if (!decrypted) continue
decryptedImage = decrypted
usedFallback = attempt.fallback || imageService.isThumbnailFile(decrypted.filePath)
break
}
const decoded = decryptedImage ? decodeDataUrl(decryptedImage.data) : null
@@ -1129,7 +1135,8 @@ export async function runExport(
}
message.exportMediaUrl = mediaUrl
message.exportMediaType = 'image'
if (usedFallback) {
message.exportMediaQuality = imageFileQuality(decryptedImage!.filePath)
if (request.preferOriginal !== false && message.exportMediaQuality === 'thumbnail') {
keepMediaError(request, message, '原图不可用,已降级使用缩略图')
}
} else if (!fileFound) {