"use client" import { useState, useEffect } from "react" import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { User, Phone, Calendar, Tag, History, RefreshCw, Link2, BookOpen, ShoppingBag, Users, MessageCircle, Clock, CheckCircle, XCircle, Save, X } from "lucide-react" interface UserDetailModalProps { open: boolean onClose: () => void userId: string | null onUserUpdated?: () => void } interface UserDetail { id: string phone?: string nickname: string avatar?: string wechat_id?: string open_id?: string referral_code: string referred_by?: string has_full_book: boolean is_admin: boolean earnings: number pending_earnings: number referral_count: number created_at: string updated_at?: string // 标签相关 tags?: string[] ckb_tags?: string[] source_tags?: string[] merged_tags?: string[] // 存客宝同步 ckb_user_id?: string ckb_synced_at?: string // 来源信息 source?: string created_by?: string matched_by?: string } interface UserTrack { id: string action: string actionLabel: string target?: string chapterTitle?: string extraData?: any createdAt: string timeAgo: string } export function UserDetailModal({ open, onClose, userId, onUserUpdated }: UserDetailModalProps) { const [user, setUser] = useState(null) const [tracks, setTracks] = useState([]) const [referrals, setReferrals] = useState([]) const [loading, setLoading] = useState(false) const [syncing, setSyncing] = useState(false) const [saving, setSaving] = useState(false) const [activeTab, setActiveTab] = useState("info") // 可编辑字段 const [editPhone, setEditPhone] = useState("") const [editNickname, setEditNickname] = useState("") const [editTags, setEditTags] = useState([]) const [newTag, setNewTag] = useState("") // 加载用户详情 useEffect(() => { if (open && userId) { loadUserDetail() } }, [open, userId]) const loadUserDetail = async () => { if (!userId) return setLoading(true) try { // 加载用户基础信息 const userRes = await fetch(`/api/db/users?id=${userId}`) const userData = await userRes.json() if (userData.success && userData.user) { const u = userData.user setUser(u) setEditPhone(u.phone || "") setEditNickname(u.nickname || "") setEditTags(u.tags ? JSON.parse(u.tags) : []) } // 加载行为轨迹 const trackRes = await fetch(`/api/user/track?userId=${userId}&limit=50`) const trackData = await trackRes.json() if (trackData.success) { setTracks(trackData.tracks || []) } // 加载绑定关系 const refRes = await fetch(`/api/db/users/referrals?userId=${userId}`) const refData = await refRes.json() if (refData.success) { setReferrals(refData.referrals || []) } } catch (error) { console.error("Load user detail error:", error) } finally { setLoading(false) } } // 同步存客宝数据 const handleSyncCKB = async () => { if (!user?.phone) { alert("用户未绑定手机号,无法同步") return } setSyncing(true) try { const res = await fetch("/api/ckb/sync", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "full_sync", phone: user.phone, userId: user.id }) }) const data = await res.json() if (data.success) { alert("同步成功") loadUserDetail() } else { alert("同步失败: " + (data.error || "未知错误")) } } catch (error) { console.error("Sync CKB error:", error) alert("同步失败") } finally { setSyncing(false) } } // 保存用户信息 const handleSave = async () => { if (!user) return setSaving(true) try { const res = await fetch("/api/db/users", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: user.id, phone: editPhone || undefined, nickname: editNickname || undefined, tags: JSON.stringify(editTags) }) }) const data = await res.json() if (data.success) { alert("保存成功") loadUserDetail() onUserUpdated?.() } else { alert("保存失败: " + (data.error || "未知错误")) } } catch (error) { console.error("Save user error:", error) alert("保存失败") } finally { setSaving(false) } } // 添加标签 const addTag = () => { if (newTag && !editTags.includes(newTag)) { setEditTags([...editTags, newTag]) setNewTag("") } } // 移除标签 const removeTag = (tag: string) => { setEditTags(editTags.filter(t => t !== tag)) } // 获取行为图标 const getActionIcon = (action: string) => { const icons: Record = { 'view_chapter': BookOpen, 'purchase': ShoppingBag, 'match': Users, 'login': User, 'register': User, 'share': Link2, 'bind_phone': Phone, 'bind_wechat': MessageCircle, } const Icon = icons[action] || History return } if (!open) return null return ( onClose()}> 用户详情 {user?.phone && ( 已绑定手机 )} {loading ? (
加载中...
) : user ? (
{/* 用户头部信息 */}
{user.avatar ? ( ) : ( user.nickname?.charAt(0) || "?" )}

{user.nickname}

{user.is_admin && ( 管理员 )} {user.has_full_book && ( 全书已购 )}

{user.phone ? `📱 ${user.phone}` : "未绑定手机"} {user.wechat_id && ` · 💬 ${user.wechat_id}`}

ID: {user.id} · 推广码: {user.referral_code}

¥{(user.earnings || 0).toFixed(2)}

累计收益

{/* 标签页 */} 基础信息 标签体系 行为轨迹 关系链路 {/* 基础信息 */}
setEditPhone(e.target.value)} />
setEditNickname(e.target.value)} />

推荐人数

{user.referral_count || 0}

待提现

¥{(user.pending_earnings || 0).toFixed(2)}

创建时间

{user.created_at ? new Date(user.created_at).toLocaleDateString() : '-'}

{/* 存客宝同步状态 */}
存客宝同步
同步状态: {user.ckb_synced_at ? ( 已同步 ) : ( 未同步 )}
最后同步: {user.ckb_synced_at ? new Date(user.ckb_synced_at).toLocaleString() : '-'}
{/* 标签体系 */} {/* 系统标签 */}
系统标签
{editTags.map((tag, i) => ( {tag} ))} {editTags.length === 0 && 暂无标签}
setNewTag(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && addTag()} />
{/* 存客宝标签 */}
存客宝标签
{(user.ckb_tags ? JSON.parse(user.ckb_tags) : []).map((tag: string, i: number) => ( {tag} ))} {(!user.ckb_tags || JSON.parse(user.ckb_tags).length === 0) && ( 同步后显示 )}
{/* 来源标签 */}
来源标签
{user.open_id ? '微信小程序' : '手动创建'} {user.referred_by && ( 推荐来源: {user.referred_by.slice(0, 8)} )}
{/* 行为轨迹 */}
{tracks.length > 0 ? ( tracks.map((track) => (
{getActionIcon(track.action)}
{track.actionLabel} {track.chapterTitle && ( - {track.chapterTitle} )}

{track.timeAgo} · {new Date(track.createdAt).toLocaleString()}

)) ) : (

暂无行为记录

)}
{/* 关系链路 */} {/* 来源信息 */}
来源追溯
创建方式: {user.open_id ? '微信授权' : '手动创建'}
{user.referred_by && (
推荐人: {user.referred_by}
)}
创建时间: {user.created_at ? new Date(user.created_at).toLocaleString() : '-'}
{/* 推荐的用户 */}
推荐的用户
共 {referrals.length} 人
{referrals.length > 0 ? ( referrals.map((ref: any) => (
{ref.nickname?.charAt(0) || "?"}
{ref.nickname}
{ref.status === 'vip' && ( 已购 )} {ref.createdAt ? new Date(ref.createdAt).toLocaleDateString() : ''}
)) ) : (

暂无推荐用户

)}
{/* 底部操作栏 */}
) : (
用户不存在
)}
) }