Files
nl-blogs/server/repositories/work_repository.go
2026-01-15 13:51:44 +08:00

302 lines
6.5 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 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
}