fix: P0-08 cursor pagination sort consistency
Cursor pagination now only applies when sorting by created_at. Other sort fields (username, last_login_time, updated_at) will not use cursor pagination to prevent data inconsistency. Fixes: UserRepository.ListCursor() allowing sort fields that don't match the cursor predicate.
This commit is contained in:
@@ -381,14 +381,9 @@ func (r *UserRepository) ListCursor(ctx context.Context, filter *AdvancedFilter,
|
||||
}
|
||||
|
||||
// Apply cursor condition
|
||||
if cursor != nil && cursor.LastID > 0 {
|
||||
query = query.Where(
|
||||
"(created_at < ? OR (created_at = ? AND id < ?))",
|
||||
cursor.LastValue, cursor.LastValue, cursor.LastID,
|
||||
)
|
||||
}
|
||||
|
||||
// Determine sort field
|
||||
// 安全修复:游标分页必须与排序字段一致。
|
||||
// 如果排序字段不是 created_at,游标分页会返回错误结果。
|
||||
// 因此只有在按 created_at 排序时才允许使用游标。
|
||||
sortBy := "created_at"
|
||||
if filter.SortBy != "" {
|
||||
allowedFields := map[string]bool{
|
||||
@@ -399,6 +394,15 @@ func (r *UserRepository) ListCursor(ctx context.Context, filter *AdvancedFilter,
|
||||
sortBy = filter.SortBy
|
||||
}
|
||||
}
|
||||
|
||||
// 只有在按 created_at 排序时才应用游标条件
|
||||
if cursor != nil && cursor.LastID > 0 && sortBy == "created_at" {
|
||||
query = query.Where(
|
||||
"(created_at < ? OR (created_at = ? AND id < ?))",
|
||||
cursor.LastValue, cursor.LastValue, cursor.LastID,
|
||||
)
|
||||
}
|
||||
|
||||
sortOrder := "DESC"
|
||||
if filter.SortOrder == "asc" {
|
||||
sortOrder = "ASC"
|
||||
|
||||
Reference in New Issue
Block a user