Files
backend/internal/repository/material_repo.go
lafay 0ef8e5a7e1
Some checks failed
Build Backend / build (push) Failing after 12m1s
Build Backend / build-docker (push) Has been skipped
feat(material): add material handling and routing functionality
- Introduced MaterialHandler for managing learning materials and subjects.
- Updated router to include routes for public and admin material management.
- Enhanced database initialization with material subject and file models.
- Implemented seeding logic for material subjects and files.
- Updated wire generation to include MaterialHandler and related services.
2026-03-25 20:44:12 +08:00

247 lines
6.7 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 repository
import (
"carrot_bbs/internal/model"
"gorm.io/gorm"
)
// MaterialSubjectRepository 学科分类仓储
type MaterialSubjectRepository struct {
db *gorm.DB
}
func NewMaterialSubjectRepository(db *gorm.DB) *MaterialSubjectRepository {
return &MaterialSubjectRepository{db: db}
}
// ListActive 获取所有启用的学科分类
func (r *MaterialSubjectRepository) ListActive() ([]*model.MaterialSubject, error) {
var subjects []*model.MaterialSubject
err := r.db.
Where("is_active = ?", true).
Order("sort_order ASC, created_at ASC").
Find(&subjects).Error
return subjects, err
}
// ListAll 获取所有学科分类(管理端用)
func (r *MaterialSubjectRepository) ListAll() ([]*model.MaterialSubject, error) {
var subjects []*model.MaterialSubject
err := r.db.
Order("sort_order ASC, created_at ASC").
Find(&subjects).Error
return subjects, err
}
// GetByID 根据ID获取学科分类
func (r *MaterialSubjectRepository) GetByID(id string) (*model.MaterialSubject, error) {
var subject model.MaterialSubject
if err := r.db.First(&subject, "id = ?", id).Error; err != nil {
return nil, err
}
return &subject, nil
}
// Create 创建学科分类
func (r *MaterialSubjectRepository) Create(subject *model.MaterialSubject) error {
return r.db.Create(subject).Error
}
// Update 更新学科分类
func (r *MaterialSubjectRepository) Update(subject *model.MaterialSubject) error {
return r.db.Save(subject).Error
}
// Delete 删除学科分类
func (r *MaterialSubjectRepository) Delete(id string) error {
return r.db.Delete(&model.MaterialSubject{}, "id = ?", id).Error
}
// CountMaterials 统计学科下的资料数量
func (r *MaterialSubjectRepository) CountMaterials(subjectID string) (int64, error) {
var count int64
err := r.db.Model(&model.MaterialFile{}).Where("subject_id = ?", subjectID).Count(&count).Error
return count, err
}
// MaterialFileRepository 文件资料仓储
type MaterialFileRepository struct {
db *gorm.DB
}
func NewMaterialFileRepository(db *gorm.DB) *MaterialFileRepository {
return &MaterialFileRepository{db: db}
}
// ListQueryParams 查询参数
type MaterialFileQueryParams struct {
SubjectID string
FileType string
Status string
Keyword string
Page int
PageSize int
SortBy string
SortOrder string
}
// List 获取资料列表(支持筛选和分页)
func (r *MaterialFileRepository) List(params MaterialFileQueryParams) ([]*model.MaterialFile, int64, error) {
var files []*model.MaterialFile
var total int64
query := r.db.Model(&model.MaterialFile{})
// 筛选条件
if params.SubjectID != "" {
query = query.Where("subject_id = ?", params.SubjectID)
}
if params.FileType != "" {
query = query.Where("file_type = ?", params.FileType)
}
if params.Status != "" {
query = query.Where("status = ?", params.Status)
}
if params.Keyword != "" {
keyword := "%" + params.Keyword + "%"
query = query.Where("title LIKE ? OR description LIKE ?", keyword, keyword)
}
// 统计总数
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// 排序
sortBy := params.SortBy
if sortBy == "" {
sortBy = "created_at"
}
sortOrder := params.SortOrder
if sortOrder == "" {
sortOrder = "DESC"
}
orderClause := sortBy + " " + sortOrder
// 分页
page := params.Page
if page < 1 {
page = 1
}
pageSize := params.PageSize
if pageSize < 1 {
pageSize = 20
}
offset := (page - 1) * pageSize
// 查询
if err := query.Order(orderClause).Offset(offset).Limit(pageSize).Find(&files).Error; err != nil {
return nil, 0, err
}
return files, total, nil
}
// GetByID 根据ID获取资料详情
func (r *MaterialFileRepository) GetByID(id string) (*model.MaterialFile, error) {
var file model.MaterialFile
if err := r.db.First(&file, "id = ?", id).Error; err != nil {
return nil, err
}
return &file, nil
}
// GetByIDWithSubject 根据ID获取资料详情包含学科信息
func (r *MaterialFileRepository) GetByIDWithSubject(id string) (*model.MaterialFile, error) {
var file model.MaterialFile
if err := r.db.Preload("Subject").First(&file, "id = ?", id).Error; err != nil {
return nil, err
}
return &file, nil
}
// Create 创建资料
func (r *MaterialFileRepository) Create(file *model.MaterialFile) error {
return r.db.Create(file).Error
}
// Update 更新资料
func (r *MaterialFileRepository) Update(file *model.MaterialFile) error {
return r.db.Save(file).Error
}
// Delete 删除资料
func (r *MaterialFileRepository) Delete(id string) error {
return r.db.Delete(&model.MaterialFile{}, "id = ?", id).Error
}
// IncrementDownloadCount 增加下载次数
func (r *MaterialFileRepository) IncrementDownloadCount(id string) error {
return r.db.Model(&model.MaterialFile{}).Where("id = ?", id).
UpdateColumn("download_count", gorm.Expr("download_count + ?", 1)).Error
}
// GetBySubjectID 根据学科ID获取资料列表
func (r *MaterialFileRepository) GetBySubjectID(subjectID string, page, pageSize int) ([]*model.MaterialFile, int64, error) {
var files []*model.MaterialFile
var total int64
query := r.db.Model(&model.MaterialFile{}).Where("subject_id = ? AND status = ?", subjectID, model.MaterialStatusActive)
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
offset := (page - 1) * pageSize
if err := query.Order("created_at DESC").Offset(offset).Limit(pageSize).Find(&files).Error; err != nil {
return nil, 0, err
}
return files, total, nil
}
// Search 搜索资料
func (r *MaterialFileRepository) Search(keyword string, page, pageSize int) ([]*model.MaterialFile, int64, error) {
var files []*model.MaterialFile
var total int64
query := r.db.Model(&model.MaterialFile{}).Where("status = ?", model.MaterialStatusActive)
if keyword != "" {
kw := "%" + keyword + "%"
query = query.Where("title LIKE ? OR description LIKE ?", kw, kw)
}
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
offset := (page - 1) * pageSize
if err := query.Order("created_at DESC").Offset(offset).Limit(pageSize).Find(&files).Error; err != nil {
return nil, 0, err
}
return files, total, nil
}
// GetHotMaterials 获取热门资料(按下载次数排序)
func (r *MaterialFileRepository) GetHotMaterials(limit int) ([]*model.MaterialFile, error) {
var files []*model.MaterialFile
err := r.db.
Where("status = ?", model.MaterialStatusActive).
Order("download_count DESC").
Limit(limit).
Find(&files).Error
return files, err
}
// GetLatestMaterials 获取最新资料
func (r *MaterialFileRepository) GetLatestMaterials(limit int) ([]*model.MaterialFile, error) {
var files []*model.MaterialFile
err := r.db.
Where("status = ?", model.MaterialStatusActive).
Order("created_at DESC").
Limit(limit).
Find(&files).Error
return files, err
}