refactor(dto, repository): standardize pagination field names and update moderation status handling
Some checks failed
Build Backend / build (push) Successful in 12m39s
Build Backend / build-docker (push) Failing after 2m0s

- Changed JSON field names from "items" to "list" in various cursor pagination response DTOs for consistency.
- Updated moderation status update methods in CommentRepository and PostRepository to use UpdateColumn for better clarity and to ensure that moderation actions do not affect content update timestamps.
This commit is contained in:
lafay
2026-03-23 01:06:41 +08:00
parent fa68f101de
commit 9d546b9989
3 changed files with 26 additions and 18 deletions

View File

@@ -530,7 +530,7 @@ type SystemUnreadCountResponse struct {
// SystemMessageCursorPageResponse 系统消息游标分页响应 // SystemMessageCursorPageResponse 系统消息游标分页响应
type SystemMessageCursorPageResponse struct { type SystemMessageCursorPageResponse struct {
Items []*SystemMessageResponse `json:"items"` Items []*SystemMessageResponse `json:"list"`
NextCursor string `json:"next_cursor"` NextCursor string `json:"next_cursor"`
PrevCursor string `json:"prev_cursor"` PrevCursor string `json:"prev_cursor"`
HasMore bool `json:"has_more"` HasMore bool `json:"has_more"`
@@ -1201,7 +1201,7 @@ type CursorPageRequest struct {
// 注意:由于 Go 的限制,这里使用 interface{} 作为 Items 类型 // 注意:由于 Go 的限制,这里使用 interface{} 作为 Items 类型
// 实际使用时可以创建特定类型的响应结构体 // 实际使用时可以创建特定类型的响应结构体
type CursorPageResponse struct { type CursorPageResponse struct {
Items interface{} `json:"items"` Items interface{} `json:"list"`
NextCursor string `json:"next_cursor,omitempty"` // 下一页游标 NextCursor string `json:"next_cursor,omitempty"` // 下一页游标
PrevCursor string `json:"prev_cursor,omitempty"` // 上一页游标(可选) PrevCursor string `json:"prev_cursor,omitempty"` // 上一页游标(可选)
HasMore bool `json:"has_more"` // 是否有更多数据 HasMore bool `json:"has_more"` // 是否有更多数据
@@ -1215,7 +1215,7 @@ type CursorPageMeta struct {
// PostCursorPageResponse 帖子游标分页响应 // PostCursorPageResponse 帖子游标分页响应
type PostCursorPageResponse struct { type PostCursorPageResponse struct {
Items []*PostResponse `json:"items"` Items []*PostResponse `json:"list"`
NextCursor string `json:"next_cursor,omitempty"` NextCursor string `json:"next_cursor,omitempty"`
PrevCursor string `json:"prev_cursor,omitempty"` PrevCursor string `json:"prev_cursor,omitempty"`
HasMore bool `json:"has_more"` HasMore bool `json:"has_more"`
@@ -1223,7 +1223,7 @@ type PostCursorPageResponse struct {
// CommentCursorPageResponse 评论游标分页响应 // CommentCursorPageResponse 评论游标分页响应
type CommentCursorPageResponse struct { type CommentCursorPageResponse struct {
Items []*CommentResponse `json:"items"` Items []*CommentResponse `json:"list"`
NextCursor string `json:"next_cursor,omitempty"` NextCursor string `json:"next_cursor,omitempty"`
PrevCursor string `json:"prev_cursor,omitempty"` PrevCursor string `json:"prev_cursor,omitempty"`
HasMore bool `json:"has_more"` HasMore bool `json:"has_more"`
@@ -1231,7 +1231,7 @@ type CommentCursorPageResponse struct {
// MessageCursorPageResponse 消息游标分页响应 // MessageCursorPageResponse 消息游标分页响应
type MessageCursorPageResponse struct { type MessageCursorPageResponse struct {
Items []*MessageResponse `json:"items"` Items []*MessageResponse `json:"list"`
NextCursor string `json:"next_cursor,omitempty"` NextCursor string `json:"next_cursor,omitempty"`
PrevCursor string `json:"prev_cursor,omitempty"` PrevCursor string `json:"prev_cursor,omitempty"`
HasMore bool `json:"has_more"` HasMore bool `json:"has_more"`
@@ -1239,7 +1239,7 @@ type MessageCursorPageResponse struct {
// ConversationCursorPageResponse 会话游标分页响应 // ConversationCursorPageResponse 会话游标分页响应
type ConversationCursorPageResponse struct { type ConversationCursorPageResponse struct {
Items []*ConversationResponse `json:"items"` Items []*ConversationResponse `json:"list"`
NextCursor string `json:"next_cursor,omitempty"` NextCursor string `json:"next_cursor,omitempty"`
PrevCursor string `json:"prev_cursor,omitempty"` PrevCursor string `json:"prev_cursor,omitempty"`
HasMore bool `json:"has_more"` HasMore bool `json:"has_more"`
@@ -1247,7 +1247,7 @@ type ConversationCursorPageResponse struct {
// GroupCursorPageResponse 群组游标分页响应 // GroupCursorPageResponse 群组游标分页响应
type GroupCursorPageResponse struct { type GroupCursorPageResponse struct {
Items []*GroupResponse `json:"items"` Items []*GroupResponse `json:"list"`
NextCursor string `json:"next_cursor,omitempty"` NextCursor string `json:"next_cursor,omitempty"`
PrevCursor string `json:"prev_cursor,omitempty"` PrevCursor string `json:"prev_cursor,omitempty"`
HasMore bool `json:"has_more"` HasMore bool `json:"has_more"`
@@ -1255,7 +1255,7 @@ type GroupCursorPageResponse struct {
// NotificationCursorPageResponse 通知游标分页响应 // NotificationCursorPageResponse 通知游标分页响应
type NotificationCursorPageResponse struct { type NotificationCursorPageResponse struct {
Items []*NotificationResponse `json:"items"` Items []*NotificationResponse `json:"list"`
NextCursor string `json:"next_cursor,omitempty"` NextCursor string `json:"next_cursor,omitempty"`
PrevCursor string `json:"prev_cursor,omitempty"` PrevCursor string `json:"prev_cursor,omitempty"`
HasMore bool `json:"has_more"` HasMore bool `json:"has_more"`
@@ -1263,7 +1263,7 @@ type NotificationCursorPageResponse struct {
// GroupMemberCursorPageResponse 群成员游标分页响应 // GroupMemberCursorPageResponse 群成员游标分页响应
type GroupMemberCursorPageResponse struct { type GroupMemberCursorPageResponse struct {
Items []*GroupMemberResponse `json:"items"` Items []*GroupMemberResponse `json:"list"`
NextCursor string `json:"next_cursor,omitempty"` NextCursor string `json:"next_cursor,omitempty"`
PrevCursor string `json:"prev_cursor,omitempty"` PrevCursor string `json:"prev_cursor,omitempty"`
HasMore bool `json:"has_more"` HasMore bool `json:"has_more"`
@@ -1271,7 +1271,7 @@ type GroupMemberCursorPageResponse struct {
// GroupAnnouncementCursorPageResponse 群公告游标分页响应 // GroupAnnouncementCursorPageResponse 群公告游标分页响应
type GroupAnnouncementCursorPageResponse struct { type GroupAnnouncementCursorPageResponse struct {
Items []*GroupAnnouncementResponse `json:"items"` Items []*GroupAnnouncementResponse `json:"list"`
NextCursor string `json:"next_cursor,omitempty"` NextCursor string `json:"next_cursor,omitempty"`
PrevCursor string `json:"prev_cursor,omitempty"` PrevCursor string `json:"prev_cursor,omitempty"`
HasMore bool `json:"has_more"` HasMore bool `json:"has_more"`

View File

@@ -40,9 +40,10 @@ func (r *CommentRepository) Update(comment *model.Comment) error {
// UpdateModerationStatus 更新评论审核状态 // UpdateModerationStatus 更新评论审核状态
func (r *CommentRepository) UpdateModerationStatus(commentID string, status model.CommentStatus) error { func (r *CommentRepository) UpdateModerationStatus(commentID string, status model.CommentStatus) error {
// 审核状态更新属于管理操作不应影响评论内容更新时间updated_at
return r.db.Model(&model.Comment{}). return r.db.Model(&model.Comment{}).
Where("id = ?", commentID). Where("id = ?", commentID).
Update("status", status).Error UpdateColumn("status", status).Error
} }
// Delete 删除评论(软删除,同时清理关联数据) // Delete 删除评论(软删除,同时清理关联数据)
@@ -67,8 +68,9 @@ func (r *CommentRepository) Delete(id string) error {
// 仅已发布评论才参与统计,避免 pending/rejected 影响计数 // 仅已发布评论才参与统计,避免 pending/rejected 影响计数
if comment.Status == model.CommentStatusPublished { if comment.Status == model.CommentStatusPublished {
// 减少帖子的评论数并同步热度分 // 减少帖子的评论数并同步热度分
// 评论数属于统计字段不应影响帖子内容更新时间updated_at
if err := tx.Model(&model.Post{}).Where("id = ?", comment.PostID). if err := tx.Model(&model.Post{}).Where("id = ?", comment.PostID).
Updates(map[string]interface{}{ UpdateColumns(map[string]interface{}{
"comments_count": gorm.Expr("comments_count - 1"), "comments_count": gorm.Expr("comments_count - 1"),
"hot_score": gorm.Expr("likes_count * 2 + (comments_count - 1) * 3 + views_count * 0.1"), "hot_score": gorm.Expr("likes_count * 2 + (comments_count - 1) * 3 + views_count * 0.1"),
}).Error; err != nil { }).Error; err != nil {
@@ -95,8 +97,9 @@ func (r *CommentRepository) ApplyPublishedStats(comment *model.Comment) error {
} }
return r.db.Transaction(func(tx *gorm.DB) error { return r.db.Transaction(func(tx *gorm.DB) error {
// 增加帖子的评论数并同步热度分 // 增加帖子的评论数并同步热度分
// 评论数属于统计字段不应影响帖子内容更新时间updated_at
if err := tx.Model(&model.Post{}).Where("id = ?", comment.PostID). if err := tx.Model(&model.Post{}).Where("id = ?", comment.PostID).
Updates(map[string]interface{}{ UpdateColumns(map[string]any{
"comments_count": gorm.Expr("comments_count + 1"), "comments_count": gorm.Expr("comments_count + 1"),
"hot_score": gorm.Expr("likes_count * 2 + (comments_count + 1) * 3 + views_count * 0.1"), "hot_score": gorm.Expr("likes_count * 2 + (comments_count + 1) * 3 + views_count * 0.1"),
}).Error; err != nil { }).Error; err != nil {

View File

@@ -114,13 +114,14 @@ func (r *PostRepository) UpdateWithImages(post *model.Post, images *[]string) er
// UpdateModerationStatus 更新帖子审核状态 // UpdateModerationStatus 更新帖子审核状态
func (r *PostRepository) UpdateModerationStatus(postID string, status model.PostStatus, rejectReason string, reviewedBy string) error { func (r *PostRepository) UpdateModerationStatus(postID string, status model.PostStatus, rejectReason string, reviewedBy string) error {
// 审核状态更新属于管理操作不应影响帖子内容更新时间updated_at
updates := map[string]interface{}{ updates := map[string]interface{}{
"status": status, "status": status,
"reviewed_at": gorm.Expr("CURRENT_TIMESTAMP"), "reviewed_at": gorm.Expr("CURRENT_TIMESTAMP"),
"reviewed_by": reviewedBy, "reviewed_by": reviewedBy,
"reject_reason": rejectReason, "reject_reason": rejectReason,
} }
return r.db.Model(&model.Post{}).Where("id = ?", postID).Updates(updates).Error return r.db.Model(&model.Post{}).Where("id = ?", postID).UpdateColumns(updates).Error
} }
// Delete 删除帖子(软删除,同时清理关联数据) // Delete 删除帖子(软删除,同时清理关联数据)
@@ -252,8 +253,9 @@ func (r *PostRepository) Like(postID, userID string) error {
} }
// 增加帖子点赞数并同步热度分 // 增加帖子点赞数并同步热度分
// 点赞属于统计字段更新不应影响帖子内容更新时间updated_at
return tx.Model(&model.Post{}).Where("id = ?", postID). return tx.Model(&model.Post{}).Where("id = ?", postID).
Updates(map[string]interface{}{ UpdateColumns(map[string]any{
"likes_count": gorm.Expr("likes_count + 1"), "likes_count": gorm.Expr("likes_count + 1"),
"hot_score": gorm.Expr("(likes_count + 1) * 2 + comments_count * 3 + views_count * 0.1"), "hot_score": gorm.Expr("(likes_count + 1) * 2 + comments_count * 3 + views_count * 0.1"),
}).Error }).Error
@@ -269,8 +271,9 @@ func (r *PostRepository) Unlike(postID, userID string) error {
} }
if result.RowsAffected > 0 { if result.RowsAffected > 0 {
// 减少帖子点赞数并同步热度分 // 减少帖子点赞数并同步热度分
// 取消点赞属于统计字段更新不应影响帖子内容更新时间updated_at
return tx.Model(&model.Post{}).Where("id = ?", postID). return tx.Model(&model.Post{}).Where("id = ?", postID).
Updates(map[string]interface{}{ UpdateColumns(map[string]any{
"likes_count": gorm.Expr("likes_count - 1"), "likes_count": gorm.Expr("likes_count - 1"),
"hot_score": gorm.Expr("(likes_count - 1) * 2 + comments_count * 3 + views_count * 0.1"), "hot_score": gorm.Expr("(likes_count - 1) * 2 + comments_count * 3 + views_count * 0.1"),
}).Error }).Error
@@ -701,14 +704,16 @@ func (r *PostRepository) BatchUpdateStatus(ids []string, status model.PostStatus
// UpdatePinStatus 更新帖子置顶状态 // UpdatePinStatus 更新帖子置顶状态
func (r *PostRepository) UpdatePinStatus(postID string, isPinned bool) error { func (r *PostRepository) UpdatePinStatus(postID string, isPinned bool) error {
// 置顶状态属于管理操作不应影响帖子内容更新时间updated_at
return r.db.Model(&model.Post{}).Where("id = ?", postID). return r.db.Model(&model.Post{}).Where("id = ?", postID).
Update("is_pinned", isPinned).Error UpdateColumn("is_pinned", isPinned).Error
} }
// UpdateFeatureStatus 更新帖子加精状态 // UpdateFeatureStatus 更新帖子加精状态
func (r *PostRepository) UpdateFeatureStatus(postID string, isFeatured bool) error { func (r *PostRepository) UpdateFeatureStatus(postID string, isFeatured bool) error {
// 加精状态属于管理操作不应影响帖子内容更新时间updated_at
return r.db.Model(&model.Post{}).Where("id = ?", postID). return r.db.Model(&model.Post{}).Where("id = ?", postID).
Update("is_featured", isFeatured).Error UpdateColumn("is_featured", isFeatured).Error
} }
// ========== Cursor Pagination Methods ========== // ========== Cursor Pagination Methods ==========