feat(forum): like toggle, like status, author soft-delete
This commit is contained in:
parent
b2dd9d3bd6
commit
94c9b0c060
|
|
@ -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()
|
export const forumRoutes = forumRouter.routes()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue