Files
nl-blogs/server/repositories/work_repository.go

347 lines
8.2 KiB
Go
Raw Normal View History

2026-01-15 13:51:44 +08:00
package repositories
import (
2026-01-19 20:21:09 +08:00
"encoding/json"
2026-01-15 13:51:44 +08:00
"log"
2026-01-16 13:01:21 +08:00
"time"
2026-01-15 13:51:44 +08:00
"github.com/niangaodev/art-code/config"
"github.com/niangaodev/art-code/models"
2026-01-19 13:53:32 +08:00
"gorm.io/gorm"
2026-01-15 13:51:44 +08:00
)
// GetWorks 获取所有作品
func GetWorks() ([]models.Work, error) {
2026-01-19 13:53:32 +08:00
var works []models.Work
err := config.DB.Model(&models.Work{}).
Where("deleted_at = ?", 0).
2026-01-20 08:31:42 +08:00
Order("id DESC").
2026-01-19 13:53:32 +08:00
Find(&works).Error
2026-01-15 13:51:44 +08:00
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
2026-01-19 13:53:32 +08:00
err := config.DB.Model(&models.Work{}).
Where("id = ? AND deleted_at = ?", id, 0).
First(&work).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
2026-01-15 13:51:44 +08:00
return nil, nil
}
2026-01-19 13:53:32 +08:00
log.Printf("Error getting work by ID: %v", err)
2026-01-15 13:51:44 +08:00
return nil, err
}
return &work, nil
}
// GetWorkTechStack 获取作品的技术栈
func GetWorkTechStack(workID string) ([]models.WorkTechStack, error) {
2026-01-19 13:53:32 +08:00
var techStacks []models.WorkTechStack
err := config.DB.Model(&models.WorkTechStack{}).
Where("work_id = ? AND deleted_at = ?", workID, 0).
Find(&techStacks).Error
2026-01-15 13:51:44 +08:00
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) {
2026-01-19 13:53:32 +08:00
var galleries []models.WorkGallery
err := config.DB.Model(&models.WorkGallery{}).
Where("work_id = ? AND deleted_at = ?", workID, 0).
Order("sort_order").
Find(&galleries).Error
2026-01-15 13:51:44 +08:00
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)
}
2026-01-19 20:21:09 +08:00
// 解析links JSON
var linksData map[string]interface{}
if work.Links != "" {
if err := json.Unmarshal([]byte(work.Links), &linksData); err != nil {
log.Printf("Error parsing links JSON: %v", err)
linksData = map[string]interface{}{"live": ""}
}
} else {
linksData = map[string]interface{}{"live": ""}
}
2026-01-15 13:51:44 +08:00
// 获取下一个作品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,
2026-01-19 20:21:09 +08:00
Links: linksData,
Next: nextWorkID,
2026-01-15 13:51:44 +08:00
}, nil
}
// GetNextWorkID 获取下一个作品ID(简单实现,实际可能需要更复杂的逻辑)
func GetNextWorkID(currentID string) (string, error) {
2026-01-19 13:53:32 +08:00
var ids []string
err := config.DB.Model(&models.Work{}).
Select("id").
Where("deleted_at = ?", 0).
Pluck("id", &ids).Error
2026-01-15 13:51:44 +08:00
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
}
2026-01-19 20:21:09 +08:00
// CreateWorkTechStack 创建作品技术栈
func CreateWorkTechStack(workID string, techStack []map[string]interface{}) error {
// 先删除旧的技术栈(软删除)
err := config.DB.Model(&models.WorkTechStack{}).
Where("work_id = ?", workID).
Update("deleted_at", time.Now().Unix()).Error
if err != nil {
log.Printf("Error deleting old tech stack: %v", err)
}
// 创建新的技术栈
for _, categoryData := range techStack {
category, ok := categoryData["category"].(string)
if !ok {
continue
}
items, ok := categoryData["items"].([]interface{})
if !ok {
continue
}
for _, item := range items {
itemStr, ok := item.(string)
if !ok || itemStr == "" {
continue
}
techStackItem := models.WorkTechStack{
WorkID: workID,
Category: category,
Item: itemStr,
CreatedAt: time.Now().Unix(),
DeletedAt: 0,
}
if err := config.DB.Create(&techStackItem).Error; err != nil {
log.Printf("Error creating tech stack item: %v", err)
return err
}
}
}
return nil
}
// CreateWorkGallery 创建作品图库
func CreateWorkGallery(workID string, gallery []string) error {
// 先删除旧的图库(软删除)
err := config.DB.Model(&models.WorkGallery{}).
Where("work_id = ?", workID).
Update("deleted_at", time.Now().Unix()).Error
if err != nil {
log.Printf("Error deleting old gallery: %v", err)
}
// 创建新的图库
for index, imageURL := range gallery {
if imageURL == "" {
continue
}
galleryItem := models.WorkGallery{
WorkID: workID,
ImageURL: imageURL,
SortOrder: uint(index + 1),
Description: "",
CreatedAt: time.Now().Unix(),
DeletedAt: 0,
}
if err := config.DB.Create(&galleryItem).Error; err != nil {
log.Printf("Error creating gallery item: %v", err)
return err
}
}
return nil
}
2026-01-15 13:51:44 +08:00
// CreateWork 创建作品
func CreateWork(work *models.Work) error {
2026-01-19 13:53:32 +08:00
err := config.DB.Create(work).Error
2026-01-15 13:51:44 +08:00
if err != nil {
log.Printf("Error creating work: %v", err)
return err
}
return nil
}
// UpdateWork 更新作品
func UpdateWork(work *models.Work) error {
2026-01-19 20:21:09 +08:00
updateData := 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(),
}
if work.Links != "" {
updateData["links"] = work.Links
}
2026-01-19 13:53:32 +08:00
err := config.DB.Model(&models.Work{}).
Where("id = ? AND deleted_at = ?", work.ID, 0).
2026-01-19 20:21:09 +08:00
Updates(updateData).Error
2026-01-15 13:51:44 +08:00
if err != nil {
log.Printf("Error updating work: %v", err)
return err
}
return nil
}
2026-01-16 13:01:21 +08:00
// DeleteWork 删除作品 (Soft Delete)
2026-01-15 13:51:44 +08:00
func DeleteWork(id string) error {
2026-01-19 13:53:32 +08:00
err := config.DB.Model(&models.Work{}).
Where("id = ?", id).
Update("deleted_at", time.Now().Unix()).Error
2026-01-15 13:51:44 +08:00
if err != nil {
log.Printf("Error deleting work: %v", err)
return err
}
return nil
}
2026-01-16 17:03:34 +08:00
// GetAdminWorks 获取后台作品列表 (分页)
func GetAdminWorks(page, pageSize int) ([]models.Work, int, error) {
offset := (page - 1) * pageSize
2026-01-19 13:53:32 +08:00
var works []models.Work
var total int64
2026-01-16 17:03:34 +08:00
// 获取总数
2026-01-19 13:53:32 +08:00
err := config.DB.Model(&models.Work{}).
Where("deleted_at = ?", 0).
Count(&total).Error
2026-01-16 17:03:34 +08:00
if err != nil {
log.Printf("Error getting work count: %v", err)
return nil, 0, err
}
2026-01-19 13:53:32 +08:00
// 获取列表
err = config.DB.Model(&models.Work{}).
Where("deleted_at = ?", 0).
Order("created_at DESC").
Limit(pageSize).
Offset(offset).
Find(&works).Error
2026-01-16 17:03:34 +08:00
if err != nil {
log.Printf("Error querying admin works: %v", err)
return nil, 0, err
}
2026-01-19 13:53:32 +08:00
return works, int(total), nil
2026-01-16 17:03:34 +08:00
}
// 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
}
2026-01-15 13:51:44 +08:00
// GetWorkCount 获取作品总数
func GetWorkCount() (int, error) {
2026-01-19 13:53:32 +08:00
var count int64
err := config.DB.Model(&models.Work{}).
Where("deleted_at = ?", 0).
Count(&count).Error
2026-01-15 13:51:44 +08:00
if err != nil {
log.Printf("Error getting work count: %v", err)
return 0, err
}
2026-01-19 13:53:32 +08:00
return int(count), nil
2026-01-15 13:51:44 +08:00
}