diff --git a/app/components/MediaSessionCard.vue b/app/components/MediaSessionCard.vue index 62054e4..63cdf2d 100644 --- a/app/components/MediaSessionCard.vue +++ b/app/components/MediaSessionCard.vue @@ -180,6 +180,11 @@ const presetLabel = computed(() => {

+ + { void Promise.all([ loadActiveTranscodes(), - loadUploadPolicy().catch(() => {}) + loadUploadPolicy().catch(() => {}), + fetchTags() ]) }) @@ -89,6 +93,27 @@ async function removeItem(item: FileItem) { toast.add({ title: t('files.deleteFailed'), color: 'error' }) } } + +async function confirmBatchTags(tagIds: number[]) { + const keys = sessionItems.value.map(item => item.key) + if (!keys.length || !tagIds.length) return + + try { + await batchUpdateTags(keys, tagIds, 'add') + batchTagOpen.value = false + recordRecent(tagIds) + await fetchTags(true) + const addedTags = tagItems.value.filter(tag => tagIds.includes(tag.id)) + sessionItems.value = sessionItems.value.map((item) => { + const merged = new Map((item.tags ?? []).map(tag => [tag.id, tag])) + for (const tag of addedTags) merged.set(tag.id, tag) + return { ...item, tags: [...merged.values()] } + }) + toast.add({ title: t('tags.batchSuccess'), color: 'success' }) + } catch { + toast.add({ title: t('tags.batchFailed'), color: 'error' }) + } +} diff --git a/server/api/images/batch-tags.post.ts b/server/api/images/batch-tags.post.ts index b99748c..bd412a8 100644 --- a/server/api/images/batch-tags.post.ts +++ b/server/api/images/batch-tags.post.ts @@ -46,7 +46,7 @@ export default defineEventHandler(async (event) => { const action = body?.action === 'remove' ? 'remove' : 'add' if (!keys.length) { - createApiError(event, 'INVALID_REQUEST', '请提供图片列表', 400) + createApiError(event, 'INVALID_REQUEST', '请提供媒体列表', 400) } if (!tagIds.length) { createApiError(event, 'INVALID_REQUEST', '请提供标签列表', 400) @@ -55,7 +55,7 @@ export default defineEventHandler(async (event) => { createApiError( event, 'INVALID_REQUEST', - `每次最多处理 ${MAX_DELETE_BATCH} 张图片`, + `每次最多处理 ${MAX_DELETE_BATCH} 个媒体`, 400 ) } @@ -64,7 +64,7 @@ export default defineEventHandler(async (event) => { validateKeys(keys) } catch (error) { if (error instanceof Error && error.message.startsWith('INVALID_KEY:')) { - createApiError(event, 'INVALID_IMAGE_KEY', `无效的图片路径: ${error.message.slice(12)}`, 400) + createApiError(event, 'INVALID_IMAGE_KEY', `无效的媒体路径: ${error.message.slice(12)}`, 400) } throw error } @@ -87,10 +87,10 @@ export default defineEventHandler(async (event) => { logActivity(event, { action: 'tags', - key: 'images/batch-tags', + key: 'media/batch-tags', originalName: action === 'add' - ? `批量打标(${keys.length} 张)` - : `批量移除标签(${keys.length} 张)`, + ? `批量打标(${keys.length} 个媒体)` + : `批量移除标签(${keys.length} 个媒体)`, userId: user.id })