Skip to content

Commit 338569f

Browse files
committed
feat(fs): Add pagination support and enhance response structure
- Introduced new pagination fields: `page`, `per_page`, `has_more`, and `pages_total` in `FsListResp` - Added `normalizeListPage` and `calcPagesTotal` for effective pagination handling - Updated default and max page size values; implemented validations for page parameters - Refactored `FsList` handler to include paginated responses and filtered totals - Adjusted default page size in site settings from 30 to 50
1 parent f3d6230 commit 338569f

File tree

2 files changed

+63
-20
lines changed

2 files changed

+63
-20
lines changed

internal/bootstrap/data/setting.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func InitialSettings() []model.SettingItem {
100100
{Key: conf.SiteTitle, Value: "AList", Type: conf.TypeString, Group: model.SITE},
101101
{Key: conf.Announcement, Value: "### repo\nhttps://github.com/alist-org/alist", Type: conf.TypeText, Group: model.SITE},
102102
{Key: "pagination_type", Value: "all", Type: conf.TypeSelect, Options: "all,pagination,load_more,auto_load_more", Group: model.SITE},
103-
{Key: "default_page_size", Value: "30", Type: conf.TypeNumber, Group: model.SITE},
103+
{Key: "default_page_size", Value: "50", Type: conf.TypeNumber, Group: model.SITE},
104104
{Key: conf.AllowIndexed, Value: "false", Type: conf.TypeBool, Group: model.SITE},
105105
{Key: conf.AllowMounted, Value: "true", Type: conf.TypeBool, Group: model.SITE},
106106
{Key: conf.RobotsTxt, Value: "User-agent: *\nAllow: /", Type: conf.TypeText, Group: model.SITE},

server/handles/fsread.go

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,17 @@ type ObjResp struct {
4949
}
5050

5151
type FsListResp struct {
52-
Content []ObjLabelResp `json:"content"`
53-
Total int64 `json:"total"`
54-
Readme string `json:"readme"`
55-
Header string `json:"header"`
56-
Write bool `json:"write"`
57-
Provider string `json:"provider"`
52+
Content []ObjLabelResp `json:"content"`
53+
Total int64 `json:"total"`
54+
FilteredTotal int64 `json:"filtered_total"`
55+
Page int `json:"page"`
56+
PerPage int `json:"per_page"`
57+
HasMore bool `json:"has_more"`
58+
PagesTotal int `json:"pages_total"`
59+
Readme string `json:"readme"`
60+
Header string `json:"header"`
61+
Write bool `json:"write"`
62+
Provider string `json:"provider"`
5863
}
5964

6065
type ObjLabelResp struct {
@@ -74,13 +79,20 @@ type ObjLabelResp struct {
7479
StorageClass string `json:"storage_class,omitempty"`
7580
}
7681

82+
const (
83+
DefaultPerPage = 200
84+
MaxPerPage = 500
85+
)
86+
7787
func FsList(c *gin.Context) {
7888
var req ListReq
7989
if err := c.ShouldBind(&req); err != nil {
8090
common.ErrorResp(c, err, 400)
8191
return
8292
}
83-
req.Validate()
93+
effPage, effPerPage := normalizeListPage(req.Page, req.PerPage)
94+
req.Page = effPage
95+
req.PerPage = effPerPage
8496
user := c.MustGet("user").(*model.User)
8597
reqPath, err := user.JoinPath(req.Path)
8698
if err != nil {
@@ -104,6 +116,11 @@ func FsList(c *gin.Context) {
104116
common.ErrorStrResp(c, "Refresh without permission", 403)
105117
return
106118
}
119+
provider := "unknown"
120+
storage, storageErr := fs.GetStorage(reqPath, &fs.GetStoragesArgs{})
121+
if storageErr == nil {
122+
provider = storage.GetStorage().Driver
123+
}
107124
objs, err := fs.List(c, reqPath, &fs.ListArgs{Refresh: req.Refresh})
108125
if err != nil {
109126
common.ErrorResp(c, err, 500)
@@ -116,19 +133,23 @@ func FsList(c *gin.Context) {
116133
filtered = append(filtered, obj)
117134
}
118135
}
119-
total, objs := pagination(filtered, &req.PageReq)
120-
provider := "unknown"
121-
storage, err := fs.GetStorage(reqPath, &fs.GetStoragesArgs{})
122-
if err == nil {
123-
provider = storage.GetStorage().Driver
124-
}
136+
total, pageObjs := pagination(filtered, &req.PageReq)
137+
respContent := toObjsResp(pageObjs, reqPath, isEncrypt(meta, reqPath))
138+
pagesTotal := calcPagesTotal(total, req.PerPage)
139+
hasMore := req.Page*req.PerPage < total
140+
125141
common.SuccessResp(c, FsListResp{
126-
Content: toObjsResp(objs, reqPath, isEncrypt(meta, reqPath)),
127-
Total: int64(total),
128-
Readme: getReadme(meta, reqPath),
129-
Header: getHeader(meta, reqPath),
130-
Write: common.HasPermission(perm, common.PermWrite) || common.CanWrite(meta, reqPath),
131-
Provider: provider,
142+
Content: respContent,
143+
Total: int64(total),
144+
FilteredTotal: int64(total),
145+
Page: req.Page,
146+
PerPage: req.PerPage,
147+
HasMore: hasMore,
148+
PagesTotal: pagesTotal,
149+
Readme: getReadme(meta, reqPath),
150+
Header: getHeader(meta, reqPath),
151+
Write: common.HasPermission(perm, common.PermWrite) || common.CanWrite(meta, reqPath),
152+
Provider: provider,
132153
})
133154
}
134155

@@ -226,6 +247,28 @@ func isEncrypt(meta *model.Meta, path string) bool {
226247
return true
227248
}
228249

250+
func normalizeListPage(page, perPage int) (int, int) {
251+
effPage := page
252+
if effPage <= 0 {
253+
effPage = 1
254+
}
255+
effPerPage := perPage
256+
if effPerPage <= 0 {
257+
effPerPage = DefaultPerPage
258+
}
259+
if effPerPage > MaxPerPage {
260+
effPerPage = MaxPerPage
261+
}
262+
return effPage, effPerPage
263+
}
264+
265+
func calcPagesTotal(total, perPage int) int {
266+
if total <= 0 || perPage <= 0 {
267+
return 0
268+
}
269+
return (total + perPage - 1) / perPage
270+
}
271+
229272
func pagination(objs []model.Obj, req *model.PageReq) (int, []model.Obj) {
230273
pageIndex, pageSize := req.Page, req.PerPage
231274
total := len(objs)

0 commit comments

Comments
 (0)