update doc list api antrian + pagination

This commit is contained in:
renaldybrada
2026-02-02 15:21:32 +07:00
parent 564b24b343
commit 046903c7a1
8 changed files with 154 additions and 9 deletions
+14
View File
@@ -33,6 +33,20 @@ const docTemplate = `{
"description": "Type antrian : all, kategori, spesialis, sub-spesialis",
"name": "type",
"in": "query"
},
{
"type": "string",
"default": "10",
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "string",
"default": "0",
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
+14
View File
@@ -27,6 +27,20 @@
"description": "Type antrian : all, kategori, spesialis, sub-spesialis",
"name": "type",
"in": "query"
},
{
"type": "string",
"default": "10",
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "string",
"default": "0",
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
+10
View File
@@ -219,6 +219,16 @@ paths:
in: query
name: type
type: string
- default: "10"
description: Limit
in: query
name: limit
type: string
- default: "0"
description: Offset
in: query
name: offset
type: string
responses:
"200":
description: OK
+6 -1
View File
@@ -81,6 +81,8 @@ func (h AntrianOperasiHandler) CreateAntrianOperasi(c *gin.Context) {
// @Tags Antrian Operasi
// @Param search query string false "Search Keyword"
// @Param type query string false "Type antrian : all, kategori, spesialis, sub-spesialis"
// @Param limit query string false "Limit" default(10)
// @Param offset query string false "Offset" default(0)
// @Success 200 {object} []PasienOperasi
// @Failure 500 {object} shared.BaseErrorResponse
// @Router /antrian-operasi/ [get]
@@ -95,5 +97,8 @@ func (h AntrianOperasiHandler) GetListAntrianOperasi(c *gin.Context) {
return
}
c.JSON(200, shared.ToBaseResponse(res, true, 200, "success get list antrian operasi"))
c.JSON(200,
shared.ToBaseResponsePaginate(
res.Data, res.Paging, true, 200, "success get list antrian operasi",
))
}
+9 -1
View File
@@ -1,6 +1,9 @@
package antrianoperasi
import "time"
import (
"antrian-operasi/internal/shared"
"time"
)
type PasienOperasi struct {
ID string `db:"id" json:"id"`
@@ -17,3 +20,8 @@ type PasienOperasi struct {
NoUrutSpesialis int `db:"no_urut_spesialis"`
NoUrutSubSpesialis int `db:"no_urut_sub_spesialis"`
}
type ListPasienOperasiPaginate struct {
Data []PasienOperasi
Paging shared.PaginationInfo
}
+27 -7
View File
@@ -2,6 +2,7 @@ package antrianoperasi
import (
"antrian-operasi/internal/database"
"antrian-operasi/internal/shared"
queryUtils "antrian-operasi/internal/utils/query"
"log"
"slices"
@@ -16,7 +17,7 @@ const TBL_NAME = "data_pasien_operasi"
type IAntrianOperasiRepository interface {
CreateAntrianOperasi(c *gin.Context, req CreatePasienOperasiRequest) (CreatePasienOperasiRequest, error)
SearchableListAntrianOperasi(c *gin.Context) ([]PasienOperasi, error)
SearchableListAntrianOperasi(c *gin.Context) (ListPasienOperasiPaginate, error)
}
type antrianOperasiRepo struct {
@@ -267,8 +268,8 @@ func (r antrianOperasiRepo) CreateAntrianOperasi(c *gin.Context, req CreatePasie
return req, nil
}
func (r antrianOperasiRepo) SearchableListAntrianOperasi(c *gin.Context) ([]PasienOperasi, error) {
var result []PasienOperasi
func (r antrianOperasiRepo) SearchableListAntrianOperasi(c *gin.Context) (ListPasienOperasiPaginate, error) {
var result ListPasienOperasiPaginate
search := c.Query("search")
availableType := []string{"all", "kategori", "spesialis", "sub-spesialis"}
antrianType := c.Query("type")
@@ -277,6 +278,9 @@ func (r antrianOperasiRepo) SearchableListAntrianOperasi(c *gin.Context) ([]Pasi
antrianType = "all"
}
limit := shared.ParseQueryLimit(c)
offset := shared.ParseQueryOffset(c)
query := queryUtils.DynamicQuery{
From: TBL_NAME,
Aliases: "dpo",
@@ -292,7 +296,6 @@ func (r antrianOperasiRepo) SearchableListAntrianOperasi(c *gin.Context) ([]Pasi
{Expression: "ddpo.Diagnosa", Alias: "diagnosa"},
{Expression: "dko.Kategori", Alias: "kategori"},
},
Limit: 10,
Sort: []queryUtils.SortField{
{Column: "dpo.Tanggal_daftar", Order: "ASC"}},
}
@@ -390,16 +393,33 @@ func (r antrianOperasiRepo) SearchableListAntrianOperasi(c *gin.Context) ([]Pasi
query.Filters = append(query.Filters, queryUtils.FilterGroup{Filters: searchFilters, LogicOp: "OR"})
}
// TODO Filtering status
dbconn, err := r.db.GetSQLXDB(DB_NAME)
if err != nil {
log.Printf("Unable to connect db : %s", err)
return result, err
}
err = r.queryBuilder.ExecuteQuery(
c, dbconn, query, &result)
// query count
countData, err := r.queryBuilder.ExecuteCount(c, dbconn, query)
if err != nil {
log.Printf("Unable to execute query : %s", err)
log.Printf("Unable to execute query count : %s ", err)
return result, err
}
result.Paging.Limit = limit
result.Paging.Offset = offset
result.Paging.Total = int(countData)
result.Paging.CalculatePagingInfo()
// query data
queryData := query
queryData.Limit = limit
queryData.Offset = offset
err = r.queryBuilder.ExecuteQuery(
c, dbconn, queryData, &result.Data)
if err != nil {
log.Printf("Unable to execute query data : %s", err)
return result, err
}
+17
View File
@@ -14,6 +14,11 @@ type BaseResponse[T any] struct {
Data T `json:"data" swaggertype:"object"`
}
type BaseResponsePaginate[T any] struct {
BaseResponse[T]
Paginate PaginationInfo
}
func ToBaseResponse[T any](data T, isSuccess bool, code int, message string) BaseResponse[T] {
return BaseResponse[T]{
Success: true,
@@ -22,3 +27,15 @@ func ToBaseResponse[T any](data T, isSuccess bool, code int, message string) Bas
Data: data,
}
}
func ToBaseResponsePaginate[T any](data T, paginate PaginationInfo, isSuccess bool, code int, message string) BaseResponsePaginate[T] {
return BaseResponsePaginate[T]{
BaseResponse: BaseResponse[T]{
Success: true,
Code: 200,
Message: message,
Data: data,
},
Paginate: paginate,
}
}
+57
View File
@@ -0,0 +1,57 @@
package shared
import (
"strconv"
"github.com/gin-gonic/gin"
)
type PaginationInfo struct {
Limit int
Offset int
Total int
TotalPages int
CurrentPage int
HasNext bool
HasPrev bool
}
func ParseQueryLimit(c *gin.Context) int {
limit := 10 // default
l, err := strconv.Atoi(c.Query("limit"))
if err == nil {
if l > 100 {
limit = 100 // max limit default
} else if l < 100 && l > 0 {
limit = l
}
}
return limit
}
func ParseQueryOffset(c *gin.Context) int {
offset := 0
o, err := strconv.Atoi(c.Query("offset"))
if err == nil {
if o > 0 {
offset = o
}
}
return offset
}
func (source *PaginationInfo) CalculatePagingInfo() *PaginationInfo {
result := source
result.TotalPages, result.CurrentPage = 0, 1
if result.Limit > 0 {
result.TotalPages = (result.Total + result.Limit - 1) / result.Limit
result.CurrentPage = (result.Offset / result.Limit) + 1
}
result.HasNext = result.Offset+result.Limit < result.Total
result.HasPrev = result.Offset > 0
return result
}