From 6a9c52fe1033b1b0a38d14de50e0a2d7359d6c29 Mon Sep 17 00:00:00 2001 From: dmy Date: Wed, 14 Jan 2026 01:06:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0AI=E6=8E=A8=E8=8D=90?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=8A=E8=87=AA=E5=8A=A8=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增AI推荐模块,包括后端数据获取接口和前端展示组件 实现自动刷新功能,每5分钟自动更新当前标签页数据 添加手动刷新按钮,优化用户交互体验 --- widget/looker/.gitignore | 3 + widget/looker/app.go | 64 +++++++ widget/looker/frontend/src/App.vue | 67 +++++++- .../src/components/AiRecommendations.vue | 161 ++++++++++++++++++ .../frontend/src/components/PinnedBids.vue | 4 + .../looker/frontend/wailsjs/go/main/App.d.ts | 2 + widget/looker/frontend/wailsjs/go/main/App.js | 4 + widget/looker/frontend/wailsjs/go/models.ts | 18 ++ 8 files changed, 317 insertions(+), 6 deletions(-) create mode 100644 widget/looker/.gitignore create mode 100644 widget/looker/frontend/src/components/AiRecommendations.vue diff --git a/widget/looker/.gitignore b/widget/looker/.gitignore new file mode 100644 index 0000000..129d522 --- /dev/null +++ b/widget/looker/.gitignore @@ -0,0 +1,3 @@ +build/bin +node_modules +frontend/dist diff --git a/widget/looker/app.go b/widget/looker/app.go index 5efbe7e..ba11b44 100644 --- a/widget/looker/app.go +++ b/widget/looker/app.go @@ -35,6 +35,14 @@ type BidItem struct { UpdatedAt string `json:"updatedAt"` } +// AiRecommendation AI推荐结构体 +type AiRecommendation struct { + ID string `json:"id"` + Title string `json:"title"` + Confidence int `json:"confidence"` + CreatedAt string `json:"createdAt"` +} + // App struct type App struct { ctx context.Context @@ -212,3 +220,59 @@ func (a *App) GetPinnedBidItems() ([]BidItem, error) { return items, nil } + +// GetAiRecommendations 获取 AI 推荐数据 +func (a *App) GetAiRecommendations() ([]AiRecommendation, error) { + dsn := a.GetDatabaseDSN() + if dsn == "" { + return nil, fmt.Errorf("数据库配置未加载") + } + + db, err := sql.Open("mysql", dsn) + if err != nil { + return nil, fmt.Errorf("连接数据库失败: %v", err) + } + defer db.Close() + + // 测试连接 + if err := db.Ping(); err != nil { + return nil, fmt.Errorf("数据库连接测试失败: %v", err) + } + + // 查询 ai_recommendations 表 + query := `SELECT id, title, confidence, createdAt + FROM ai_recommendations + ORDER BY createdAt DESC` + + rows, err := db.Query(query) + if err != nil { + return nil, fmt.Errorf("查询失败: %v", err) + } + defer rows.Close() + + var items []AiRecommendation + for rows.Next() { + var item AiRecommendation + var createdAt time.Time + + err := rows.Scan( + &item.ID, + &item.Title, + &item.Confidence, + &createdAt, + ) + if err != nil { + return nil, fmt.Errorf("扫描行失败: %v", err) + } + + item.CreatedAt = createdAt.Format("2006-01-02 15:04:05") + + items = append(items, item) + } + + if err := rows.Err(); err != nil { + return nil, fmt.Errorf("遍历行失败: %v", err) + } + + return items, nil +} diff --git a/widget/looker/frontend/src/App.vue b/widget/looker/frontend/src/App.vue index 0e82db4..4a9184f 100644 --- a/widget/looker/frontend/src/App.vue +++ b/widget/looker/frontend/src/App.vue @@ -1,13 +1,47 @@ @@ -82,6 +117,26 @@ body { padding: 20px; } +.refresh-button { + margin-left: auto; + padding: 8px 16px; + background: #3498db; + color: #fff; + border: none; + border-radius: 4px; + font-size: 14px; + cursor: pointer; + transition: all 0.2s ease; +} + +.refresh-button:hover { + background: #2980b9; +} + +.refresh-button:active { + transform: scale(0.98); +} + .placeholder { display: flex; align-items: center; diff --git a/widget/looker/frontend/src/components/AiRecommendations.vue b/widget/looker/frontend/src/components/AiRecommendations.vue new file mode 100644 index 0000000..4a1176c --- /dev/null +++ b/widget/looker/frontend/src/components/AiRecommendations.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/widget/looker/frontend/src/components/PinnedBids.vue b/widget/looker/frontend/src/components/PinnedBids.vue index b67c803..5191d0b 100644 --- a/widget/looker/frontend/src/components/PinnedBids.vue +++ b/widget/looker/frontend/src/components/PinnedBids.vue @@ -38,6 +38,10 @@ const openUrl = (url: string) => { onMounted(() => { loadPinnedBids() }) + +defineExpose({ + loadPinnedBids +})