🎯 评分规则
核心评分指标
指标 | 权重 | 说明 |
---|---|---|
🔥 浏览量 (Views) | 1.0 | 直接体现文章热度 |
👍 点赞数 (Likes) | 3.0 | 点赞代表用户的正面反馈 |
💬 评论数 (Comments) | 2.0 | 评论数量代表互动程度 |
🕒 发布时间 (Recency) | 依据时间衰减 | 较新的文章得分更高 |
评分公式
Trending Score = (views * 1) + (likes * 3) + (comments_count * 2) + (time_factor)
🛠️ Prisma 模型调整
BlogPost 模型
model BlogPost {
id String @id @default(cuid())
views Int @default(0) // 🔥 新增字段
comments_count Int @default(0) // 🔥 新增字段
comments Comment[] // 🔥 新增关系
@@map("blog_posts")
}
Comment 模型 (已完成)
无需修改,支持嵌套评论。
⚙️ Prisma 查询实现
获取热门文章 (Trending News)
import { prisma } from '@/lib/prisma'
export async function getTrendingNews() {
const trendingNews = await prisma.blogPost.findMany({
where: {
status: 'published',
published_at: {
gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) // 最近 7 天
}
},
include: {
blog_post_likes: true,
comments: true
},
orderBy: [
{ views: 'desc' },
{ blog_post_likes: { _count: 'desc' } },
{ comments_count: 'desc' },
{ published_at: 'desc' }
],
take: 10 // 获取前 10 篇热门文章
})
return trendingNews
}
浏览量自增
export async function incrementViewCount(blogPostId: string) {
await prisma.blogPost.update({
where: { id: blogPostId },
data: { views: { increment: 1 } }
})
}
点赞数更新
export async function likePost(postId: string) {
await prisma.blogPost.update({
where: { id: postId },
data: { blog_post_likes: { create: {} } }
})
}
评论数更新
export async function addCommentToPost(postId: string, userId: string, content: string) {
await prisma.comment.create({
data: {
blog_post_id: postId,
user_id: userId,
content
}
})
await prisma.blogPost.update({
where: { id: postId },
data: { comments_count: { increment: 1 } }
})
}
🚀 最终效果
✅ 热点文章根据浏览量、点赞数、评论数、发布时间等指标排序
✅ 点击文章时自动记录浏览量
✅ 支持评论嵌套结构,对评论的活跃度纳入评分
✅ 结合 Prisma 强大的 orderBy
、where
以及分页功能,实现灵活的 Trending News 系统
TODO后续优化
1、🔥 热门文章标识
- 在文章模型中新增 is_trending 字段,后台任务(如 cron job)定期更新热门文章。
2、⏳ 热度随时间衰减
- 在评分公式中引入时间衰减因子,让新文章更易获得推荐机会。
示例:
Trending Score = (views * 1) + (likes * 3) + (comments_count * 2) / (时间间隔 + 1)
3、📊 分类推荐
- 根据用户历史浏览文章的 category_id 进行个性化推荐。
4、📬 通知系统
- 若用户评论的文章成为热门文章,可以触发通知提醒,提高用户参与度。