Files
nl-blogs/server/repositories/work_repository.go
2026-01-19 13:53:32 +08:00

260 lines
6.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 repositories
import (
"log"
"time"
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
"gorm.io/gorm"
)
// GetWorks 获取所有作品
func GetWorks() ([]models.Work, error) {
var works []models.Work
err := config.DB.Model(&models.Work{}).
Where("deleted_at = ?", 0).
Find(&works).Error
if err != nil {
log.Printf("Error querying works: %v", err)
return nil, err
}
return works, nil
}
// GetWorkByID 根据ID获取作品
func GetWorkByID(id string) (*models.Work, error) {
var work models.Work
err := config.DB.Model(&models.Work{}).
Where("id = ? AND deleted_at = ?", id, 0).
First(&work).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
}
log.Printf("Error getting work by ID: %v", err)
return nil, err
}
return &work, nil
}
// GetWorkTechStack 获取作品的技术栈
func GetWorkTechStack(workID string) ([]models.WorkTechStack, error) {
var techStacks []models.WorkTechStack
err := config.DB.Model(&models.WorkTechStack{}).
Where("work_id = ? AND deleted_at = ?", workID, 0).
Find(&techStacks).Error
if err != nil {
log.Printf("Error querying work tech stack: %v", err)
return nil, err
}
return techStacks, nil
}
// GetWorkGallery 获取作品的图库
func GetWorkGallery(workID string) ([]models.WorkGallery, error) {
var galleries []models.WorkGallery
err := config.DB.Model(&models.WorkGallery{}).
Where("work_id = ? AND deleted_at = ?", workID, 0).
Order("sort_order").
Find(&galleries).Error
if err != nil {
log.Printf("Error querying work gallery: %v", err)
return nil, err
}
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) {
var ids []string
err := config.DB.Model(&models.Work{}).
Select("id").
Where("deleted_at = ?", 0).
Pluck("id", &ids).Error
if err != nil {
return "", err
}
// 找到当前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 {
err := config.DB.Create(work).Error
if err != nil {
log.Printf("Error creating work: %v", err)
return err
}
return nil
}
// UpdateWork 更新作品
func UpdateWork(work *models.Work) error {
err := config.DB.Model(&models.Work{}).
Where("id = ? AND deleted_at = ?", work.ID, 0).
Updates(map[string]interface{}{
"title": work.Title,
"category": work.Category,
"year": work.Year,
"hero_img": work.HeroImg,
"description": work.Description,
"is_featured": work.IsFeatured,
"updated_at": time.Now().Unix(),
}).Error
if err != nil {
log.Printf("Error updating work: %v", err)
return err
}
return nil
}
// DeleteWork 删除作品 (Soft Delete)
func DeleteWork(id string) error {
err := config.DB.Model(&models.Work{}).
Where("id = ?", id).
Update("deleted_at", time.Now().Unix()).Error
if err != nil {
log.Printf("Error deleting work: %v", err)
return err
}
return nil
}
// GetAdminWorks 获取后台作品列表 (分页)
func GetAdminWorks(page, pageSize int) ([]models.Work, int, error) {
offset := (page - 1) * pageSize
var works []models.Work
var total int64
// 获取总数
err := config.DB.Model(&models.Work{}).
Where("deleted_at = ?", 0).
Count(&total).Error
if err != nil {
log.Printf("Error getting work count: %v", err)
return nil, 0, err
}
// 获取列表
err = config.DB.Model(&models.Work{}).
Where("deleted_at = ?", 0).
Order("created_at DESC").
Limit(pageSize).
Offset(offset).
Find(&works).Error
if err != nil {
log.Printf("Error querying admin works: %v", err)
return nil, 0, err
}
return works, int(total), nil
}
// BuildWorksResponse 构建作品列表响应
func BuildWorksResponse(works []models.Work) []models.WorkResponse {
var responses []models.WorkResponse
for _, work := range works {
// 这里不包含详情,简化处理
responses = append(responses, models.WorkResponse{
ID: work.ID,
Title: work.Title,
Category: work.Category,
Year: work.Year,
HeroImg: work.HeroImg,
Desc: work.Description,
})
}
return responses
}
// GetWorkCount 获取作品总数
func GetWorkCount() (int, error) {
var count int64
err := config.DB.Model(&models.Work{}).
Where("deleted_at = ?", 0).
Count(&count).Error
if err != nil {
log.Printf("Error getting work count: %v", err)
return 0, err
}
return int(count), nil
}