package announcement import ( "time" "hfb_sys/backend/internal/model" "gorm.io/gorm" ) type Repository struct { db *gorm.DB } func NewRepository(db *gorm.DB) *Repository { return &Repository{db: db} } // List 获取公告列表(前台用户) func (r *Repository) List(query AnnouncementListQuery) (*PaginatedResult, error) { var total int64 tx := r.db.Model(&model.Announcement{}).Where("status = ?", "published") if query.Category != "" { tx = tx.Where("category = ?", query.Category) } if err := tx.Count(&total).Error; err != nil { return nil, err } offset := (query.Page - 1) * query.PageSize var rows []model.Announcement if err := tx.Order("is_pinned DESC, priority DESC, published_at DESC"). Offset(offset). Limit(query.PageSize). Find(&rows).Error; err != nil { return nil, err } items := make([]AnnouncementDTO, 0, len(rows)) for _, row := range rows { items = append(items, toAnnouncementDTO(row)) } return &PaginatedResult{ Items: items, Total: total, Page: query.Page, PageSize: query.PageSize, }, nil } // GetByID 获取公告详情 func (r *Repository) GetByID(id uint64) (*AnnouncementDTO, error) { var announcement model.Announcement if err := r.db.Where("id = ? AND status = ?", id, "published").First(&announcement).Error; err != nil { return nil, err } // 增加查看次数 r.db.Model(&model.Announcement{}).Where("id = ?", id).UpdateColumn("view_count", gorm.Expr("view_count + ?", 1)) dto := toAnnouncementDTO(announcement) return &dto, nil } // AdminList 管理员获取公告列表 func (r *Repository) AdminList(query AnnouncementListQuery) (*PaginatedResult, error) { var total int64 tx := r.db.Model(&model.Announcement{}) if query.Status != "" { tx = tx.Where("status = ?", query.Status) } if query.Category != "" { tx = tx.Where("category = ?", query.Category) } if err := tx.Count(&total).Error; err != nil { return nil, err } offset := (query.Page - 1) * query.PageSize var rows []model.Announcement if err := tx.Order("is_pinned DESC, priority DESC, id DESC"). Offset(offset). Limit(query.PageSize). Find(&rows).Error; err != nil { return nil, err } items := make([]AnnouncementDTO, 0, len(rows)) for _, row := range rows { items = append(items, toAnnouncementDTO(row)) } return &PaginatedResult{ Items: items, Total: total, Page: query.Page, PageSize: query.PageSize, }, nil } // AdminGetByID 管理员获取公告详情 func (r *Repository) AdminGetByID(id uint64) (*AnnouncementDTO, error) { var announcement model.Announcement if err := r.db.Where("id = ?", id).First(&announcement).Error; err != nil { return nil, err } dto := toAnnouncementDTO(announcement) return &dto, nil } // Create 创建公告 func (r *Repository) Create(req CreateAnnouncementRequest, createdBy uint64) (*AnnouncementDTO, error) { announcement := model.Announcement{ Title: req.Title, Content: req.Content, Category: req.Category, Priority: req.Priority, IsPinned: req.IsPinned, IsImportant: req.IsImportant, Status: "draft", CreatedBy: &createdBy, } if err := r.db.Create(&announcement).Error; err != nil { return nil, err } dto := toAnnouncementDTO(announcement) return &dto, nil } // Update 更新公告 func (r *Repository) Update(id uint64, req UpdateAnnouncementRequest) (*AnnouncementDTO, error) { updates := make(map[string]interface{}) if req.Title != "" { updates["title"] = req.Title } if req.Content != "" { updates["content"] = req.Content } if req.Category != "" { updates["category"] = req.Category } updates["priority"] = req.Priority updates["is_pinned"] = req.IsPinned updates["is_important"] = req.IsImportant if err := r.db.Model(&model.Announcement{}).Where("id = ?", id).Updates(updates).Error; err != nil { return nil, err } return r.AdminGetByID(id) } // Publish 发布公告 func (r *Repository) Publish(id uint64) error { now := time.Now() return r.db.Model(&model.Announcement{}). Where("id = ?", id). Updates(map[string]interface{}{ "status": "published", "published_at": now, }).Error } // Archive 归档公告 func (r *Repository) Archive(id uint64) error { return r.db.Model(&model.Announcement{}). Where("id = ?", id). Update("status", "archived").Error } // Delete 删除公告 func (r *Repository) Delete(id uint64) error { return r.db.Where("id = ?", id).Delete(&model.Announcement{}).Error } func toAnnouncementDTO(a model.Announcement) AnnouncementDTO { return AnnouncementDTO{ ID: a.ID, Title: a.Title, Content: a.Content, Category: a.Category, Priority: a.Priority, IsPinned: a.IsPinned, IsImportant: a.IsImportant, ViewCount: a.ViewCount, Status: a.Status, PublishedAt: a.PublishedAt, CreatedAt: a.CreatedAt, UpdatedAt: a.UpdatedAt, } }