Files
memory/server/internal/handler/search.go
2025-12-14 20:33:33 +08:00

136 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"database/sql"
"net/http"
"memory/internal/config"
"memory/internal/middleware"
"memory/internal/model"
"github.com/gin-gonic/gin"
)
type SearchHandler struct {
db *sql.DB
cfg *config.Config
}
func NewSearchHandler(db *sql.DB, cfg *config.Config) *SearchHandler {
return &SearchHandler{db: db, cfg: cfg}
}
func (h *SearchHandler) Search(c *gin.Context) {
userID := middleware.GetUserID(c)
var req model.SearchRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if req.Page < 1 {
req.Page = 1
}
if req.PageSize < 1 || req.PageSize > 50 {
req.PageSize = 20
}
offset := (req.Page - 1) * req.PageSize
// 构建查询
query := `
SELECT p.id, p.user_id, p.content, p.created_at,
u.id, u.username, u.nickname, u.avatar_url,
(SELECT COUNT(*) FROM likes WHERE post_id = p.id) as like_count,
(SELECT COUNT(*) FROM likes WHERE post_id = p.id AND user_id = ?) as liked,
(SELECT COUNT(*) FROM comments WHERE post_id = p.id) as comment_count
FROM posts p
JOIN users u ON p.user_id = u.id
WHERE 1=1
`
args := []interface{}{userID}
if req.Query != "" {
query += " AND p.content LIKE ?"
args = append(args, "%"+req.Query+"%")
}
if req.StartDate != "" {
query += " AND DATE(p.created_at) >= ?"
args = append(args, req.StartDate)
}
if req.EndDate != "" {
query += " AND DATE(p.created_at) <= ?"
args = append(args, req.EndDate)
}
query += " ORDER BY p.created_at DESC LIMIT ? OFFSET ?"
args = append(args, req.PageSize, offset)
rows, err := h.db.Query(query, args...)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "database error"})
return
}
defer rows.Close()
posts := []model.Post{}
for rows.Next() {
var post model.Post
var user model.User
var liked int
err := rows.Scan(
&post.ID, &post.UserID, &post.Content, &post.CreatedAt,
&user.ID, &user.Username, &user.Nickname, &user.AvatarURL,
&post.LikeCount, &liked, &post.CommentCount,
)
if err != nil {
continue
}
post.User = &user
post.Liked = liked > 0
posts = append(posts, post)
}
c.JSON(http.StatusOK, posts)
}
// 获取热力图数据GitHub 风格)
func (h *SearchHandler) Heatmap(c *gin.Context) {
year := c.DefaultQuery("year", "")
query := `
SELECT DATE(created_at) as date, COUNT(*) as count
FROM posts
WHERE 1=1
`
args := []interface{}{}
if year != "" {
query += " AND strftime('%Y', created_at) = ?"
args = append(args, year)
} else {
// 默认最近一年
query += " AND created_at >= DATE('now', '-1 year')"
}
query += " GROUP BY DATE(created_at) ORDER BY date"
rows, err := h.db.Query(query, args...)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "database error"})
return
}
defer rows.Close()
data := []model.HeatmapData{}
for rows.Next() {
var item model.HeatmapData
rows.Scan(&item.Date, &item.Count)
data = append(data, item)
}
c.JSON(http.StatusOK, data)
}