fix(poll): GetPackages 接口新增分页 POLL-03

- 新增 AssetPackagesResult DTO(含 total/page/page_size/items 字段)
- GetPackages 签名新增 page/pageSize 参数,默认 page=1、pageSize=50、最大 100
- admin/asset.go:Packages 从 Query 参数读取 page/page_size 传入 Service
- client_asset.go 调用处同步更新,使用默认分页参数
This commit is contained in:
2026-03-28 10:41:20 +08:00
parent 4be473c248
commit 8553a46143
4 changed files with 50 additions and 11 deletions

View File

@@ -90,7 +90,7 @@ func (h *AssetHandler) Refresh(c *fiber.Ctx) error {
return response.Success(c, result)
}
// Packages 获取资产所有套餐列表
// Packages 获取资产所有套餐列表(支持分页,默认 page=1 pageSize=50
// GET /api/admin/assets/:asset_type/:id/packages
func (h *AssetHandler) Packages(c *fiber.Ctx) error {
assetType := c.Params("asset_type")
@@ -99,7 +99,10 @@ func (h *AssetHandler) Packages(c *fiber.Ctx) error {
return errors.New(errors.CodeInvalidParam, "无效的资产ID")
}
result, err := h.assetService.GetPackages(c.UserContext(), assetType, uint(id))
page := c.QueryInt("page", 1)
pageSize := c.QueryInt("page_size", 50)
result, err := h.assetService.GetPackages(c.UserContext(), assetType, uint(id), page, pageSize)
if err != nil {
return err
}

View File

@@ -210,11 +210,11 @@ func (h *ClientAssetHandler) GetAvailablePackages(c *fiber.Ctx) error {
return errors.New(errors.CodeNoAvailablePackage, "当前无可购买套餐")
}
allUsages, err := h.assetService.GetPackages(resolved.SkipPermissionCtx, resolved.Asset.AssetType, resolved.Asset.AssetID)
packagesResult, err := h.assetService.GetPackages(resolved.SkipPermissionCtx, resolved.Asset.AssetType, resolved.Asset.AssetID, 1, 50)
if err != nil {
return err
}
resolved.MainPackageActived = hasActiveMainPackage(allUsages)
resolved.MainPackageActived = hasActiveMainPackage(packagesResult.Items)
listCtx := resolved.SkipPermissionCtx
if resolved.IsAgentChannel {

View File

@@ -97,6 +97,14 @@ type AssetPackageResponse struct {
CreatedAt time.Time `json:"created_at" description:"创建时间"`
}
// AssetPackagesResult 套餐列表分页结果
type AssetPackagesResult struct {
Total int64 `json:"total" description:"总条数"`
Page int `json:"page" description:"当前页码"`
PageSize int `json:"page_size" description:"每页条数"`
Items []*AssetPackageResponse `json:"items" description:"套餐列表"`
}
// AssetResolveRequest 资产解析请求(路径参数)
type AssetResolveRequest struct {
Identifier string `path:"identifier" description:"资产标识符(虚拟号/ICCID/IMEI/SN/MSISDN" required:"true"`

View File

@@ -343,8 +343,20 @@ func (s *Service) Refresh(ctx context.Context, assetType string, id uint) (*dto.
}
}
// GetPackages 获取资产的所有套餐列表
func (s *Service) GetPackages(ctx context.Context, assetType string, id uint) ([]*dto.AssetPackageResponse, error) {
// GetPackages 获取资产的所有套餐列表(支持分页)
// page 默认 1pageSize 默认 50pageSize 最大 100
func (s *Service) GetPackages(ctx context.Context, assetType string, id uint, page, pageSize int) (*dto.AssetPackagesResult, error) {
// 分页参数边界处理
if page < 1 {
page = 1
}
if pageSize < 1 {
pageSize = 50
}
if pageSize > 100 {
pageSize = 100
}
// assetType 对应 Store 中的 carrierTypecard→iot_card, device→device
carrierType := assetType
if assetType == "card" {
@@ -371,7 +383,7 @@ func (s *Service) GetPackages(ctx context.Context, assetType string, id uint) ([
pkgMap[p.ID] = p
}
result := make([]*dto.AssetPackageResponse, 0, len(usages))
all := make([]*dto.AssetPackageResponse, 0, len(usages))
for _, u := range usages {
pkg := pkgMap[u.PackageID]
ratio := 1.0
@@ -403,15 +415,31 @@ func (s *Service) GetPackages(ctx context.Context, assetType string, id uint) ([
Priority: u.Priority,
CreatedAt: u.CreatedAt,
}
result = append(result, item)
all = append(all, item)
}
// 按 created_at DESC 排序
sort.Slice(result, func(i, j int) bool {
return result[i].CreatedAt.After(result[j].CreatedAt)
sort.Slice(all, func(i, j int) bool {
return all[i].CreatedAt.After(all[j].CreatedAt)
})
return result, nil
total := int64(len(all))
offset := (page - 1) * pageSize
end := offset + pageSize
if offset >= len(all) {
offset = len(all)
}
if end > len(all) {
end = len(all)
}
items := all[offset:end]
return &dto.AssetPackagesResult{
Total: total,
Page: page,
PageSize: pageSize,
Items: items,
}, nil
}
// GetCurrentPackage 获取资产当前生效的主套餐