上传标签

This commit is contained in:
tianmo committed 2026-10-17 18:22:55 +08:00
1 parent 6494ad2918
commit 832261739f
8 files changed
+120 -20

No files matched your search

+16 -1
View File
@@ -11,6 +11,11 @@ import { createApiError } from '../../utils/api-error'
import { checkUploadRateLimit } from '../../utils/rate-limit'
import { processSingleFileUpload } from '../../utils/file-bed'
import { getFileBedAccessMode } from '../../utils/env'
import { readMultipartFormFieldValues } from '../../utils/multipart-form'
import {
parseTagNamesParam,
resolveUploadTagIds
} from '../../utils/tags'
export default defineEventHandler(async (event) => {
await requireUploadAuth(event)
@@ -28,6 +33,15 @@ export default defineEventHandler(async (event) => {
const source = verifyApiUploadToken(event) ? 'api' : 'web'
const uploadUserId = await getUploadUserId(event, formToken)
const tagNamesRaw = readMultipartFormFieldValues(formData, 'tagNames')
const uploadTagNames = parseTagNamesParam(
tagNamesRaw.length === 1 ? tagNamesRaw[0] : tagNamesRaw
)
const resolvedTags = resolveUploadTagIds(uploadUserId, uploadTagNames)
if ('message' in resolvedTags) {
createApiError(event, 'INVALID_REQUEST', resolvedTags.message, 400)
}
const uploadTagIds = resolvedTags.tagIds
const fileParts = formData.filter(
part => (part.name === 'file' || part.name === 'files') && part.data?.length
@@ -54,7 +68,8 @@ export default defineEventHandler(async (event) => {
filename: part.filename,
contentType: part.type,
source,
userId: uploadUserId
userId: uploadUserId,
tagIds: uploadTagIds
})
if ('error' in result) {
+16 -1
View File
@@ -17,6 +17,11 @@ import {
parseTranscodePreset
} from '../../utils/transcode'
import { getFileBedAccessMode } from '../../utils/env'
import { readMultipartFormFieldValues } from '../../utils/multipart-form'
import {
parseTagNamesParam,
resolveUploadTagIds
} from '../../utils/tags'
export default defineEventHandler(async (event) => {
await requireUploadAuth(event)
@@ -34,6 +39,15 @@ export default defineEventHandler(async (event) => {
const source = verifyApiUploadToken(event) ? 'api' : 'web'
const uploadUserId = await getUploadUserId(event, formToken)
const tagNamesRaw = readMultipartFormFieldValues(formData, 'tagNames')
const uploadTagNames = parseTagNamesParam(
tagNamesRaw.length === 1 ? tagNamesRaw[0] : tagNamesRaw
)
const resolvedTags = resolveUploadTagIds(uploadUserId, uploadTagNames)
if ('message' in resolvedTags) {
createApiError(event, 'INVALID_REQUEST', resolvedTags.message, 400)
}
const uploadTagIds = resolvedTags.tagIds
const transcodeField = formData.find(part => part.name === 'transcode')
const wantTranscode = transcodeField?.data?.length
@@ -98,7 +112,8 @@ export default defineEventHandler(async (event) => {
filename: part.filename,
contentType: part.type,
source,
userId: uploadUserId
userId: uploadUserId,
tagIds: uploadTagIds
})
if ('error' in result) {
+26 -11
View File
@@ -25,6 +25,10 @@ import {
isForbiddenFileExtension,
isVideoExtensionAllowed
} from './upload-policy'
import {
attachTagsAfterUpload,
getTagsForImageKeys
} from './tags'
export { isForbiddenFileExtension }
@@ -107,6 +111,7 @@ export async function processSingleFileUpload(
contentType?: string
source?: LogSource
userId?: number | null
tagIds?: number[]
}
): Promise<{ item: FileItem } | { error: UploadErrorItem }> {
const originalName = sanitizeDownloadName(input.filename ?? 'file')
@@ -157,7 +162,8 @@ export async function processSingleFileUpload(
contentType: normalizeFileContentType(input.contentType, extension),
source: input.source,
userId: input.userId,
mediaType: 'file'
mediaType: 'file',
tagIds: input.tagIds
})
}
@@ -173,6 +179,7 @@ async function persistMediaUpload(
source?: LogSource
userId?: number | null
mediaType: MediaType
tagIds?: number[]
}
): Promise<{ item: FileItem } | { error: UploadErrorItem }> {
let backendId: string
@@ -222,16 +229,22 @@ async function persistMediaUpload(
source: input.source ?? 'web'
})
if (input.tagIds?.length && input.userId != null) {
attachTagsAfterUpload(input.key, input.tagIds, input.userId)
}
const item = buildFileItem({
event,
key: input.key,
backendId,
originalName: input.originalName,
contentType: input.contentType,
size: input.bytes.byteLength,
uploadedAt: input.uploadedAt
})
const tags = getTagsForImageKeys([input.key]).get(input.key) ?? []
return {
item: buildFileItem({
event,
key: input.key,
backendId,
originalName: input.originalName,
contentType: input.contentType,
size: input.bytes.byteLength,
uploadedAt: input.uploadedAt
})
item: tags.length ? { ...item, tags } : item
}
}
@@ -243,6 +256,7 @@ export async function processSingleVideoUpload(
contentType?: string
source?: LogSource
userId?: number | null
tagIds?: number[]
}
): Promise<{ item: FileItem } | { error: UploadErrorItem }> {
const originalName = sanitizeDownloadName(input.filename ?? 'video')
@@ -293,7 +307,8 @@ export async function processSingleVideoUpload(
contentType: normalizeVideoContentType(input.contentType, extension),
source: input.source,
userId: input.userId,
mediaType: 'video'
mediaType: 'video',
tagIds: input.tagIds
})
// 生成封面缩略图;失败不影响上传结果