import { NextRequest, NextResponse } from 'next/server' import { getMongoClient } from '@/lib/mongodb' // 项目定义(基于真实数据库) const PROJECTS = { ckb: { id: 'ckb', name: '存客宝', database: 'KR_存客宝', collection: '用户资产统一视图', color: 'blue', icon: 'Users' }, dlm: { id: 'dlm', name: '点了码', database: 'KR_点了码', collection: '用户资产统一视图', color: 'green', icon: 'QrCode' }, weibo: { id: 'weibo', name: '微博', database: 'KR_微博', collection: '微博uid+手机', color: 'orange', icon: 'Globe' }, qq: { id: 'qq', name: 'QQ社交', database: 'KR_腾讯', collection: 'QQ+手机', color: 'purple', icon: 'MessageCircle' } } // 获取项目列表及统计 async function getProjectStats() { const client = await getMongoClient() const stats = [] for (const [key, project] of Object.entries(PROJECTS)) { try { const db = client.db(project.database) const count = await db.collection(project.collection).estimatedDocumentCount() stats.push({ ...project, userCount: count, status: 'active' }) } catch { stats.push({ ...project, userCount: 0, status: 'error' }) } } return stats } // 获取项目下的流量池/标签分类 async function getProjectPools(projectId: string) { const client = await getMongoClient() const project = PROJECTS[projectId as keyof typeof PROJECTS] if (!project) { return { error: '项目不存在' } } const db = client.db(project.database) const collection = db.collection(project.collection) // 根据项目类型获取不同的分组字段 let pools: any[] = [] if (projectId === 'ckb') { // 存客宝按流量池分组 const poolStats = await collection.aggregate([ { $sample: { size: 50000 } }, { $group: { _id: '$traffic_pool.pool_name', count: { $sum: 1 }, avgScore: { $avg: '$user_evaluation_score' } }}, { $sort: { count: -1 } } ], { maxTimeMS: 10000 }).toArray() // 按标签分组 const tagStats = await collection.aggregate([ { $sample: { size: 50000 } }, { $unwind: '$unified_tags' }, { $group: { _id: '$unified_tags', count: { $sum: 1 } }}, { $sort: { count: -1 } }, { $limit: 20 } ], { maxTimeMS: 10000 }).toArray() const total = await collection.estimatedDocumentCount() const ratio = total / 50000 pools = [ ...poolStats.filter(p => p._id).map(p => ({ id: `pool_${p._id}`, name: p._id, type: 'pool', count: Math.round(p.count * ratio), avgScore: Math.round(p.avgScore || 0) })), ...tagStats.filter(t => t._id).map(t => ({ id: `tag_${t._id}`, name: t._id, type: 'tag', count: Math.round(t.count * ratio) })) ] } else if (projectId === 'dlm') { // 点了码按角色标签分组 const roleStats = await collection.aggregate([ { $unwind: { path: '$角色标签', preserveNullAndEmptyArrays: true } }, { $group: { _id: '$角色标签', count: { $sum: 1 } }}, { $sort: { count: -1 } } ], { maxTimeMS: 10000 }).toArray() // 按用户等级分组 const levelStats = await collection.aggregate([ { $group: { _id: '$用户等级', count: { $sum: 1 } }}, { $sort: { count: -1 } } ], { maxTimeMS: 10000 }).toArray() pools = [ ...roleStats.filter(r => r._id).map(r => ({ id: `role_${r._id}`, name: r._id, type: 'role', count: r.count })), ...levelStats.filter(l => l._id).map(l => ({ id: `level_${l._id}`, name: `${l._id}级用户`, type: 'level', count: l.count })) ] } else if (projectId === 'qq') { // QQ按省份分组 const provinceStats = await collection.aggregate([ { $sample: { size: 100000 } }, { $match: { '省份': { $exists: true, $ne: null } } }, { $group: { _id: '$省份', count: { $sum: 1 } }}, { $sort: { count: -1 } }, { $limit: 20 } ], { maxTimeMS: 10000 }).toArray() const total = await collection.estimatedDocumentCount() const ratio = total / 100000 pools = provinceStats.map(p => ({ id: `province_${p._id}`, name: p._id, type: 'province', count: Math.round(p.count * ratio) })) } else if (projectId === 'weibo') { // 微博简单统计 const total = await collection.estimatedDocumentCount() pools = [{ id: 'weibo_all', name: '微博用户', type: 'all', count: total }] } return { project, pools, totalPools: pools.length } } // 获取流量池内的用户列表 async function getPoolUsers(projectId: string, poolId: string, page: number = 1, limit: number = 20) { const client = await getMongoClient() const project = PROJECTS[projectId as keyof typeof PROJECTS] if (!project) { return { error: '项目不存在' } } const db = client.db(project.database) const collection = db.collection(project.collection) // 解析poolId构建查询条件 let query: any = {} const [type, ...nameParts] = poolId.split('_') const name = nameParts.join('_') console.log('Pool query:', { type, name, projectId, poolId }) if (type === 'pool') { query['traffic_pool.pool_name'] = name } else if (type === 'tag') { query['unified_tags'] = name } else if (type === 'role') { query['角色标签'] = name } else if (type === 'level') { query['用户等级'] = name.replace('级用户', '') } else if (type === 'province') { query['省份'] = name } // 如果没有匹配条件,尝试直接用name搜索 if (Object.keys(query).length === 0 || type === 'all') { query = {} } const skip = (page - 1) * limit const [users, total] = await Promise.all([ collection.find(query) .project({ phone_masked: 1, name: 1, 'core_profile.name': 1, user_evaluation_score: 1, unified_tags: 1, '角色标签': 1, '用户等级': 1, 'rfm_scores.user_level': 1, created_at: 1 }) .skip(skip) .limit(limit) .toArray(), collection.countDocuments(query) ]) return { users: users.map(u => ({ id: u._id.toString(), phone: u.phone_masked || '未知', name: u.name || u.core_profile?.name || '未知用户', score: u.user_evaluation_score || 0, level: u.rfm_scores?.user_level || u['用户等级'] || '-', tags: u.unified_tags || u['角色标签'] || [], createdAt: u.created_at })), total, page, totalPages: Math.ceil(total / limit) } } export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url) const action = searchParams.get('action') || 'projects' const projectId = searchParams.get('projectId') const poolId = searchParams.get('poolId') const page = parseInt(searchParams.get('page') || '1') try { if (action === 'projects') { const stats = await getProjectStats() return NextResponse.json({ success: true, projects: stats }) } if (action === 'pools' && projectId) { const pools = await getProjectPools(projectId) return NextResponse.json({ success: true, ...pools }) } if (action === 'users' && projectId && poolId) { const users = await getPoolUsers(projectId, poolId, page) return NextResponse.json({ success: true, ...users }) } return NextResponse.json({ error: '无效的操作' }, { status: 400 }) } catch (error) { console.error('流量池API错误:', error) return NextResponse.json({ error: '查询失败' }, { status: 500 }) } }