feat: refactor data asset center for enhanced search and analytics

Refactor homepage for focused search and data display; streamline data platform; enhance user and tag management; focus AI assistant on data analysis and report generation.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
v0
2025-07-25 06:42:34 +00:00
parent ecd8a48863
commit 4eed69520c
40 changed files with 6853 additions and 6111 deletions

View File

@@ -0,0 +1,473 @@
// 智能搜索服务 - 实现亚秒级查询和AI增强搜索
import { getMindsDBConnector, type SearchRequest, type AIQueryRequest } from "@/lib/mindsdb-connector"
export interface SearchResult {
id: string
type: "user" | "traffic" | "insight"
title: string
description: string
tags: string[]
relevanceScore: number
updatedAt: string
metadata?: Record<string, any>
}
export interface SearchStats {
totalResults: number
queryTime: number
suggestions: string[]
filters: Record<string, any>
}
export interface SearchResponse {
results: SearchResult[]
stats: SearchStats
hasMore: boolean
}
export class IntelligentSearchService {
private mindsDB = getMindsDBConnector()
private searchHistory: string[] = []
private popularQueries: Map<string, number> = new Map()
// 智能搜索主入口
async search(
query: string,
type: "user" | "traffic" | "all" = "all",
options: {
limit?: number
offset?: number
filters?: Record<string, any>
useAI?: boolean
includeInsights?: boolean
} = {},
): Promise<SearchResponse> {
const startTime = Date.now()
try {
// 记录搜索历史
this.addToSearchHistory(query)
// 如果启用AI增强搜索
if (options.useAI) {
return await this.aiEnhancedSearch(query, type, options)
}
// 标准搜索
const searchRequest: SearchRequest = {
keyword: query,
type,
filters: options.filters,
limit: options.limit || 50,
offset: options.offset || 0,
}
const rawResults = await this.mindsDB.intelligentSearch(searchRequest)
const results = this.formatSearchResults(rawResults)
// 如果需要包含AI洞察
if (options.includeInsights) {
const insights = await this.generateSearchInsights(query, results)
results.push(...insights)
}
const queryTime = Date.now() - startTime
return {
results,
stats: {
totalResults: results.length,
queryTime,
suggestions: await this.generateSuggestions(query),
filters: this.extractAvailableFilters(results),
},
hasMore: results.length === (options.limit || 50),
}
} catch (error) {
console.error("搜索失败:", error)
throw error
}
}
// AI增强搜索
private async aiEnhancedSearch(
query: string,
type: "user" | "traffic" | "all",
options: any,
): Promise<SearchResponse> {
const startTime = Date.now()
// 使用AI理解查询意图
const aiRequest: AIQueryRequest = {
query: `分析这个搜索查询的意图并提供相关的搜索建议: "${query}"`,
model: "gpt4",
useCache: true,
}
const aiAnalysis = await this.mindsDB.aiQuery(aiRequest)
// 基于AI分析结果优化搜索参数
const enhancedSearchRequest: SearchRequest = {
keyword: query,
type,
filters: {
...options.filters,
...this.extractFiltersFromAI(aiAnalysis),
},
limit: options.limit || 50,
offset: options.offset || 0,
}
const rawResults = await this.mindsDB.intelligentSearch(enhancedSearchRequest)
const results = this.formatSearchResults(rawResults)
// AI生成的相关洞察
const aiInsights = await this.generateAIInsights(query, results)
results.push(...aiInsights)
const queryTime = Date.now() - startTime
return {
results,
stats: {
totalResults: results.length,
queryTime,
suggestions: await this.generateAISuggestions(query, aiAnalysis),
filters: this.extractAvailableFilters(results),
},
hasMore: results.length === (options.limit || 50),
}
}
// 格式化搜索结果
private formatSearchResults(rawResults: any[]): SearchResult[] {
return rawResults.map((result) => ({
id: result.id || result.user_id || result.keyword_id,
type: result.type || "user",
title: result.title || result.username || result.keyword,
description: result.description || this.generateDescription(result),
tags: this.parseTags(result.tags),
relevanceScore: result.relevance_score || 0,
updatedAt: result.updated_at || result.last_active || result.last_updated,
metadata: {
...result,
searchType: result.type,
},
}))
}
// 生成描述
private generateDescription(result: any): string {
if (result.type === "user") {
return `${result.phone || ""} | ${result.email || ""} | RFM: ${result.rfm_score || "N/A"}`
} else if (result.type === "traffic") {
return `搜索量: ${result.search_volume || "N/A"} | 竞争度: ${result.competition || "N/A"} | CPC: ${result.cpc || "N/A"}`
}
return result.description || ""
}
// 解析标签
private parseTags(tags: any): string[] {
if (typeof tags === "string") {
try {
return JSON.parse(tags)
} catch {
return tags.split(",").map((tag) => tag.trim())
}
}
return Array.isArray(tags) ? tags : []
}
// 生成搜索建议
private async generateSuggestions(query: string): Promise<string[]> {
const suggestions: string[] = []
// 基于搜索历史的建议
const historySuggestions = this.searchHistory
.filter((h) => h.toLowerCase().includes(query.toLowerCase()) && h !== query)
.slice(0, 3)
suggestions.push(...historySuggestions)
// 基于热门查询的建议
const popularSuggestions = Array.from(this.popularQueries.entries())
.sort((a, b) => b[1] - a[1])
.map(([q]) => q)
.filter((q) => q.toLowerCase().includes(query.toLowerCase()) && q !== query)
.slice(0, 3)
suggestions.push(...popularSuggestions)
// 智能补全建议
const completionSuggestions = await this.generateCompletionSuggestions(query)
suggestions.push(...completionSuggestions)
return [...new Set(suggestions)].slice(0, 8)
}
// 生成AI建议
private async generateAISuggestions(query: string, aiAnalysis: any): Promise<string[]> {
try {
const aiRequest: AIQueryRequest = {
query: `基于查询"${query}"和分析结果生成5个相关的搜索建议`,
model: "gpt4",
useCache: true,
}
const result = await this.mindsDB.aiQuery(aiRequest)
return this.parseAISuggestions(result)
} catch (error) {
console.error("生成AI建议失败:", error)
return []
}
}
// 生成补全建议
private async generateCompletionSuggestions(query: string): Promise<string[]> {
// 这里可以集成更复杂的自动补全逻辑
const commonSuffixes = ["分析", "统计", "趋势", "预测", "报告", "用户", "流量", "关键词", "转化", "留存"]
return commonSuffixes
.map((suffix) => `${query} ${suffix}`)
.filter((suggestion) => suggestion.length <= 50)
.slice(0, 3)
}
// 解析AI建议
private parseAISuggestions(aiResult: any): string[] {
try {
// 假设AI返回的是建议列表
if (aiResult.suggestions && Array.isArray(aiResult.suggestions)) {
return aiResult.suggestions
}
// 如果是文本格式,尝试解析
if (typeof aiResult === "string") {
const lines = aiResult.split("\n")
return lines
.filter((line) => line.trim().length > 0)
.map((line) => line.replace(/^\d+\.\s*/, "").trim())
.slice(0, 5)
}
return []
} catch (error) {
console.error("解析AI建议失败:", error)
return []
}
}
// 从AI分析中提取过滤器
private extractFiltersFromAI(aiAnalysis: any): Record<string, any> {
const filters: Record<string, any> = {}
try {
if (aiAnalysis.filters) {
Object.assign(filters, aiAnalysis.filters)
}
// 基于AI分析结果添加智能过滤器
if (aiAnalysis.intent === "high_value_users") {
filters.rfm_score = { $gte: 80 }
}
if (aiAnalysis.intent === "recent_activity") {
filters.last_active = { $gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) }
}
} catch (error) {
console.error("提取AI过滤器失败:", error)
}
return filters
}
// 生成搜索洞察
private async generateSearchInsights(query: string, results: SearchResult[]): Promise<SearchResult[]> {
const insights: SearchResult[] = []
try {
// 用户相关洞察
const userResults = results.filter((r) => r.type === "user")
if (userResults.length > 0) {
const userInsight = await this.generateUserInsight(query, userResults)
if (userInsight) insights.push(userInsight)
}
// 流量相关洞察
const trafficResults = results.filter((r) => r.type === "traffic")
if (trafficResults.length > 0) {
const trafficInsight = await this.generateTrafficInsight(query, trafficResults)
if (trafficInsight) insights.push(trafficInsight)
}
} catch (error) {
console.error("生成搜索洞察失败:", error)
}
return insights
}
// 生成AI洞察
private async generateAIInsights(query: string, results: SearchResult[]): Promise<SearchResult[]> {
const insights: SearchResult[] = []
try {
const aiRequest: AIQueryRequest = {
query: `基于搜索查询"${query}"和${results.length}个结果生成3个关键业务洞察`,
model: "gpt4",
useCache: true,
}
const aiResult = await this.mindsDB.aiQuery(aiRequest)
const aiInsights = this.parseAIInsights(aiResult)
insights.push(...aiInsights)
} catch (error) {
console.error("生成AI洞察失败:", error)
}
return insights
}
// 解析AI洞察
private parseAIInsights(aiResult: any): SearchResult[] {
const insights: SearchResult[] = []
try {
if (aiResult.insights && Array.isArray(aiResult.insights)) {
aiResult.insights.forEach((insight: any, index: number) => {
insights.push({
id: `ai_insight_${Date.now()}_${index}`,
type: "insight",
title: insight.title || `AI洞察 ${index + 1}`,
description: insight.description || insight.content,
tags: ["AI洞察", "智能分析"],
relevanceScore: insight.confidence || 0.8,
updatedAt: new Date().toISOString(),
metadata: {
source: "ai",
confidence: insight.confidence,
type: "insight",
},
})
})
}
} catch (error) {
console.error("解析AI洞察失败:", error)
}
return insights
}
// 生成用户洞察
private async generateUserInsight(query: string, userResults: SearchResult[]): Promise<SearchResult | null> {
try {
const totalUsers = userResults.length
const avgRelevance = userResults.reduce((sum, r) => sum + r.relevanceScore, 0) / totalUsers
return {
id: `user_insight_${Date.now()}`,
type: "insight",
title: "用户搜索洞察",
description: `找到 ${totalUsers} 个相关用户,平均相关度 ${avgRelevance.toFixed(2)}`,
tags: ["用户分析", "搜索洞察"],
relevanceScore: 0.9,
updatedAt: new Date().toISOString(),
metadata: {
totalUsers,
avgRelevance,
type: "user_insight",
},
}
} catch (error) {
console.error("生成用户洞察失败:", error)
return null
}
}
// 生成流量洞察
private async generateTrafficInsight(query: string, trafficResults: SearchResult[]): Promise<SearchResult | null> {
try {
const totalKeywords = trafficResults.length
const avgRelevance = trafficResults.reduce((sum, r) => sum + r.relevanceScore, 0) / totalKeywords
return {
id: `traffic_insight_${Date.now()}`,
type: "insight",
title: "流量关键词洞察",
description: `找到 ${totalKeywords} 个相关关键词,平均相关度 ${avgRelevance.toFixed(2)}`,
tags: ["流量分析", "关键词洞察"],
relevanceScore: 0.9,
updatedAt: new Date().toISOString(),
metadata: {
totalKeywords,
avgRelevance,
type: "traffic_insight",
},
}
} catch (error) {
console.error("生成流量洞察失败:", error)
return null
}
}
// 提取可用过滤器
private extractAvailableFilters(results: SearchResult[]): Record<string, any> {
const filters: Record<string, any> = {}
// 提取类型过滤器
const types = [...new Set(results.map((r) => r.type))]
if (types.length > 1) {
filters.type = types
}
// 提取标签过滤器
const allTags = results.flatMap((r) => r.tags)
const uniqueTags = [...new Set(allTags)]
if (uniqueTags.length > 0) {
filters.tags = uniqueTags.slice(0, 20) // 限制标签数量
}
return filters
}
// 添加到搜索历史
private addToSearchHistory(query: string): void {
if (query.trim().length === 0) return
// 更新搜索历史
this.searchHistory.unshift(query)
this.searchHistory = [...new Set(this.searchHistory)].slice(0, 100) // 保留最近100个唯一查询
// 更新热门查询统计
const count = this.popularQueries.get(query) || 0
this.popularQueries.set(query, count + 1)
}
// 获取搜索统计
getSearchStats(): any {
return {
totalSearches: this.searchHistory.length,
uniqueQueries: new Set(this.searchHistory).size,
popularQueries: Array.from(this.popularQueries.entries())
.sort((a, b) => b[1] - a[1])
.slice(0, 10)
.map(([query, count]) => ({ query, count })),
}
}
// 清理搜索历史
clearSearchHistory(): void {
this.searchHistory = []
this.popularQueries.clear()
}
}
// 单例模式
let searchServiceInstance: IntelligentSearchService | null = null
export function getIntelligentSearchService(): IntelligentSearchService {
if (!searchServiceInstance) {
searchServiceInstance = new IntelligentSearchService()
}
return searchServiceInstance
}