"use client" import { useState, useEffect, useRef } from "react" import { Users, Database, RefreshCw, Activity, Brain, Tags, Package, ArrowUpRight, Zap, Send, Loader2, Search, Phone, User, TrendingUp, Settings, ChevronRight, Sparkles, Target, } from "lucide-react" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { Input } from "@/components/ui/input" import Link from "next/link" interface ChatMessage { role: "user" | "assistant" | "thinking" content: string timestamp: string data?: any thinking?: string // AI思考过程 portrait?: UserPortrait // 用户画像 } // 标准用户画像模板 interface UserPortrait { phone?: string qq?: string name?: string gender?: string province?: string city?: string level?: string rfmScore?: number tags?: string[] behavior?: { lastActive?: string frequency?: string } dataCompleteness?: number } interface AIStatus { status: string database?: { connected: boolean totalUsers: number latency: number } } export default function HomePage() { // AI对话状态 const [query, setQuery] = useState("") const [loading, setLoading] = useState(false) const [aiStatus, setAiStatus] = useState(null) const [messages, setMessages] = useState([ { role: "assistant", content: "你好!我是神射手AI助手。\n\n你可以:\n• 输入手机号查询用户画像\n• 输入QQ号查询关联信息\n• 问我任何关于用户数据的问题", timestamp: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }), } ]) const messagesEndRef = useRef(null) // 统计数据 const [stats, setStats] = useState({ totalUsers: 0, totalDataSources: 0, latency: 0, }) // 获取AI状态 useEffect(() => { fetch("/api/ai-chat") .then(res => res.json()) .then(data => { setAiStatus(data) if (data.database) { setStats({ totalUsers: data.database.totalUsers || 0, totalDataSources: 26, latency: data.database.latency || 0, }) } }) .catch(console.error) }, []) // 自动滚动到底部 useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }) }, [messages]) // 解析用户画像数据 const parsePortrait = (data: any): UserPortrait | undefined => { if (!data) return undefined return { phone: data.phone || data.手机号, qq: data.qq || data.QQ, name: data.name || data.姓名, gender: data.gender || data.性别, province: data.province || data.省份, city: data.city || data.城市, level: data.level || data.user_level || data.等级, rfmScore: data.rfm_score || data.rfmScore || data.RFM评分, tags: data.tags || [], behavior: { lastActive: data.last_active || data.最近活跃, frequency: data.frequency || data.活跃频率, }, dataCompleteness: data.data_completeness || data.数据完整度, } } // 生成思考过程 const generateThinking = (query: string): string => { const isPhone = /^1[3-9]\d{9}$/.test(query.replace(/\s/g, '')) const isQQ = /^\d{5,11}$/.test(query.replace(/\s|qq/gi, '')) if (isPhone) { return `🔍 识别到手机号查询\n→ 拆解意图: 查询用户画像\n→ 数据源: KR.用户估值, KR_腾讯\n→ 执行: 手机号精确匹配\n→ 输出: 标准用户画像模板` } else if (isQQ) { return `🔍 识别到QQ号查询\n→ 拆解意图: QQ关联查询\n→ 数据源: KR_腾讯.qq_phone\n→ 执行: QQ号精确匹配\n→ 输出: 关联手机号 + 用户画像` } else { return `🔍 自然语言理解中...\n→ 拆解意图: ${query.slice(0, 20)}...\n→ 思考策略: 语义分析\n→ 执行: Skill查询` } } // 发送消息 const handleSend = async () => { if (!query.trim() || loading) return const userMessage: ChatMessage = { role: "user", content: query, timestamp: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }), } // 添加思考过程消息 const thinkingMessage: ChatMessage = { role: "thinking", content: generateThinking(query), timestamp: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }), } setMessages(prev => [...prev, userMessage, thinkingMessage]) setQuery("") setLoading(true) try { const response = await fetch("/api/ai-chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message: query }) }) const data = await response.json() // 解析用户画像 const portrait = parsePortrait(data.response?.data) setMessages(prev => { // 移除思考消息,添加结果 const filtered = prev.filter(m => m.role !== "thinking") return [...filtered, { role: "assistant", content: data.success ? data.response.content : `查询失败: ${data.error || "未知错误"}`, timestamp: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }), data: data.response?.data, portrait, thinking: generateThinking(query), }] }) } catch (error: any) { setMessages(prev => { const filtered = prev.filter(m => m.role !== "thinking") return [...filtered, { role: "assistant", content: `网络错误: ${error.message}`, timestamp: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }) }] }) } finally { setLoading(false) } } // 快捷查询 const quickQuery = (q: string) => { setQuery(q) setTimeout(() => handleSend(), 100) } const formatNumber = (num: number): string => { if (num >= 1000000000) return `${(num / 1000000000).toFixed(2)}B` if (num >= 1000000) return `${(num / 1000000).toFixed(1)}M` if (num >= 1000) return `${(num / 1000).toFixed(0)}K` return num.toLocaleString() } // 核心功能模块 const modules = [ { title: "数据接入", icon: Database, color: "from-blue-500 to-cyan-500", href: "/data-ingestion/sources", desc: "数据源 · 清洗 · 调度", }, { title: "标签画像", icon: Tags, color: "from-green-500 to-emerald-500", href: "/tag-portrait", desc: "标签 · 画像 · 流量池", }, { title: "数据市场", icon: Package, color: "from-orange-500 to-red-500", href: "/data-market", desc: "API · 订阅 · 变现", }, ] return (
{/* 顶部状态栏 */}

神射手

用户资产数字化中台

{stats.latency}ms
{/* 统计卡片 */}
{formatNumber(stats.totalUsers)}
用户
{stats.totalDataSources}
数据源
{stats.latency}ms
延迟
{/* AI对话区域 - 核心功能 */}
AI 智能对话
{formatNumber(stats.totalUsers)} 可查询
{/* 消息列表 */} {messages.map((msg, i) => (
{/* 思考过程 */} {msg.role === 'thinking' && (
AI思考中...
{msg.content}
)} {/* 用户消息 */} {msg.role === 'user' && (
{msg.content}
{msg.timestamp}
)} {/* AI回复 */} {msg.role === 'assistant' && (
{/* 思考过程折叠显示 */} {msg.thinking && (
💭 思考过程
{msg.thinking}
)} {/* 用户画像卡片 */} {msg.portrait && (msg.portrait.phone || msg.portrait.qq) && (
{(msg.portrait.name || '?')[0]}
{msg.portrait.name || '未知用户'}
{msg.portrait.phone && 📱 {msg.portrait.phone}} {msg.portrait.qq && QQ: {msg.portrait.qq}}
{msg.portrait.level && ( {msg.portrait.level}级 )}
{msg.portrait.rfmScore !== undefined && (
RFM
{msg.portrait.rfmScore}
)} {msg.portrait.province && (
地区
{msg.portrait.province} {msg.portrait.city}
)} {msg.portrait.dataCompleteness !== undefined && (
完整度
{msg.portrait.dataCompleteness}%
)}
{msg.portrait.tags && msg.portrait.tags.length > 0 && (
{msg.portrait.tags.slice(0, 5).map((tag, ti) => ( {tag} ))}
)}
)} {/* 文本回复 */}
{msg.content}
{msg.timestamp}
)}
))} {loading && (
查询中...
)}
{/* 快捷查询 */}
{/* 输入框 */}
setQuery(e.target.value)} onKeyPress={(e) => e.key === "Enter" && handleSend()} placeholder="输入手机号、QQ号或问题..." className="flex-1 h-10 bg-gray-50 border-0" />
{/* 功能模块入口 */}
{modules.map((module, i) => (

{module.title}

{module.desc}

))}
) }