This repository has been archived on 2026-06-21. You can view files and clone it, but cannot push or open issues or pull requests.
Files
MetaLab/internal/repository/post_repo.go
Victor_Jay 90d17ed4b1 feat: 管理后台待审稿件置顶优先显示
- FindAdminPageable 新增 pageResultsAdmin,使用 CASE WHEN 排序
- pending 和有 PendingBody 的 approved 帖子排在最前
- 其余帖子按创建时间倒序排在后面
2026-05-30 20:33:14 +08:00

151 lines
4.6 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 (
"metazone.cc/metalab/internal/model"
"gorm.io/gorm"
)
// PostRepo 帖子数据访问
type PostRepo struct {
db *gorm.DB
}
// NewPostRepo 构造函数
func NewPostRepo(db *gorm.DB) *PostRepo {
return &PostRepo{db: db}
}
// Create 创建帖子
func (r *PostRepo) Create(post *model.Post) error {
return r.db.Create(post).Error
}
// FindByID 按 ID 查找帖子
func (r *PostRepo) FindByID(id uint) (*model.Post, error) {
var post model.Post
err := r.db.First(&post, id).Error
if err != nil {
return nil, err
}
return &post, nil
}
// FindByIDWithAuthor 按 ID 查找帖子(含作者用户名)
func (r *PostRepo) FindByIDWithAuthor(id uint) (*model.Post, error) {
var post model.Post
err := r.db.Table("posts").
Select("posts.*, users.username as author_name").
Joins("LEFT JOIN users ON users.uid = posts.user_id").
Where("posts.id = ?", id).
First(&post).Error
if err != nil {
return nil, err
}
return &post, nil
}
// buildQuery 构建帖子查询公共部分(联表 + 未删除 + 关键词 + 可选状态过滤)
func (r *PostRepo) buildQuery(keyword, status string) *gorm.DB {
query := r.db.Table("posts").
Select("posts.*, users.username as author_name").
Joins("LEFT JOIN users ON users.uid = posts.user_id").
Where("posts.deleted_at IS NULL")
if keyword != "" {
like := "%" + keyword + "%"
query = query.Where("posts.title LIKE ?", like)
}
if status != "" {
query = query.Where("posts.status = ?", status)
}
return query
}
// FindPageable 分页查询帖子列表(仅 approved 状态,关键词模糊搜索标题)
func (r *PostRepo) FindPageable(keyword string, offset, limit int) ([]model.Post, int64, error) {
query := r.buildQuery(keyword, model.PostStatusApproved)
return r.pageResults(query, offset, limit)
}
// FindAdminPageable 管理后台分页查询(全状态筛选,待审置顶)
func (r *PostRepo) FindAdminPageable(keyword, status string, offset, limit int) ([]model.Post, int64, error) {
query := r.buildQuery(keyword, status)
return r.pageResultsAdmin(query, offset, limit)
}
// FindByUserID 分页查询某用户发布的帖子(仅 approved含作者用户名
func (r *PostRepo) FindByUserID(userID uint, offset, limit int) ([]model.Post, int64, error) {
query := r.buildQuery("", model.PostStatusApproved).
Where("posts.user_id = ?", userID)
return r.pageResults(query, offset, limit)
}
// FindByUserIDAndStatus 分页查询某用户指定状态的帖子(空 status=全状态)
func (r *PostRepo) FindByUserIDAndStatus(userID uint, status string, offset, limit int) ([]model.Post, int64, error) {
query := r.buildQuery("", status).
Where("posts.user_id = ?", userID)
return r.pageResults(query, offset, limit)
}
// FindPendingRevisions 查询有待审修订的帖子approved 且 pending_body 不为空)
func (r *PostRepo) FindPendingRevisions(keyword string, offset, limit int) ([]model.Post, int64, error) {
query := r.buildQuery(keyword, model.PostStatusApproved).
Where("posts.pending_body != ''")
return r.pageResults(query, offset, limit)
}
// pageResults 执行 Count + Offset/Limit + ORDER BY
func (r *PostRepo) pageResults(query *gorm.DB, offset, limit int) ([]model.Post, int64, error) {
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
var posts []model.Post
err := query.Order("posts.created_at DESC").
Offset(offset).Limit(limit).Find(&posts).Error
if err != nil {
return nil, 0, err
}
return posts, total, nil
}
// pageResultsAdmin 管理后台分页待审稿件pending 或 修订待审)置顶优先
func (r *PostRepo) pageResultsAdmin(query *gorm.DB, offset, limit int) ([]model.Post, int64, error) {
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
var posts []model.Post
err := query.Order(`CASE WHEN posts.status = 'pending' OR (posts.status = 'approved' AND posts.pending_body != '') THEN 0 ELSE 1 END ASC, posts.created_at DESC`).
Offset(offset).Limit(limit).Find(&posts).Error
if err != nil {
return nil, 0, err
}
return posts, total, nil
}
// Update 更新帖子
func (r *PostRepo) Update(post *model.Post) error {
return r.db.Save(post).Error
}
// SoftDelete 软删除帖子
func (r *PostRepo) SoftDelete(id uint) error {
return r.db.Delete(&model.Post{}, id).Error
}
// Restore 恢复软删除
func (r *PostRepo) Restore(id uint) error {
result := r.db.Unscoped().Model(&model.Post{}).Where("id = ?", id).Update("deleted_at", nil)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return gorm.ErrRecordNotFound
}
return nil
}