From b45963f9b5d529572f3499b51a778521e7664025 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Sat, 23 Dec 2023 15:36:42 +0800 Subject: [PATCH] feat: enhanced paging support --- internal/api/status/query.go | 13 +++++++++---- internal/api/status/query_version.go | 7 ++++--- internal/e/resp.go | 5 +++++ internal/service/status/query.go | 13 +++++++------ internal/service/status/service.go | 2 +- internal/service/submission/query.go | 9 +++++---- internal/service/submission/service.go | 2 +- 7 files changed, 32 insertions(+), 19 deletions(-) diff --git a/internal/api/status/query.go b/internal/api/status/query.go index 6bad0eb..809ff7f 100644 --- a/internal/api/status/query.go +++ b/internal/api/status/query.go @@ -14,7 +14,7 @@ type queryRequest struct { Limit int `form:"limit" json:"limit" binding:"required"` } -type queryResponse struct { +type submissionWithScore struct { Submission model.Submission `json:"submission"` Point int32 `json:"point"` } @@ -29,7 +29,8 @@ type queryResponse struct { // @Param uid formData uint false "user id" // @Param offset formData int false "start position" // @Param limit formData int true "limit number of records" -// @Response 200 {object} e.Response[[]queryResponse] "queryResponse" +// @Response 200 {object} e.Response[e.WithCount[submissionWithScore]] "status" +// @Security Authentication // @Router /v1/status/query [post] func (h *handler) Query(c *gin.Context) { claim, exist := c.Get("claim") @@ -55,10 +56,14 @@ func (h *handler) Query(c *gin.Context) { role := claim.(*model.Claim).Role var response []*queryResponse + var count int64 + submissions, status := h.submissionService.Query(req.Pid, req.Uid, req.Offset, req.Limit, &count) + + var response []*submissionWithScore for _, submission := range submissions { cur, _ := h.statusService.Query(submission.ID, false) point := utils.If(cur == nil, -1, cur.Point) - resp := &queryResponse{ + resp := &submissionWithScore{ Submission: *submission, Point: point, } @@ -71,5 +76,5 @@ func (h *handler) Query(c *gin.Context) { response = append(response, resp) } - e.Pong(c, status, response) + e.Pong(c, status, e.WithCount[*submissionWithScore]{Count: count, Data: response}) } diff --git a/internal/api/status/query_version.go b/internal/api/status/query_version.go index 387b3a3..d7b70fc 100644 --- a/internal/api/status/query_version.go +++ b/internal/api/status/query_version.go @@ -21,7 +21,7 @@ type queryByVersionRequest struct { // @Param pvid formData uint true "problem version" // @Param offset formData int false "start position" // @Param limit formData int true "max number of results" -// @Response 200 {object} e.Response[[]model.Status] "submission status array" +// @Response 200 {object} e.Response[e.WithCount[model.Status]] "submission status array" // @Security Authentication // @Router /v1/status/query/version [post] func (h *handler) QueryByProblemVersion(c *gin.Context) { @@ -44,6 +44,7 @@ func (h *handler) QueryByProblemVersion(c *gin.Context) { return } - submitStatus, status := h.statusService.QueryByVersion(req.ProblemVersionID, req.Offset, req.Limit) - e.Pong(c, status, submitStatus) + var count int64 + submitStatus, status := h.statusService.QueryByVersion(req.ProblemVersionID, req.Offset, req.Limit, &count) + e.Pong(c, status, e.WithCount[*model.Status]{Count: count, Data: submitStatus}) } diff --git a/internal/e/resp.go b/internal/e/resp.go index cd07d7f..edef91d 100644 --- a/internal/e/resp.go +++ b/internal/e/resp.go @@ -12,6 +12,11 @@ type Response[T any] struct { Body T `json:"body"` } +type WithCount[T any] struct { + Count int64 `json:"count"` + Data []T `json:"data"` +} + func wrap[T any](status Status, body T) Response[interface{}] { return Response[interface{}]{ Code: int(status), diff --git a/internal/service/status/query.go b/internal/service/status/query.go index 96d9e32..1073e31 100644 --- a/internal/service/status/query.go +++ b/internal/service/status/query.go @@ -36,8 +36,8 @@ func (s *service) Query(sid uint, associations bool) (*model.Status, e.Status) { return status, e.Success } -func (s *service) QueryByVersion(pvid uint, offset int, limit int) ([]*model.Status, e.Status) { - var statuses []*model.Status +func (s *service) QueryByVersion(pvid uint, offset int, limit int, count *int64) ([]*model.Status, e.Status) { + var ret []*model.Status status := &model.Status{ ProblemVersionID: pvid, IsEnabled: true, @@ -45,12 +45,13 @@ func (s *service) QueryByVersion(pvid uint, offset int, limit int) ([]*model.Sta err := s.db.Get().Preload(clause.Associations). Where(status). - Limit(limit). - Offset(offset). - Find(&statuses).Error + Order("created_at DESC"). + Offset(offset).Limit(limit).Find(&ret). + Offset(-1).Limit(-1).Count(count). + Error if err != nil { s.log.Warn("DatabaseError", zap.Error(err), zap.Any("status", status)) return nil, e.DatabaseError } - return statuses, e.Success + return ret, e.Success } diff --git a/internal/service/status/service.go b/internal/service/status/service.go index b255d98..9683389 100644 --- a/internal/service/status/service.go +++ b/internal/service/status/service.go @@ -14,7 +14,7 @@ var _ Service = (*service)(nil) type Service interface { Create(data *CreateData) (*model.Status, e.Status) Query(sid uint, associations bool) (*model.Status, e.Status) - QueryByVersion(pvid uint, offset int, limit int) ([]*model.Status, e.Status) + QueryByVersion(pvid uint, offset int, limit int, count *int64) ([]*model.Status, e.Status) HealthCheck() error } diff --git a/internal/service/submission/query.go b/internal/service/submission/query.go index 391b67c..2d07220 100644 --- a/internal/service/submission/query.go +++ b/internal/service/submission/query.go @@ -9,7 +9,7 @@ import ( "gorm.io/gorm/clause" ) -func (s *service) Query(pid uint, uid uint, offset int, limit int) ([]*model.Submission, e.Status) { +func (s *service) Query(pid uint, uid uint, offset int, limit int, count *int64) ([]*model.Submission, e.Status) { submissions := make([]*model.Submission, 0) submission := &model.Submission{ @@ -19,9 +19,10 @@ func (s *service) Query(pid uint, uid uint, offset int, limit int) ([]*model.Sub err := s.db.Get().Preload(clause.Associations). Where(submission). - Limit(limit). - Offset(offset). - Find(&submissions).Error + Order("created_at DESC"). + Offset(offset).Limit(limit).Find(&submissions). + Offset(-1).Limit(-1).Count(count). + Error //if errors.Is(err, gorm.ErrRecordNotFound) { // return nil, e.ProblemNotFound diff --git a/internal/service/submission/service.go b/internal/service/submission/service.go index 3ea8043..1eaa2dc 100644 --- a/internal/service/submission/service.go +++ b/internal/service/submission/service.go @@ -13,7 +13,7 @@ var _ Service = (*service)(nil) type Service interface { Create(data *CreateData) (*model.Submission, e.Status) - Query(pid uint, uid uint, offset int, limit int) ([]*model.Submission, e.Status) + Query(pid uint, uid uint, offset int, limit int, count *int64) ([]*model.Submission, e.Status) QueryBySid(sid uint, associations bool) (*model.Submission, e.Status) HealthCheck() error