feat(forum): like toggle, like status, author soft-delete

This commit is contained in:
zty 2026-07-07 03:26:32 -04:00
parent b2dd9d3bd6
commit 94c9b0c060
1 changed files with 72 additions and 0 deletions

View File

@ -148,4 +148,76 @@ forumRouter.post(
}
)
// 点赞状态(登录,用于详情页初始化)
forumRouter.get('/threads/:id/like', authn(CERT_TYPE.ACCOUNT), async ctx => {
const id = Number(ctx.params.id)
const cert = ctx.state.acct_cert as UserCert
const existing = await db.forumThreadLike.findUnique({
where: { thread_id_user_id: { thread_id: id, user_id: cert.id } }
})
const thread = await db.forumThread.findFirst({ where: { id }, select: { like_count: true } })
ctx.body = { liked: !!existing, like_count: thread?.like_count ?? 0 }
})
// 点赞 / 取消登录toggle
forumRouter.post('/threads/:id/like', authn(CERT_TYPE.ACCOUNT), async ctx => {
const id = Number(ctx.params.id)
const cert = ctx.state.acct_cert as UserCert
const thread = await db.forumThread.findFirst({ where: { id, deleted: 0 } })
if (!thread) {
ctx.throw(422, fail(ERR_CODE.UNKNOWN_ERR, '帖子不存在'))
return
}
const existing = await db.forumThreadLike.findUnique({
where: { thread_id_user_id: { thread_id: id, user_id: cert.id } }
})
const liked = !existing
const updated = await db.$transaction(async tx => {
if (existing) {
await tx.forumThreadLike.delete({
where: { thread_id_user_id: { thread_id: id, user_id: cert.id } }
})
return tx.forumThread.update({ where: { id }, data: { like_count: { decrement: 1 } } })
} else {
await tx.forumThreadLike.create({ data: { thread_id: id, user_id: cert.id } })
return tx.forumThread.update({ where: { id }, data: { like_count: { increment: 1 } } })
}
})
ctx.body = { liked, like_count: updated.like_count }
})
// 删除自己的帖(登录,软删)
forumRouter.delete('/threads/:id', authn(CERT_TYPE.ACCOUNT), async ctx => {
const id = Number(ctx.params.id)
const cert = ctx.state.acct_cert as UserCert
const thread = await db.forumThread.findFirst({ where: { id, deleted: 0 } })
if (!thread) {
ctx.throw(422, fail(ERR_CODE.UNKNOWN_ERR, '帖子不存在'))
return
}
if (thread.author_id !== cert.id) {
ctx.throw(422, fail(ERR_CODE.FORBIDDEN, '只能删除自己的帖子'))
return
}
await db.forumThread.update({ where: { id }, data: { deleted: 1 } })
ctx.body = { ok: true }
})
// 删除自己的回帖(登录,软删;不回退 floor
forumRouter.delete('/replies/:id', authn(CERT_TYPE.ACCOUNT), async ctx => {
const id = Number(ctx.params.id)
const cert = ctx.state.acct_cert as UserCert
const reply = await db.forumReply.findFirst({ where: { id, deleted: 0 } })
if (!reply) {
ctx.throw(422, fail(ERR_CODE.UNKNOWN_ERR, '回帖不存在'))
return
}
if (reply.author_id !== cert.id) {
ctx.throw(422, fail(ERR_CODE.FORBIDDEN, '只能删除自己的回帖'))
return
}
await db.forumReply.update({ where: { id }, data: { deleted: 1 } })
ctx.body = { ok: true }
})
export const forumRoutes = forumRouter.routes()