feat: 每日热点问题共享库(定时生成+管理员手动更新+点击埋点)
数据库: - daily_topics表:每天每场景一条热点问题记录 - sample_clicks表:记录用户点击示例问题行为 后端: - DailyTopicStore: CRUD + 埋点 + 点击统计 - generate_daily_topics: AI生成4场景各25-30个问题 - 定时任务:每天凌晨3点自动生成(后台线程轮询) - GET /topics/daily: 获取当天热点(公开) - POST /topics/click: 点击埋点 - GET /admin/daily-topics: 管理端查看 - POST /admin/daily-topics: 管理员手动更新 - POST /admin/daily-topics/generate: 手动触发AI生成 - GET /admin/sample-clicks: 点击统计 前端: - ChatPanel挂载时取当天热点,无则用硬编码兜底 - 点击示例问题时记录埋点 - AdminDailyTopics管理页面:查看/编辑/手动生成 - 路由 /admin/daily-topics + 导航配置 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -240,6 +240,32 @@ export const api = {
|
||||
method: 'POST', body: JSON.stringify({ scene, topic, existing }),
|
||||
}),
|
||||
|
||||
// ===== 每日热点问题 =====
|
||||
getDailyTopics: (scene: Scene) =>
|
||||
request<{ scene: string; questions: string[] }>(`/topics/daily?scene=${scene}`),
|
||||
recordSampleClick: (scene: Scene, question: string) =>
|
||||
request<{ recorded: boolean }>('/topics/click', {
|
||||
method: 'POST', body: JSON.stringify({ scene, question }),
|
||||
}),
|
||||
|
||||
// ===== 管理端:热点问题 =====
|
||||
adminGetDailyTopics: (date?: string) =>
|
||||
request<{ results: Array<{ id: number; date: string; scene: string; questions: string[]; source: string; created_at: string }> }>(
|
||||
`/admin/daily-topics${date ? `?date=${date}` : ''}`,
|
||||
),
|
||||
adminUpdateDailyTopics: (data: { scene: string; questions: string[]; date?: string }) =>
|
||||
request<{ updated: boolean; topic: { id: number; date: string; scene: string; questions: string[]; source: string } }>(
|
||||
'/admin/daily-topics', { method: 'POST', body: JSON.stringify(data) },
|
||||
),
|
||||
adminGenerateDailyTopics: () =>
|
||||
request<{ generated: boolean; results: Record<string, { count: number; source: string; error?: string }> }>(
|
||||
'/admin/daily-topics/generate', { method: 'POST' },
|
||||
),
|
||||
adminSampleClickStats: (days = 14) =>
|
||||
request<{ results: Array<{ scene: string; question: string; clicks: number }> }>(
|
||||
`/admin/sample-clicks?days=${days}`,
|
||||
),
|
||||
|
||||
// ===== 知识库 =====
|
||||
addKnowledge: (data: { title: string; content: string; source?: string; doc_type?: string; region?: string | null; effective_date?: string | null; keywords?: string | null }) =>
|
||||
request<KnowledgeDoc>('/knowledge', { method: 'POST', body: JSON.stringify(data) }),
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { ComponentType } from 'react'
|
||||
import {
|
||||
LayoutDashboard, ClipboardList, Scale, TrendingUp, Heart, Users,
|
||||
BookOpen, History, User, Settings, ShieldCheck, FileText,
|
||||
BarChart3, Cpu, MessageSquare, UserCog, Briefcase,
|
||||
BarChart3, Cpu, MessageSquare, UserCog, Briefcase, Sparkles,
|
||||
} from 'lucide-react'
|
||||
|
||||
export interface NavItem {
|
||||
@@ -69,6 +69,7 @@ export const ADMIN_NAV: NavItem[] = [
|
||||
{ path: '/admin/expert-activity', label: '专家沟通', icon: MessageSquare, group: '管理后台' },
|
||||
{ path: '/admin/users', label: '用户管理', icon: Users, group: '管理后台' },
|
||||
{ path: '/admin/experts', label: '专家管理', icon: UserCog, group: '管理后台' },
|
||||
{ path: '/admin/daily-topics', label: '热点问题', icon: Sparkles, group: '管理后台' },
|
||||
]
|
||||
|
||||
/** 按角色获取导航 */
|
||||
|
||||
Reference in New Issue
Block a user