From 8553a461431491c0315d79bc3639fec314a2f37d Mon Sep 17 00:00:00 2001 From: huang Date: Sat, 28 Mar 2026 10:41:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(poll):=20GetPackages=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=88=86=E9=A1=B5=20POLL-03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 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 调用处同步更新,使用默认分页参数 --- internal/handler/admin/asset.go | 7 +++-- internal/handler/app/client_asset.go | 4 +-- internal/model/dto/asset_dto.go | 8 ++++++ internal/service/asset/service.go | 42 +++++++++++++++++++++++----- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/internal/handler/admin/asset.go b/internal/handler/admin/asset.go index 5fbff96..3944da9 100644 --- a/internal/handler/admin/asset.go +++ b/internal/handler/admin/asset.go @@ -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 } diff --git a/internal/handler/app/client_asset.go b/internal/handler/app/client_asset.go index 0c4818c..0fa26a7 100644 --- a/internal/handler/app/client_asset.go +++ b/internal/handler/app/client_asset.go @@ -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 { diff --git a/internal/model/dto/asset_dto.go b/internal/model/dto/asset_dto.go index 0d604f8..3da072b 100644 --- a/internal/model/dto/asset_dto.go +++ b/internal/model/dto/asset_dto.go @@ -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"` diff --git a/internal/service/asset/service.go b/internal/service/asset/service.go index 773e3c0..2d21a98 100644 --- a/internal/service/asset/service.go +++ b/internal/service/asset/service.go @@ -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 默认 1,pageSize 默认 50,pageSize 最大 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 中的 carrierType:card→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 获取资产当前生效的主套餐