52 lines
1.9 KiB
JavaScript
52 lines
1.9 KiB
JavaScript
import { Router } from 'express'
|
|
import { prisma } from '../db.js'
|
|
import { authRequired } from '../middleware.js'
|
|
|
|
const router = Router()
|
|
router.use(authRequired)
|
|
|
|
// 新闻列表: 按时间最新优先, cursor 分页
|
|
// cursor 格式: "<publishedAt ISO>|<lastId>", 兼容旧版纯时间戳 (不带 |)
|
|
// 同秒多条时用 id 兜底, 避免翻页时整批漏掉
|
|
router.get('/news', async (req, res, next) => {
|
|
try {
|
|
const rawLimit = Number(req.query.limit)
|
|
const limit = Number.isFinite(rawLimit) && rawLimit >= 1 ? Math.min(Math.floor(rawLimit), 50) : 10
|
|
let where = {}
|
|
const cursor = req.query.cursor || ''
|
|
if (cursor) {
|
|
const [ts, idRaw] = cursor.split('|')
|
|
const c = new Date(ts)
|
|
if (!isNaN(c.getTime())) {
|
|
const id = Number(idRaw)
|
|
where = id > 0
|
|
? { OR: [{ publishedAt: { lt: c } }, { publishedAt: c, id: { lt: id } }] }
|
|
: { publishedAt: { lt: c } }
|
|
}
|
|
}
|
|
const items = await prisma.news.findMany({
|
|
select: { id: true, title: true, summary: true, source: true, url: true, publishedAt: true, impactRank: true },
|
|
where,
|
|
orderBy: [{ publishedAt: 'desc' }, { id: 'desc' }],
|
|
take: limit,
|
|
})
|
|
const nextCursor = items.length === limit && items.length > 0
|
|
? items[items.length - 1].publishedAt.toISOString() + '|' + items[items.length - 1].id
|
|
: null
|
|
res.json({ items, nextCursor })
|
|
} catch (e) { next(e) }
|
|
})
|
|
|
|
// 新闻详情: 含正文 content
|
|
router.get('/news/:id', async (req, res, next) => {
|
|
try {
|
|
const id = Number(req.params.id)
|
|
if (!Number.isInteger(id) || id <= 0) return res.status(400).json({ error: '无效的新闻 id' })
|
|
const item = await prisma.news.findUnique({ where: { id } })
|
|
if (!item) return res.status(404).json({ error: '新闻不存在' })
|
|
res.json({ item })
|
|
} catch (e) { next(e) }
|
|
})
|
|
|
|
export default router
|