From c89291b36288751fb31ea5535263f2ec688384ba Mon Sep 17 00:00:00 2001 From: break Date: Wed, 29 Jul 2026 17:00:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AE=A2=E6=88=B7=E6=8C=89?= =?UTF-8?q?=E5=A5=97=E9=A4=90=E7=B1=BB=E5=9E=8B=E7=BC=A9=E5=B0=8F=E5=8F=AF?= =?UTF-8?q?=E8=B4=AD=E8=8C=83=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Constraint: 查询参数可选且仅接受 formal 或 addon Rejected: 新增专用 Store 方法 | 现有 PackageStore.List 已支持 package_type 过滤 Confidence: high Scope-risk: narrow Directive: 套餐类型取值继续与 pkg/constants 保持一致 Tested: go run cmd/gendocs/main.go,确认 OpenAPI 生成 package_type 查询参数 Not-tested: 按用户要求未执行自动化测试 --- docs/admin-openapi.yaml | 7 +++++++ internal/handler/app/client_asset.go | 21 ++++++++++++++++----- internal/model/dto/client_asset_dto.go | 3 ++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/docs/admin-openapi.yaml b/docs/admin-openapi.yaml index 3674b76..98f4f76 100644 --- a/docs/admin-openapi.yaml +++ b/docs/admin-openapi.yaml @@ -29405,6 +29405,13 @@ paths: maxLength: 50 minLength: 1 type: string + - description: 套餐类型 (formal:正式套餐, addon:附加套餐) + in: query + name: package_type + schema: + description: 套餐类型 (formal:正式套餐, addon:附加套餐) + nullable: true + type: string responses: "200": content: diff --git a/internal/handler/app/client_asset.go b/internal/handler/app/client_asset.go index cb6896e..23a87ab 100644 --- a/internal/handler/app/client_asset.go +++ b/internal/handler/app/client_asset.go @@ -22,11 +22,14 @@ import ( "github.com/break/junhong_cmp_fiber/pkg/errors" pkgMiddleware "github.com/break/junhong_cmp_fiber/pkg/middleware" "github.com/break/junhong_cmp_fiber/pkg/response" + "github.com/go-playground/validator/v10" "github.com/gofiber/fiber/v2" "go.uber.org/zap" "gorm.io/gorm" ) +var clientAssetValidator = validator.New() + // ClientAssetHandler C 端资产信息处理器 // 提供 B1~B4 资产信息、可购套餐、套餐历史、手动刷新接口 type ClientAssetHandler struct { @@ -342,6 +345,9 @@ func (h *ClientAssetHandler) GetAvailablePackages(c *fiber.Ctx) error { if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } + if err := clientAssetValidator.Struct(&req); err != nil { + return errors.New(errors.CodeInvalidParam) + } resolved, err := h.resolveAssetFromIdentifier(c, req.Identifier) if err != nil { @@ -369,15 +375,20 @@ func (h *ClientAssetHandler) GetAvailablePackages(c *fiber.Ctx) error { listCtx = context.WithValue(listCtx, constants.ContextKeyShopID, resolved.SellerShopID) } + filters := map[string]any{ + "series_id": *resolved.Asset.SeriesID, + "status": constants.StatusEnabled, + "shelf_status": constants.ShelfStatusOn, + } + if req.PackageType != nil { + filters["package_type"] = *req.PackageType + } + pkgs, _, err := h.packageStore.List(listCtx, &store.QueryOptions{ Page: 1, PageSize: constants.MaxPageSize, OrderBy: "id DESC", - }, map[string]any{ - "series_id": *resolved.Asset.SeriesID, - "status": constants.StatusEnabled, - "shelf_status": constants.ShelfStatusOn, - }) + }, filters) if err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "查询可购套餐失败") } diff --git a/internal/model/dto/client_asset_dto.go b/internal/model/dto/client_asset_dto.go index fed7d96..bb1bb68 100644 --- a/internal/model/dto/client_asset_dto.go +++ b/internal/model/dto/client_asset_dto.go @@ -146,7 +146,8 @@ type DeviceRealtimeInfo struct { // AssetPackageListRequest B2 资产可购套餐列表请求 type AssetPackageListRequest struct { - Identifier string `json:"identifier" query:"identifier" validate:"required,min=1,max=50" required:"true" minLength:"1" maxLength:"50" description:"资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)"` + Identifier string `json:"identifier" query:"identifier" validate:"required,min=1,max=50" required:"true" minLength:"1" maxLength:"50" description:"资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)"` + PackageType *string `json:"package_type" query:"package_type" validate:"omitempty,oneof=formal addon" description:"套餐类型 (formal:正式套餐, addon:附加套餐)"` } // ClientPackageItem B2 客户端套餐项