From 3c8cefbb2a119ba89394a6dda44f5249c0fd569d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 11 Nov 2026 17:49:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B9=BF=E5=91=8A=E7=B4=A0=E6=9D=90=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=8E=92=E5=BA=8F=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit advitise_info 增加 sort 字段,列表默认按 sort 从小到大排序。 info/list 增加 orderBy 参数: sortAsc(默认) / sortDesc / newest, 三种排序末尾都追加 _id 作为最后一级,避免同值文档在分页时重复或漏数据。 启动时回填历史数据缺失的 sort 字段: 缺字段的文档在升序里会排在 0 之前, 且按 sort=0 精确查询查不到。用 UpdateMMany 避免刷新全表 updatedAt。 Co-Authored-By: Claude Opus 5 --- api/proto/advitiseV2.go | 3 +++ models/advitiseInfoMod/advitise.go | 22 ++++++++++++++++- models/advitiseInfoMod/tag.go | 2 ++ models/advitiseInfoMod/type.go | 1 + service/advitiseV2Ser/info.go | 39 +++++++++++++++++++++++++++++- 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/api/proto/advitiseV2.go b/api/proto/advitiseV2.go index 4a92aa3..6409d42 100644 --- a/api/proto/advitiseV2.go +++ b/api/proto/advitiseV2.go @@ -14,6 +14,7 @@ type AdvitiseInfoListReq struct { Title string `json:"title" form:"title"` Remark string `json:"remark" form:"remark"` Status *bool `json:"status" form:"status"` + OrderBy string `json:"orderBy" form:"orderBy"` // 排序方式:sortAsc(默认,从小到大) / sortDesc(从大到小) / newest(最新) PageNum int64 `json:"pageNum" form:"pageNum" binding:"required,gte=1"` PageSize int64 `json:"pageSize" form:"pageSize" binding:"required,gte=1,lte=500"` } @@ -37,6 +38,7 @@ type AddAdvitiseInfoReq struct { RandomNames []string `json:"randomNames"` Link string `json:"link"` Status bool `json:"status"` + Sort int64 `json:"sort"` StartTime time.Time `json:"startTime"` EndTime time.Time `json:"endTime"` Remark string `json:"remark"` @@ -58,6 +60,7 @@ type UpdateAdvitiseInfoReq struct { RandomNames *[]string `json:"randomNames"` Link *string `json:"link"` Status *bool `json:"status"` + Sort *int64 `json:"sort"` StartTime *time.Time `json:"startTime"` EndTime *time.Time `json:"endTime"` Remark *string `json:"remark"` diff --git a/models/advitiseInfoMod/advitise.go b/models/advitiseInfoMod/advitise.go index 3a5fcd7..1030155 100644 --- a/models/advitiseInfoMod/advitise.go +++ b/models/advitiseInfoMod/advitise.go @@ -20,10 +20,31 @@ func Init(ctx context.Context) { {Key: FN.AdvitiseInfo.Status, Value: 1}, }}, {Keys: bson.D{{Key: FN.AdvitiseInfo.CreatedAt, Value: -1}}}, + {Keys: bson.D{ + {Key: FN.AdvitiseInfo.Sort, Value: 1}, + {Key: FN.AdvitiseInfo.CreatedAt, Value: -1}, + }}, } if _, err := db.CreateIndex(ctx, indexes); err != nil { panic(fmt.Sprintf("(advitiseInfoMod:Init) CreateIndex failed: %+v", err)) } + backfillSort(ctx) +} + +// backfillSort 给历史数据补 sort 字段。缺字段的文档在升序排序里会排在 0 之前, +// 且按 sort=0 精确查询查不到,所以启动时统一补 0。幂等,补完后不再命中。 +func backfillSort(ctx context.Context) { + ret, err := db.UpdateMMany(ctx, + bson.M{FN.AdvitiseInfo.Sort: bson.M{"$exists": false}}, + bson.M{"$set": bson.M{FN.AdvitiseInfo.Sort: int64(0)}}, + ) + if err != nil { + log.Warn("advitiseInfoMod backfill sort failed", log.E(err)) + return + } + if ret != nil && ret.ModifiedCount > 0 { + log.Info("advitiseInfoMod backfill sort done", log.Any("modified", ret.ModifiedCount)) + } } func InsertOneAdvitiseInfo(ctx context.Context, doc *AdvitiseInfo) error { @@ -76,4 +97,3 @@ func FindManyAdvitiseInfos(ctx context.Context, filter bson.M, opts ...*options. } return list, nil } - diff --git a/models/advitiseInfoMod/tag.go b/models/advitiseInfoMod/tag.go index edc1931..92de850 100644 --- a/models/advitiseInfoMod/tag.go +++ b/models/advitiseInfoMod/tag.go @@ -15,6 +15,7 @@ type TagAdvitiseInfo struct { RandomNames string Link string Status string + Sort string StartTime string EndTime string Remark string @@ -46,6 +47,7 @@ func init() { FN.AdvitiseInfo.RandomNames = "randomNames" FN.AdvitiseInfo.Link = "link" FN.AdvitiseInfo.Status = "status" + FN.AdvitiseInfo.Sort = "sort" FN.AdvitiseInfo.StartTime = "startTime" FN.AdvitiseInfo.EndTime = "endTime" FN.AdvitiseInfo.Remark = "remark" diff --git a/models/advitiseInfoMod/type.go b/models/advitiseInfoMod/type.go index 8186581..97e16cf 100644 --- a/models/advitiseInfoMod/type.go +++ b/models/advitiseInfoMod/type.go @@ -24,6 +24,7 @@ type AdvitiseInfo struct { RandomNames []string `json:"randomNames" bson:"randomNames"` // 随机名称 Link string `json:"link" bson:"link"` // 跳转链接 Status bool `json:"status" bson:"status"` // 是否激活 + Sort int64 `json:"sort" bson:"sort"` // 排序值,从小到大 StartTime time.Time `json:"startTime" bson:"startTime"` // 开始时间 EndTime time.Time `json:"endTime" bson:"endTime"` // 结束时间 Remark string `json:"remark" bson:"remark"` // 备注 diff --git a/service/advitiseV2Ser/info.go b/service/advitiseV2Ser/info.go index 6ae2216..bec9ff7 100644 --- a/service/advitiseV2Ser/info.go +++ b/service/advitiseV2Ser/info.go @@ -31,7 +31,7 @@ func InfoList(ctx context.Context, req *proto.AdvitiseInfoListReq) (*proto.Advit return nil, err } opt := &options.FindOptions{} - opt.SetSort(bson.D{{Key: advitiseInfoMod.FN.AdvitiseInfo.CreatedAt, Value: -1}}) + opt.SetSort(infoListOrder(req.OrderBy)) opt.SetSkip((req.PageNum - 1) * req.PageSize) opt.SetLimit(req.PageSize) list, err := advitiseInfoMod.FindManyAdvitiseInfos(ctx, filter, opt) @@ -43,6 +43,39 @@ func InfoList(ctx context.Context, req *proto.AdvitiseInfoListReq) (*proto.Advit return resp, nil } +// 列表排序方式 +const ( + OrderBySortAsc = "sortAsc" // 排序值从小到大(默认) + OrderBySortDesc = "sortDesc" // 排序值从大到小 + OrderByNewest = "newest" // 按创建时间,最新在前 +) + +// infoListOrder 把排序方式翻成 mongo 的 sort 文档。 +// 末尾一律追加 _id 作为最后一级,sort/createdAt 相同的文档顺序才是确定的, +// 否则 skip/limit 翻页会出现重复或漏数据。 +func infoListOrder(orderBy string) bson.D { + fn := advitiseInfoMod.FN.AdvitiseInfo + switch orderBy { + case OrderBySortDesc: + return bson.D{ + {Key: fn.Sort, Value: -1}, + {Key: fn.CreatedAt, Value: -1}, + {Key: fn.Id, Value: -1}, + } + case OrderByNewest: + return bson.D{ + {Key: fn.CreatedAt, Value: -1}, + {Key: fn.Id, Value: -1}, + } + default: // OrderBySortAsc 及未传值 + return bson.D{ + {Key: fn.Sort, Value: 1}, + {Key: fn.CreatedAt, Value: -1}, + {Key: fn.Id, Value: -1}, + } + } +} + func InfoAdd(ctx context.Context, req *proto.AddAdvitiseInfoReq) error { now := time.Now() doc := &advitiseInfoMod.AdvitiseInfo{ @@ -60,6 +93,7 @@ func InfoAdd(ctx context.Context, req *proto.AddAdvitiseInfoReq) error { RandomNames: emptyIfNil(req.RandomNames), Link: req.Link, Status: req.Status, + Sort: req.Sort, StartTime: req.StartTime, EndTime: req.EndTime, Remark: req.Remark, @@ -113,6 +147,9 @@ func InfoUpdate(ctx context.Context, req *proto.UpdateAdvitiseInfoReq) error { if req.Status != nil { set[advitiseInfoMod.FN.AdvitiseInfo.Status] = *req.Status } + if req.Sort != nil { + set[advitiseInfoMod.FN.AdvitiseInfo.Sort] = *req.Sort + } if req.StartTime != nil { set[advitiseInfoMod.FN.AdvitiseInfo.StartTime] = *req.StartTime }