package repository import ( "with_you/internal/dto" "with_you/internal/model" "with_you/internal/pkg/utils" "gorm.io/gorm" ) // MaterialSubjectRepository 学科分类仓储接口 type MaterialSubjectRepository interface { ListActive() ([]*model.MaterialSubject, error) ListAll() ([]*model.MaterialSubject, error) GetByID(id string) (*model.MaterialSubject, error) Create(subject *model.MaterialSubject) error Update(subject *model.MaterialSubject) error Delete(id string) error CountMaterials(subjectID string) (int64, error) } // 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 interface { List(params dto.MaterialFileQueryParams) ([]*model.MaterialFile, int64, error) GetByID(id string) (*model.MaterialFile, error) GetByIDWithSubject(id string) (*model.MaterialFile, error) Create(file *model.MaterialFile) error Update(file *model.MaterialFile) error Delete(id string) error IncrementDownloadCount(id string) error GetBySubjectID(subjectID string, page, pageSize int) ([]*model.MaterialFile, int64, error) Search(keyword string, page, pageSize int) ([]*model.MaterialFile, int64, error) GetHotMaterials(limit int) ([]*model.MaterialFile, error) GetLatestMaterials(limit int) ([]*model.MaterialFile, error) } // materialFileRepository 文件资料仓储实现 type materialFileRepository struct { db *gorm.DB } func NewMaterialFileRepository(db *gorm.DB) MaterialFileRepository { return &materialFileRepository{db: db} } // List 获取资料列表(支持筛选和分页) func (r *materialFileRepository) List(params dto.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 := "%" + utils.EscapeLikeWildcard(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 := "%" + utils.EscapeLikeWildcard(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 }