补齐论坛核心能力:讨论锁定、发帖本地草稿、标签精确筛选,以及私信与通知分流。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -34,6 +34,7 @@ type PostListQuery struct {
|
||||
Page int
|
||||
Size int
|
||||
Keyword string
|
||||
Tag string // 精确标签筛选(整枚匹配,不走 keyword LIKE)
|
||||
Sort string // latest | reply | hot
|
||||
ViewerID uint // 当前查看者(用于 pending 仅作者可见)
|
||||
ViewerIsAdmin bool
|
||||
@@ -271,6 +272,12 @@ func (s *PostService) List(q PostListQuery) ([]model.Post, int64, error) {
|
||||
kw := "%" + q.Keyword + "%"
|
||||
db = db.Where("title LIKE ? OR content_plain LIKE ? OR tags LIKE ?", kw, kw, kw)
|
||||
}
|
||||
if tag := strings.TrimSpace(q.Tag); tag != "" {
|
||||
// 整枚标签匹配:逗号/中文逗号分隔,忽略标签两侧空格,大小写不敏感
|
||||
escaped := escapeLikePattern(strings.ToLower(tag))
|
||||
normalized := "LOWER(',' || REPLACE(REPLACE(REPLACE(IFNULL(tags,''), ',', ','), ', ', ','), ' ,', ',') || ',')"
|
||||
db = db.Where(normalized+" LIKE ? ESCAPE '\\'", "%,"+escaped+",%")
|
||||
}
|
||||
var total int64
|
||||
db.Count(&total)
|
||||
var posts []model.Post
|
||||
@@ -310,6 +317,14 @@ func normalizePostSort(sort string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// escapeLikePattern 转义 LIKE 通配符,配合 ESCAPE '\'
|
||||
func escapeLikePattern(s string) string {
|
||||
s = strings.ReplaceAll(s, `\`, `\\`)
|
||||
s = strings.ReplaceAll(s, `%`, `\%`)
|
||||
s = strings.ReplaceAll(s, `_`, `\_`)
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *PostService) FindByID(id uint) (*model.Post, error) {
|
||||
var post model.Post
|
||||
err := model.DB.Preload("User").Preload("Board").First(&post, id).Error
|
||||
@@ -535,6 +550,18 @@ func (s *PostService) SetEditLocked(postID uint, locked bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetCommentsLocked 锁定/解锁讨论(禁止新评论)
|
||||
func (s *PostService) SetCommentsLocked(postID uint, locked bool) error {
|
||||
res := model.DB.Model(&model.Post{}).Where("id = ?", postID).Update("comments_locked", locked)
|
||||
if res.Error != nil {
|
||||
return res.Error
|
||||
}
|
||||
if res.RowsAffected == 0 {
|
||||
return ErrPostNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PostService) ListRevisions(postID uint) ([]model.PostRevision, error) {
|
||||
var revs []model.PostRevision
|
||||
err := model.DB.Preload("Editor").Where("post_id = ?", postID).
|
||||
|
||||
Reference in New Issue
Block a user