补全页加分页,每页 30 行
218 行在手机上堆成一屏一行有五万多像素长,分页后第 1 页只有八千多。 页码会夹紧:?page=999 停在最后一页而不是给空白页,解析不出来回第一页。 提交后留在同一页——处理完的行会从列表里消失,停在这儿才看得见剩下的。 翻页前若这一页有改过还没提交的下拉,先确认一次(预选的建议不算「改过」)。
This commit is contained in:
+53
-5
@@ -3,7 +3,9 @@ package web
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -82,6 +84,21 @@ type FillupData struct {
|
||||
Categories []fillupCategory // 类别下拉选项
|
||||
Total int
|
||||
WithHint int
|
||||
|
||||
// 分页。218 行在手机上堆成一屏一行有五万多像素长,一页 30 行刚好。
|
||||
PageNo int
|
||||
PageCount int
|
||||
}
|
||||
|
||||
// fillupPerPage 是补全页每页的行数。
|
||||
const fillupPerPage = 30
|
||||
|
||||
// PageLink 生成带页码的链接,供模板里的上一页/下一页用。
|
||||
func (d FillupData) PageLink(no int) template.URL {
|
||||
if no < 1 {
|
||||
no = 1
|
||||
}
|
||||
return template.URL("/admin/fillup?page=" + strconv.Itoa(no))
|
||||
}
|
||||
|
||||
// activityOption 只是给下拉用的(活动 id + 名字)。
|
||||
@@ -189,13 +206,26 @@ func (s *Server) adminFillupPage(w http.ResponseWriter, r *http.Request) {
|
||||
s.serverError(w, r, err)
|
||||
return
|
||||
}
|
||||
d := FillupData{Page: p, Rows: rows, Activities: acts, Categories: fillupCategories(), Total: len(rows)}
|
||||
total := len(rows)
|
||||
hinted := 0
|
||||
for _, row := range rows {
|
||||
if row.ActHint != "" || row.CatHint != "" {
|
||||
d.WithHint++
|
||||
hinted++
|
||||
}
|
||||
}
|
||||
s.render(w, "admin/fillup", d)
|
||||
pageCount := (total + fillupPerPage - 1) / fillupPerPage
|
||||
pageNo := clampPage(r.URL.Query().Get("page"), pageCount)
|
||||
from := (pageNo - 1) * fillupPerPage
|
||||
to := from + fillupPerPage
|
||||
if to > total {
|
||||
to = total
|
||||
}
|
||||
rows = rows[from:to]
|
||||
|
||||
s.render(w, "admin/fillup", FillupData{
|
||||
Page: p, Rows: rows, Activities: acts, Categories: fillupCategories(),
|
||||
Total: total, WithHint: hinted, PageNo: pageNo, PageCount: pageCount,
|
||||
})
|
||||
}
|
||||
|
||||
// activityOptions 列出该数据集的活动,供下拉选择。
|
||||
@@ -451,7 +481,25 @@ func (s *Server) adminFillupAmap(w http.ResponseWriter, r *http.Request) {
|
||||
s.fillupFlash(w, r, "ok", msg)
|
||||
}
|
||||
|
||||
// fillupFlash 把提示带回补全页本身(adminFlash 是跳后台首页的)。
|
||||
// fillupFlash 把提示带回补全页本身(adminFlash 是跳后台首页的),并保留当前页码——
|
||||
// 处理完的那几行会从列表里消失,停在同一页才看得见剩下的。
|
||||
func (s *Server) fillupFlash(w http.ResponseWriter, r *http.Request, kind, msg string) {
|
||||
http.Redirect(w, r, "/admin/fillup?"+kind+"="+urlQueryEscape(msg), http.StatusSeeOther)
|
||||
q := url.Values{}
|
||||
q.Set(kind, msg)
|
||||
if pg := strings.TrimSpace(r.PostFormValue("page")); pg != "" {
|
||||
q.Set("page", pg)
|
||||
}
|
||||
http.Redirect(w, r, "/admin/fillup?"+q.Encode(), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// clampPage 解析页码并夹到有效范围;解析不出来就回第一页。
|
||||
func clampPage(raw string, pageCount int) int {
|
||||
no, err := strconv.Atoi(strings.TrimSpace(raw))
|
||||
if err != nil || no < 1 {
|
||||
no = 1
|
||||
}
|
||||
if pageCount > 0 && no > pageCount {
|
||||
no = pageCount
|
||||
}
|
||||
return no
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user