diff --git a/admin/src/views/Dashboard.vue b/admin/src/views/Dashboard.vue index b6dd4a6..654b010 100644 --- a/admin/src/views/Dashboard.vue +++ b/admin/src/views/Dashboard.vue @@ -5,7 +5,7 @@
{{ d.stats?.approvedKnowledge ?? '-' }}已审知识共 {{ d.stats?.totalKnowledge ?? 0 }} · 含题 {{ d.stats?.withQuiz ?? 0 }}
{{ d.stats?.totalLits ?? '-' }}点亮星球{{ d.stats?.litUsers ?? 0 }} 人参与
{{ d.stats?.aiChatUsed ?? '-' }}AI 问答次数{{ d.stats?.aiChatUsers ?? 0 }} 人用过
-
{{ d.stats?.totalTrends ?? '-' }}趋势资讯待审反馈 {{ d.stats?.pendingFeedbacks ?? 0 }}
+
{{ d.stats?.totalTrends ?? '-' }}趋势资讯含人话解读 {{ d.stats?.trendsWithExplain ?? 0 }}
{{ d.stats?.paidOrders ?? '-' }}付费订单共 {{ d.stats?.totalOrders ?? 0 }} 单
diff --git a/admin/src/views/Trends.vue b/admin/src/views/Trends.vue index 92b0615..72ccbb9 100644 --- a/admin/src/views/Trends.vue +++ b/admin/src/views/Trends.vue @@ -15,6 +15,12 @@ + + + @@ -35,6 +41,8 @@ + + @@ -66,7 +74,7 @@ async function load() { } finally { loading.value = false } } function openEdit(row) { - form.value = row ? { ...row } : { title: '', summary: '', source: '', sourceUrl: '', category: '产品', hot: false, picked: false } + form.value = row ? { ...row } : { title: '', summary: '', source: '', sourceUrl: '', category: '产品', hot: false, picked: false, plainExplain: '', takeAway: '' } dlg.value = true } async function save() { diff --git a/server/src/routes/admin.js b/server/src/routes/admin.js index f1ced70..b23f288 100755 --- a/server/src/routes/admin.js +++ b/server/src/routes/admin.js @@ -1097,9 +1097,9 @@ router.get('/trends', requirePermission('trend:read'), async (req, res) => { router.post('/trends', requirePermission('trend:write'), async (req, res) => { try { - const { title, summary, source, sourceUrl, category, tags, hot, picked, newsDate } = req.body + const { title, summary, source, sourceUrl, category, tags, hot, picked, newsDate, plainExplain, takeAway } = req.body if (!title) return ApiResponse.error(res, '标题不能为空', 400) - const item = new Trend({ title, summary, source, sourceUrl, category, tags, hot: !!hot, picked: !!picked, newsDate: newsDate || new Date() }) + const item = new Trend({ title, summary, source, sourceUrl, category, tags, hot: !!hot, picked: !!picked, newsDate: newsDate || new Date(), plainExplain: plainExplain || '', takeAway: takeAway || '' }) await item.save() await logAction(req, 'create', 'trend', item._id, { title }) return ApiResponse.success(res, item, '创建成功') @@ -1111,9 +1111,9 @@ router.post('/trends', requirePermission('trend:write'), async (req, res) => { router.put('/trends/:id', requirePermission('trend:write'), async (req, res) => { try { - const { title, summary, source, sourceUrl, category, tags, hot, picked, newsDate } = req.body + const { title, summary, source, sourceUrl, category, tags, hot, picked, newsDate, plainExplain, takeAway } = req.body const item = await Trend.findByIdAndUpdate(req.params.id, - { title, summary, source, sourceUrl, category, tags, hot: !!hot, picked: !!picked, ...(newsDate ? { newsDate } : {}) }, + { title, summary, source, sourceUrl, category, tags, hot: !!hot, picked: !!picked, plainExplain: plainExplain || '', takeAway: takeAway || '', ...(newsDate ? { newsDate } : {}) }, { new: true }) if (!item) return ApiResponse.notFound(res, '趋势不存在') await logAction(req, 'update', 'trend', item._id, { title }) @@ -1144,7 +1144,7 @@ router.get('/dashboard-v2', requirePermission('dashboard:read'), async (req, res try { const [ totalUsers, newUsers7d, totalKnowledge, approvedKnowledge, withQuiz, - totalTrends, totalFeedbacks, pendingFeedbacks, totalOrders, paidOrders, + totalTrends, trendsWithExplain, totalFeedbacks, pendingFeedbacks, totalOrders, paidOrders, totalLits, litUsers, recentLogins, litByDimAgg, aiStatsRaw ] = await Promise.all([ User.countDocuments({}), @@ -1153,6 +1153,7 @@ router.get('/dashboard-v2', requirePermission('dashboard:read'), async (req, res Knowledge.countDocuments({ status: 'approved' }), Knowledge.countDocuments({ 'options.0': { $exists: true } }), Trend.countDocuments({}), + Trend.countDocuments({ plainExplain: { $exists: true, $ne: '' } }), Feedback.countDocuments({}), Feedback.countDocuments({ status: 'pending' }), Order.countDocuments({}), @@ -1175,7 +1176,7 @@ router.get('/dashboard-v2', requirePermission('dashboard:read'), async (req, res stats: { totalUsers, newUsers7d, totalKnowledge, approvedKnowledge, withQuiz, - totalTrends, totalFeedbacks, pendingFeedbacks, + totalTrends, trendsWithExplain, totalFeedbacks, pendingFeedbacks, totalOrders, paidOrders, totalLits, litUsers: litUsers.length, aiChatUsed: ai.used, aiChatUsers: ai.users, diff --git a/server/src/routes/seo.js b/server/src/routes/seo.js index cd3bd4e..6463c0c 100644 --- a/server/src/routes/seo.js +++ b/server/src/routes/seo.js @@ -121,7 +121,7 @@ router.get('/llms.txt', (req, res) => { ## 核心内容 - 五维度知识体系:AI起源、发展脉络、当前格局、学习工具、趋势跟踪 -- 每日AI趋势:每天 8:00/20:00 自动采集 Hacker News / arXiv 热点并中文归类(产品/论文/工具/公司/政策) +- 每日AI趋势:每天 8:00/20:00 自动采集 Hacker News / arXiv 热点并中文归类(产品/论文/工具/公司/政策),每条附「人话解读」:一句大白话说清 + 对普通人意味着什么 - AI问答:基于知识库的智能问答 ## 免费与付费