feat: optimize interface and database connection

Adjust MongoDB mock connector and update database structure.
Enhance sidebar, data platform, and AI analysis tools.
Clean up unnecessary code and update development docs.

#VERCEL_SKIP

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
v0
2025-07-21 00:11:52 +00:00
parent 892c5b4855
commit ecd8a48863
26 changed files with 1821 additions and 1024 deletions

View File

@@ -0,0 +1,285 @@
// lib/mongodb-mock-connector.ts
// 这是一个模拟 MongoDB 数据库连接器,用于在前端环境中模拟后端 MongoDB 的数据结构和操作。
// 在实际的 Next.js 应用中,您会使用 'mongodb' 或 'mongoose' 等库在服务器端建立真实的连接。
// 模拟 MongoDB 集合数据
const mockCollections: Record<string, any[]> = {
users: [
{
_id: "user_global_id_1",
core_profile: {
username: "zhangsan",
email: "zhangsan@example.com",
phone: "13800138000",
full_name: "张三",
gender: "male",
birth_date: "1990-01-01",
address: "北京市朝阳区",
city: "北京",
province: "北京",
country: "中国",
avatar_url: "/diverse-user-avatars.png",
bio: "热爱科技的互联网从业者",
},
unified_tags: ["高价值客户", "科技爱好者", "活跃用户"],
unified_attributes: {
total_spend: 12500,
last_active_days: 3,
content_preference: ["科技", "旅游"],
},
source_profiles: [
{
source: "douyin",
source_user_id: "dy_openid_123",
original_data: {
nickname: "抖音张三",
avatar: "/douyin-avatar.png",
follower_count: 15000,
},
content_activity: [
{
content_id: "video1",
type: "video",
url: "https://douyin.com/video1",
text: "最新科技产品评测",
publish_time: "2023-07-10T10:00:00Z",
likes: 1000,
comments: 50,
},
],
ingestion_timestamp: "2023-07-15T14:30:00Z",
},
{
source: "cunkebao_form_submit",
source_record_id: "form_submission_id_456",
original_data: {
name: "张三",
phone: "13800138000",
form_name: "产品咨询表单",
},
ingestion_timestamp: "2023-07-12T09:00:00Z",
},
],
ai_insights: {
persona_tags: ["技术爱好者", "夜猫子"],
sentiment_score: 0.8,
potential_needs: ["自动化工具", "效率提升"],
},
crm_info: {
assigned_agent_id: "agent_001",
lead_status: "qualified",
last_contact_time: "2023-07-18T11:00:00Z",
next_contact_schedule: "2023-07-25T10:00:00Z",
},
createdAt: "2023-01-01T08:00:00Z",
updatedAt: "2023-07-20T15:00:00Z",
},
{
_id: "user_global_id_2",
core_profile: {
username: "lisi",
email: "lisi@example.com",
phone: "13912345678",
full_name: "李四",
gender: "female",
birth_date: "1992-05-15",
address: "上海市浦东新区",
city: "上海",
province: "上海",
country: "中国",
avatar_url: "/diverse-user-avatars.png",
bio: "喜欢旅游和美食",
},
unified_tags: ["新用户", "旅游达人", "美食家"],
unified_attributes: {
total_spend: 500,
last_active_days: 10,
content_preference: ["美食", "旅游"],
},
source_profiles: [
{
source: "xiaohongshu",
source_user_id: "xhs_openid_456",
original_data: {
nickname: "小红书李四",
avatar: "/xiaohongshu-avatar.png",
follower_count: 5000,
},
content_activity: [
{
content_id: "noteA",
type: "note",
url: "https://xiaohongshu.com/noteA",
text: "上海美食探店",
publish_time: "2023-07-05T18:00:00Z",
likes: 500,
comments: 20,
},
],
ingestion_timestamp: "2023-07-14T10:00:00Z",
},
],
ai_insights: {
persona_tags: ["美食爱好者", "旅行家"],
sentiment_score: 0.9,
potential_needs: ["旅游攻略", "餐厅推荐"],
},
crm_info: {
assigned_agent_id: "agent_002",
lead_status: "new",
last_contact_time: "2023-07-19T09:00:00Z",
next_contact_schedule: null,
},
createdAt: "2023-07-10T12:00:00Z",
updatedAt: "2023-07-19T16:00:00Z",
},
],
devices: [
{
_id: "device_id_1",
device_name: "Android模拟器-1",
device_type: "Android",
model: "Pixel 5",
os_version: "Android 11",
imei: "IMEI1234567890",
serial_number: "SN1234567890",
status: "online",
last_online: "2023-07-20T18:00:00Z",
registered_at: "2023-03-01T09:00:00Z",
},
{
_id: "device_id_2",
device_name: "iOS模拟器-1",
device_type: "iOS",
model: "iPhone 13",
os_version: "iOS 15",
imei: "IMEI0987654321",
serial_number: "SN0987654321",
status: "offline",
last_online: "2023-07-19T10:00:00Z",
registered_at: "2023-04-10T14:00:00Z",
},
],
wechat_accounts: [
{
_id: "wechat_account_id_1",
wechat_id: "wxid_test1",
nickname: "微信小助手1",
avatar_url: "/wechat-avatar.png",
qr_code_url: "/placeholder-8b0n0.png",
status: "active",
created_at: "2023-01-05T10:00:00Z",
last_sync: "2023-07-20T17:00:00Z",
},
{
_id: "wechat_account_id_2",
wechat_id: "wxid_test2",
nickname: "微信小助手2",
avatar_url: "/wechat-avatar.png",
qr_code_url: "/placeholder-8b0n0.png",
status: "inactive",
created_at: "2023-02-10T11:00:00Z",
last_sync: "2023-07-18T09:00:00Z",
},
],
content_items: [
{
_id: "content_item_id_1",
title: "2023年科技趋势报告",
content_type: "article",
content_data: {
text: "人工智能、大数据和云计算是2023年的三大科技趋势...",
images: ["/tech-report-abstract.png"],
},
created_by: "admin_user_id",
created_at: "2023-06-01T10:00:00Z",
updated_at: "2023-06-05T11:00:00Z",
status: "published",
},
{
_id: "content_item_id_2",
title: "夏日旅游攻略",
content_type: "video",
content_data: {
url: "https://example.com/travel-video.mp4",
thumbnail: "/travel-video-thumbnail.png",
description: "探索国内小众旅游目的地",
},
created_by: "editor_user_id",
created_at: "2023-07-01T14:00:00Z",
updated_at: "2023-07-01T14:00:00Z",
status: "draft",
},
],
// 更多模拟集合...
}
// 模拟数据库名称,对应 MongoDB 的数据库概念
const mockDatabases = [
{ Database: "cunkebao_user_platform" },
{ Database: "cunkebao_traffic_analysis" },
{ Database: "cunkebao_content_library" },
{ Database: "cunkebao_wechat_management" },
{ Database: "cunkebao_device_management" },
]
// 模拟获取所有数据库(在这里是集合的逻辑分组)
export async function getDatabases() {
return mockDatabases
}
// 模拟获取指定“数据库”中的所有“表”(在这里是集合)
export async function getTables(database: string) {
// 根据模拟的数据库名称返回对应的集合列表
if (database === "cunkebao_user_platform") {
return [{ Tables_in_database: "users" }]
} else if (database === "cunkebao_device_management") {
return [{ Tables_in_database: "devices" }]
} else if (database === "cunkebao_wechat_management") {
return [{ Tables_in_database: "wechat_accounts" }]
} else if (database === "cunkebao_content_library") {
return [{ Tables_in_database: "content_items" }]
}
return []
}
// 模拟获取集合结构MongoDB 没有严格的表结构,这里模拟返回字段示例)
export async function getTableStructure(database: string, collection: string) {
// 这是一个简化的模拟,实际 MongoDB 不会返回这种 SQL 风格的结构
// 而是通过分析文档来推断 schema
if (mockCollections[collection]) {
// 假设我们只返回第一个文档的键作为字段示例
const sampleDoc = mockCollections[collection][0]
if (sampleDoc) {
return Object.keys(sampleDoc).map((key) => ({
Field: key,
Type: typeof sampleDoc[key] === "object" && sampleDoc[key] !== null ? "json" : typeof sampleDoc[key],
Null: "YES", // MongoDB 默认允许 null
Key: key === "_id" ? "PRI" : "", // 模拟主键
Default: null,
Extra: "",
}))
}
}
return []
}
// 模拟获取数据库完整结构信息
export async function getDatabaseStructure(database: string) {
const structure: Record<string, any[]> = {}
if (database === "cunkebao_user_platform") {
structure.users = await getTableStructure(database, "users")
} else if (database === "cunkebao_device_management") {
structure.devices = await getTableStructure(database, "devices")
} else if (database === "cunkebao_wechat_management") {
structure.wechat_accounts = await getTableStructure(database, "wechat_accounts")
} else if (database === "cunkebao_content_library") {
structure.content_items = await getTableStructure(database, "content_items")
}
return structure
}
// 模拟获取集合中的数据
export async function getCollectionData(collectionName: string) {
return mockCollections[collectionName] || []
}