forked from BRETT/BRETT
86 lines
3.0 KiB
TypeScript
86 lines
3.0 KiB
TypeScript
import { asc, count, desc, eq, inArray } from 'drizzle-orm'
|
|
import { commentAttachments, comments, uploads, users } from '../../../db/schema'
|
|
import type { CommentAttachment } from '~~/shared/utils/attachments'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const idParam = getRouterParam(event, 'id') ?? ''
|
|
if (!/^\d+$/.test(idParam)) {
|
|
throw createError({ statusCode: 400, statusMessage: 'Ungültige Nutzer-ID' })
|
|
}
|
|
const userId = Number(idParam)
|
|
|
|
const q = getQuery(event)
|
|
const page = Math.max(1, Math.floor(Number(q.page)) || 1)
|
|
const perPage = Math.min(100, Math.max(1, Math.floor(Number(q.perPage)) || 20))
|
|
|
|
const db = useDb()
|
|
const [user] = await db
|
|
.select({ id: users.id })
|
|
.from(users)
|
|
.where(eq(users.id, userId))
|
|
.limit(1)
|
|
|
|
if (!user) {
|
|
throw createError({ statusCode: 404, statusMessage: 'Nutzer nicht gefunden' })
|
|
}
|
|
|
|
const [totalRow, rows] = await Promise.all([
|
|
db.select({ count: count() }).from(comments).where(eq(comments.userId, userId)),
|
|
db
|
|
.select({
|
|
id: comments.id,
|
|
content: comments.content,
|
|
createdAt: comments.createdAt,
|
|
uploadId: uploads.id,
|
|
uploadType: uploads.type,
|
|
uploadFileName: uploads.fileName,
|
|
uploadExternalUrl: uploads.externalUrl,
|
|
uploadPreviewImage: uploads.previewImage,
|
|
})
|
|
.from(comments)
|
|
.innerJoin(uploads, eq(comments.uploadId, uploads.id))
|
|
.where(eq(comments.userId, userId))
|
|
.orderBy(desc(comments.createdAt))
|
|
.limit(perPage)
|
|
.offset((page - 1) * perPage),
|
|
])
|
|
|
|
const total = totalRow[0]?.count ?? 0
|
|
|
|
const commentIds = rows.map(r => r.id)
|
|
const attachmentRows = commentIds.length
|
|
? await db
|
|
.select()
|
|
.from(commentAttachments)
|
|
.where(inArray(commentAttachments.commentId, commentIds))
|
|
.orderBy(asc(commentAttachments.id))
|
|
: []
|
|
const attachmentsByComment = new Map<number, CommentAttachment[]>()
|
|
for (const a of attachmentRows) {
|
|
let list = attachmentsByComment.get(a.commentId)
|
|
if (!list) {
|
|
list = []
|
|
attachmentsByComment.set(a.commentId, list)
|
|
}
|
|
list.push({ id: a.id, name: a.originalName, url: `/uploads/attachments/${a.fileName}`, mimeType: a.mimeType, size: a.size, cover: a.cover, meta: a.meta as CommentAttachment['meta'] })
|
|
}
|
|
|
|
const items = rows.map((row) => {
|
|
const url = row.uploadExternalUrl ?? `/uploads/${row.uploadFileName}`
|
|
const embedId = row.uploadType === 'youtube' && row.uploadExternalUrl ? getYoutubeId(row.uploadExternalUrl) : null
|
|
const uploadThumbUrl = row.uploadType === 'youtube' && embedId
|
|
? youtubeThumbUrl(embedId)
|
|
: row.uploadType === 'image' ? url : row.uploadType === 'link' || row.uploadType === 'twitch' || row.uploadType === 'audio' ? row.uploadPreviewImage : null
|
|
return {
|
|
id: row.id,
|
|
content: row.content,
|
|
createdAt: row.createdAt,
|
|
uploadId: row.uploadId,
|
|
uploadThumbUrl,
|
|
attachments: attachmentsByComment.get(row.id) ?? [],
|
|
}
|
|
})
|
|
|
|
return { items, total, pageCount: Math.max(1, Math.ceil(total / perPage)) }
|
|
})
|