feat: 统一 Admin 主列表分页 (#64)
This commit is contained in:
@@ -131,17 +131,25 @@ func ListClientViews(db *sql.DB, keyword string, threshold time.Duration) ([]Cli
|
||||
|
||||
// ListClientViewsForUser 按网页登录身份限制可见范围:管理员全量,采购员只看自己。
|
||||
func ListClientViewsForUser(db *sql.DB, actor *model.User, keyword string, threshold time.Duration) ([]ClientView, error) {
|
||||
visibleUserID, err := visibleClientUserID(actor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return listClientViews(db, keyword, visibleUserID, threshold)
|
||||
}
|
||||
|
||||
func visibleClientUserID(actor *model.User) (string, error) {
|
||||
if actor == nil {
|
||||
return nil, ErrUnauthenticated
|
||||
return "", ErrUnauthenticated
|
||||
}
|
||||
visibleUserID := ""
|
||||
if !actor.IsAdmin() {
|
||||
if actor.Role != model.RolePurchaser {
|
||||
return nil, ErrAdminRequired
|
||||
return "", ErrAdminRequired
|
||||
}
|
||||
visibleUserID = actor.UserID
|
||||
}
|
||||
return listClientViews(db, keyword, visibleUserID, threshold)
|
||||
return visibleUserID, nil
|
||||
}
|
||||
|
||||
func listClientViews(db *sql.DB, keyword, visibleUserID string, threshold time.Duration) ([]ClientView, error) {
|
||||
@@ -163,6 +171,58 @@ func listClientViews(db *sql.DB, keyword, visibleUserID string, threshold time.D
|
||||
return views, nil
|
||||
}
|
||||
|
||||
// ClientListResult 是客户端页面的一页数据和同一权限范围内的完整统计。
|
||||
type ClientListResult struct {
|
||||
Rows []ClientView
|
||||
Page int
|
||||
Total int
|
||||
TotalPages int
|
||||
Online int
|
||||
Offline int
|
||||
}
|
||||
|
||||
// ListClientPageForUser 按网页登录身份、搜索词和统一页大小返回客户端列表。
|
||||
func ListClientPageForUser(db *sql.DB, actor *model.User, keyword string, threshold time.Duration, requestedPage int) (*ClientListResult, error) {
|
||||
visibleUserID, err := visibleClientUserID(actor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
page := requestedPage
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
rows, total, err := repository.ListClientsForUserPage(db, keyword, visibleUserID, PageSize, (page-1)*PageSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
totalPages := TotalPages(total)
|
||||
clampedPage := ClampPage(page, totalPages)
|
||||
if clampedPage != page {
|
||||
page = clampedPage
|
||||
rows, _, err = repository.ListClientsForUserPage(db, keyword, visibleUserID, PageSize, (page-1)*PageSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
online, err := repository.CountOnlineClientsForUser(
|
||||
db, keyword, visibleUserID, now.Add(-threshold).Format(model.TimeLayout))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
views := make([]ClientView, 0, len(rows))
|
||||
for _, client := range rows {
|
||||
views = append(views, ClientView{
|
||||
Client: client.Client, Status: client.StatusText(now, threshold),
|
||||
AssignedUserID: client.AssignedUserID, AssignedUsername: client.AssignedUsername,
|
||||
})
|
||||
}
|
||||
return &ClientListResult{
|
||||
Rows: views, Page: page, Total: total, TotalPages: totalPages,
|
||||
Online: online, Offline: total - online,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListAssignableClients 返回当前用户在采购任务页面可选择的客户端。
|
||||
// 当前创建页面尚未实现,本函数固定未来入口也必须沿用相同权限边界。
|
||||
func ListAssignableClients(db *sql.DB, actor *model.User, threshold time.Duration) ([]ClientView, error) {
|
||||
|
||||
Reference in New Issue
Block a user