package service import ( "errors" "github.com/gouki/lunar-server/internal/config" "github.com/gouki/lunar-server/internal/model" "gorm.io/gorm" ) // WikiService 百科服务 type WikiService struct { db *gorm.DB } // NewWikiService 创建百科服务 func NewWikiService() *WikiService { return &WikiService{db: config.GetDB()} } // ListEntries 百科条目列表(status<0 表示不过滤状态,供管理后台使用) func (s *WikiService) ListEntries(category, keyword string, status int) ([]*model.WikiEntry, error) { query := s.db.Model(&model.WikiEntry{}) if status >= 0 { query = query.Where("status = ?", status) } if category != "" { query = query.Where("category = ?", category) } if keyword != "" { like := "%" + keyword + "%" query = query.Where("title LIKE ? OR brief LIKE ? OR content LIKE ?", like, like, like) } var entries []*model.WikiEntry if err := query.Order("sort ASC, id ASC").Find(&entries).Error; err != nil { return nil, err } return entries, nil } // CreateEntry 新增百科条目 func (s *WikiService) CreateEntry(entry *model.WikiEntry) error { if entry.Category == "" || entry.Title == "" { return errors.New("分类和标题不能为空") } if entry.Status == 0 { entry.Status = 1 } return s.db.Create(entry).Error } // UpdateEntry 更新百科条目 func (s *WikiService) UpdateEntry(id uint, entry *model.WikiEntry) error { var existing model.WikiEntry if err := s.db.First(&existing, id).Error; err != nil { return err } return s.db.Model(&existing).Updates(map[string]interface{}{ "category": entry.Category, "title": entry.Title, "brief": entry.Brief, "content": entry.Content, "sort": entry.Sort, "status": entry.Status, }).Error } // DeleteEntry 删除百科条目 func (s *WikiService) DeleteEntry(id uint) error { return s.db.Delete(&model.WikiEntry{}, id).Error } // OnThisDayResult 某一天的历史数据 type OnThisDayResult struct { Events []model.WikiOnThisDay `json:"events"` Births []model.WikiOnThisDay `json:"births"` Deaths []model.WikiOnThisDay `json:"deaths"` Festivals []model.WikiOnThisDay `json:"festivals"` } // GetOnThisDay 查询某一天的历史上的今天数据(各板块限量返回) func (s *WikiService) GetOnThisDay(month, day int) (*OnThisDayResult, error) { if month < 1 || month > 12 || day < 1 || day > 31 { return nil, errors.New("日期参数无效") } var all []model.WikiOnThisDay if err := s.db.Where("month = ? AND day = ? AND status = 1", month, day). Order("year ASC, id ASC"). Find(&all).Error; err != nil { return nil, err } result := &OnThisDayResult{ Events: make([]model.WikiOnThisDay, 0), Births: make([]model.WikiOnThisDay, 0), Deaths: make([]model.WikiOnThisDay, 0), Festivals: make([]model.WikiOnThisDay, 0), } limits := map[string]int{"event": 20, "birth": 15, "death": 10, "festival": 10} for _, item := range all { switch item.Kind { case "event": if len(result.Events) < limits["event"] { result.Events = append(result.Events, item) } case "birth": if len(result.Births) < limits["birth"] { result.Births = append(result.Births, item) } case "death": if len(result.Deaths) < limits["death"] { result.Deaths = append(result.Deaths, item) } case "festival": if len(result.Festivals) < limits["festival"] { result.Festivals = append(result.Festivals, item) } } } return result, nil } // SyncStatus 同步状态(管理后台展示) type SyncStatus struct { Running bool `json:"running"` TotalDays int64 `json:"totalDays"` // 已覆盖的天数 TotalItems int64 `json:"totalItems"` // 总条目数 LastSync *model.WikiSyncLog `json:"lastSync"` } // GetSyncStatus 获取同步状态 func (s *WikiService) GetSyncStatus(running bool) (*SyncStatus, error) { status := &SyncStatus{Running: running} var totalDays int64 s.db.Model(&model.WikiOnThisDay{}).Where("status = 1"). Select("COUNT(DISTINCT month, day) AS c").Scan(&totalDays) status.TotalDays = totalDays s.db.Model(&model.WikiOnThisDay{}).Where("status = 1").Count(&status.TotalItems) var lastSync model.WikiSyncLog if err := s.db.Order("id DESC").First(&lastSync).Error; err == nil { status.LastSync = &lastSync } return status, nil }