feat(forum): create thread and reply with floor increment
This commit is contained in:
parent
9048a5a389
commit
b2dd9d3bd6
|
|
@ -3,6 +3,8 @@ import validate from '../middlewares/validator'
|
||||||
import { db } from '..'
|
import { db } from '..'
|
||||||
import { fail } from '../common/utils'
|
import { fail } from '../common/utils'
|
||||||
import { ERR_CODE, FORUM_BOARDS } from '../common/constants'
|
import { ERR_CODE, FORUM_BOARDS } from '../common/constants'
|
||||||
|
import authn from '../middlewares/authn'
|
||||||
|
import { CERT_TYPE, UserCert } from '../common/types'
|
||||||
|
|
||||||
const forumRouter = new Router()
|
const forumRouter = new Router()
|
||||||
forumRouter.prefix('/api/forum')
|
forumRouter.prefix('/api/forum')
|
||||||
|
|
@ -74,4 +76,76 @@ forumRouter.get('/threads/:id', async ctx => {
|
||||||
ctx.body = { thread, replies }
|
ctx.body = { thread, replies }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 发帖(登录)
|
||||||
|
forumRouter.post(
|
||||||
|
'/threads',
|
||||||
|
authn(CERT_TYPE.ACCOUNT),
|
||||||
|
validate({
|
||||||
|
body: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
board: { type: 'string' },
|
||||||
|
title: { type: 'string', minLength: 1, maxLength: 60 },
|
||||||
|
content: { type: 'string', minLength: 1, maxLength: 5000 }
|
||||||
|
},
|
||||||
|
required: ['board', 'title', 'content'],
|
||||||
|
additionalProperties: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
async ctx => {
|
||||||
|
const { board, title, content } = ctx.request.body as { board: string, title: string, content: string }
|
||||||
|
if (!FORUM_BOARDS.includes(board)) {
|
||||||
|
ctx.throw(422, fail(ERR_CODE.INVALID_REQ_DATA, '非法板块'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const cert = ctx.state.acct_cert as UserCert
|
||||||
|
const thread = await db.forumThread.create({
|
||||||
|
data: { board, title, content, author_id: cert.id, author_name: cert.username }
|
||||||
|
})
|
||||||
|
ctx.body = thread
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 回帖(登录)
|
||||||
|
forumRouter.post(
|
||||||
|
'/threads/:id/replies',
|
||||||
|
authn(CERT_TYPE.ACCOUNT),
|
||||||
|
validate({
|
||||||
|
body: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
content: { type: 'string', minLength: 1, maxLength: 5000 }
|
||||||
|
},
|
||||||
|
required: ['content'],
|
||||||
|
additionalProperties: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
async ctx => {
|
||||||
|
const id = Number(ctx.params.id)
|
||||||
|
const cert = ctx.state.acct_cert as UserCert
|
||||||
|
const { content } = ctx.request.body as { content: string }
|
||||||
|
const thread = await db.forumThread.findFirst({ where: { id, deleted: 0 } })
|
||||||
|
if (!thread) {
|
||||||
|
ctx.throw(422, fail(ERR_CODE.UNKNOWN_ERR, '帖子不存在'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const reply = await db.$transaction(async tx => {
|
||||||
|
const updated = await tx.forumThread.update({
|
||||||
|
where: { id },
|
||||||
|
data: { reply_count: { increment: 1 } }
|
||||||
|
})
|
||||||
|
return tx.forumReply.create({
|
||||||
|
data: {
|
||||||
|
thread_id: id,
|
||||||
|
floor: updated.reply_count,
|
||||||
|
content,
|
||||||
|
author_id: cert.id,
|
||||||
|
author_name: cert.username
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
ctx.body = reply
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
export const forumRoutes = forumRouter.routes()
|
export const forumRoutes = forumRouter.routes()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue