package repositories import ( "database/sql" "log" "github.com/niangaodev/art-code/config" "github.com/niangaodev/art-code/models" ) // GetWorks 获取所有作品 func GetWorks() ([]models.Work, error) { query := "SELECT id, title, category, year, hero_img, description, is_featured, created_at, updated_at FROM works" rows, err := config.DB.Query(query) if err != nil { log.Printf("Error querying works: %v", err) return nil, err } defer rows.Close() var works []models.Work for rows.Next() { var work models.Work if err := rows.Scan( &work.ID, &work.Title, &work.Category, &work.Year, &work.HeroImg, &work.Description, &work.IsFeatured, &work.CreatedAt, &work.UpdatedAt, ); err != nil { log.Printf("Error scanning work: %v", err) continue } works = append(works, work) } return works, nil } // GetWorkByID 根据ID获取作品 func GetWorkByID(id string) (*models.Work, error) { query := "SELECT id, title, category, year, hero_img, description, is_featured, created_at, updated_at FROM works WHERE id = ?" row := config.DB.QueryRow(query, id) var work models.Work if err := row.Scan( &work.ID, &work.Title, &work.Category, &work.Year, &work.HeroImg, &work.Description, &work.IsFeatured, &work.CreatedAt, &work.UpdatedAt, ); err != nil { if err == sql.ErrNoRows { return nil, nil } log.Printf("Error scanning work by ID: %v", err) return nil, err } return &work, nil } // GetWorkTechStack 获取作品的技术栈 func GetWorkTechStack(workID string) ([]models.WorkTechStack, error) { query := "SELECT id, work_id, category, item, created_at FROM work_tech_stack WHERE work_id = ?" rows, err := config.DB.Query(query, workID) if err != nil { log.Printf("Error querying work tech stack: %v", err) return nil, err } defer rows.Close() var techStacks []models.WorkTechStack for rows.Next() { var techStack models.WorkTechStack if err := rows.Scan( &techStack.ID, &techStack.WorkID, &techStack.Category, &techStack.Item, &techStack.CreatedAt, ); err != nil { log.Printf("Error scanning work tech stack: %v", err) continue } techStacks = append(techStacks, techStack) } return techStacks, nil } // GetWorkGallery 获取作品的图库 func GetWorkGallery(workID string) ([]models.WorkGallery, error) { query := "SELECT id, work_id, image_url, sort_order, description, created_at FROM work_gallery WHERE work_id = ? ORDER BY sort_order" rows, err := config.DB.Query(query, workID) if err != nil { log.Printf("Error querying work gallery: %v", err) return nil, err } defer rows.Close() var galleries []models.WorkGallery for rows.Next() { var gallery models.WorkGallery if err := rows.Scan( &gallery.ID, &gallery.WorkID, &gallery.ImageURL, &gallery.SortOrder, &gallery.Description, &gallery.CreatedAt, ); err != nil { log.Printf("Error scanning work gallery: %v", err) continue } galleries = append(galleries, gallery) } return galleries, nil } // BuildWorkResponse 构建作品响应,包含关联数据 func BuildWorkResponse(work *models.Work) (*models.WorkResponse, error) { // 获取技术栈 techStacks, err := GetWorkTechStack(work.ID) if err != nil { return nil, err } // 按类别分组技术栈 techStackMap := make(map[string][]string) for _, ts := range techStacks { techStackMap[ts.Category] = append(techStackMap[ts.Category], ts.Item) } // 转换为前端期望的格式 var techStackResponse []map[string]interface{} for category, items := range techStackMap { techStackResponse = append(techStackResponse, map[string]interface{}{ "category": category, "items": items, }) } // 获取图库 galleries, err := GetWorkGallery(work.ID) if err != nil { return nil, err } // 提取图片URL var galleryImages []string for _, g := range galleries { galleryImages = append(galleryImages, g.ImageURL) } // 获取下一个作品ID nextWorkID, err := GetNextWorkID(work.ID) if err != nil { log.Printf("Error getting next work ID: %v", err) nextWorkID = "" } return &models.WorkResponse{ ID: work.ID, Title: work.Title, Category: work.Category, Year: work.Year, HeroImg: work.HeroImg, Desc: work.Description, TechStack: techStackResponse, Gallery: galleryImages, Links: map[string]interface{}{ "live": "#", }, Next: nextWorkID, }, nil } // GetNextWorkID 获取下一个作品ID(简单实现,实际可能需要更复杂的逻辑) func GetNextWorkID(currentID string) (string, error) { // 获取所有作品ID query := "SELECT id FROM works" rows, err := config.DB.Query(query) if err != nil { return "", err } defer rows.Close() var ids []string for rows.Next() { var id string if err := rows.Scan(&id); err != nil { continue } ids = append(ids, id) } // 找到当前ID的索引 index := -1 for i, id := range ids { if id == currentID { index = i break } } // 如果没找到或者是最后一个,返回第一个 if index == -1 || index == len(ids)-1 { if len(ids) > 0 { return ids[0], nil } return "", nil } // 返回下一个 return ids[index+1], nil } // CreateWork 创建作品 func CreateWork(work *models.Work) error { query := ` INSERT INTO works (id, title, category, year, hero_img, description, is_featured, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW()) ` _, err := config.DB.Exec( query, work.ID, work.Title, work.Category, work.Year, work.HeroImg, work.Description, work.IsFeatured, ) if err != nil { log.Printf("Error creating work: %v", err) return err } return nil } // UpdateWork 更新作品 func UpdateWork(work *models.Work) error { query := ` UPDATE works SET title = ?, category = ?, year = ?, hero_img = ?, description = ?, is_featured = ?, updated_at = NOW() WHERE id = ? ` _, err := config.DB.Exec( query, work.Title, work.Category, work.Year, work.HeroImg, work.Description, work.IsFeatured, work.ID, ) if err != nil { log.Printf("Error updating work: %v", err) return err } return nil } // DeleteWork 删除作品 func DeleteWork(id string) error { query := "DELETE FROM works WHERE id = ?" _, err := config.DB.Exec(query, id) if err != nil { log.Printf("Error deleting work: %v", err) return err } return nil } // GetWorkCount 获取作品总数 func GetWorkCount() (int, error) { var count int query := "SELECT COUNT(*) FROM works" row := config.DB.QueryRow(query) err := row.Scan(&count) if err != nil { log.Printf("Error getting work count: %v", err) return 0, err } return count, nil }