新增状态筛选条件,同时修复价格未正常写入的情况
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m35s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m35s
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
|
||||
dto "github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
@@ -119,8 +121,17 @@ func (h *AssetHandler) Packages(c *fiber.Ctx) error {
|
||||
|
||||
page := c.QueryInt("page", 1)
|
||||
pageSize := c.QueryInt("page_size", 50)
|
||||
statusRaw := c.Query("status")
|
||||
var status *int
|
||||
if statusRaw != "" {
|
||||
parsedStatus, parseErr := strconv.Atoi(statusRaw)
|
||||
if parseErr != nil || parsedStatus < constants.PackageUsageStatusPending || parsedStatus > constants.PackageUsageStatusInvalidated {
|
||||
return errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
status = &parsedStatus
|
||||
}
|
||||
|
||||
result, err := h.assetService.GetPackages(c.UserContext(), asset.AssetType, asset.AssetID, page, pageSize)
|
||||
result, err := h.assetService.GetPackages(c.UserContext(), asset.AssetType, asset.AssetID, page, pageSize, status)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ func (h *ClientAssetHandler) GetAvailablePackages(c *fiber.Ctx) error {
|
||||
return errors.New(errors.CodeNoAvailablePackage, "当前无可购买套餐")
|
||||
}
|
||||
|
||||
packagesResult, err := h.assetService.GetPackages(resolved.SkipPermissionCtx, resolved.Asset.AssetType, resolved.Asset.AssetID, 1, 50)
|
||||
packagesResult, err := h.assetService.GetPackages(resolved.SkipPermissionCtx, resolved.Asset.AssetType, resolved.Asset.AssetID, 1, 50, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -140,12 +140,12 @@ type AssetTypeIDRequest struct {
|
||||
ID uint `path:"id" description:"资产ID" required:"true"`
|
||||
}
|
||||
|
||||
// AssetPackagesRequest 资产套餐列表请求(路径参数 + 分页)
|
||||
// AssetPackagesRequest 资产套餐列表请求(路径参数 + 分页 + 状态筛选)
|
||||
type AssetPackagesRequest struct {
|
||||
AssetType string `path:"asset_type" description:"资产类型:card 或 device" required:"true"`
|
||||
ID uint `path:"id" description:"资产ID" required:"true"`
|
||||
Page int `query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码(默认1)"`
|
||||
PageSize int `query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页条数(默认50,最大100)"`
|
||||
Identifier string `path:"identifier" description:"资产标识符(虚拟号/ICCID/IMEI/SN/MSISDN)" required:"true"`
|
||||
Page int `query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码(默认1)"`
|
||||
PageSize int `query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页条数(默认50,最大100)"`
|
||||
Status *int `query:"status" validate:"omitempty,min=0,max=4" minimum:"0" maximum:"4" description:"套餐状态 (0:待生效, 1:生效中, 2:已用完, 3:已过期, 4:已失效)"`
|
||||
}
|
||||
|
||||
// DeviceIDRequest 设备ID请求(路径参数)
|
||||
|
||||
@@ -41,9 +41,9 @@ func registerAssetRoutes(router fiber.Router, handler *admin.AssetHandler, walle
|
||||
|
||||
Register(assets, doc, groupPath, "GET", "/:identifier/packages", handler.Packages, RouteSpec{
|
||||
Summary: "资产套餐列表",
|
||||
Description: "查询该资产所有套餐记录,含虚流量换算结果。支持分页。",
|
||||
Description: "查询该资产所有套餐记录,含虚流量换算结果。支持分页与 status 状态筛选。",
|
||||
Tags: []string{"资产管理"},
|
||||
Input: new(dto.AssetIdentifierRequest),
|
||||
Input: new(dto.AssetPackagesRequest),
|
||||
Output: new(dto.AssetPackagesResult),
|
||||
Auth: true,
|
||||
})
|
||||
|
||||
@@ -648,9 +648,9 @@ func parseGatewayTime(raw gateway.FlexString) *time.Time {
|
||||
return &t
|
||||
}
|
||||
|
||||
// GetPackages 获取资产的所有套餐列表(支持分页)
|
||||
// GetPackages 获取资产的所有套餐列表(支持分页和状态筛选)
|
||||
// page 默认 1,pageSize 默认 50,pageSize 最大 100
|
||||
func (s *Service) GetPackages(ctx context.Context, assetType string, id uint, page, pageSize int) (*dto.AssetPackagesResult, error) {
|
||||
func (s *Service) GetPackages(ctx context.Context, assetType string, id uint, page, pageSize int, status *int) (*dto.AssetPackagesResult, error) {
|
||||
// 分页参数边界处理
|
||||
if page < 1 {
|
||||
page = 1
|
||||
@@ -661,6 +661,9 @@ func (s *Service) GetPackages(ctx context.Context, assetType string, id uint, pa
|
||||
if pageSize > 100 {
|
||||
pageSize = 100
|
||||
}
|
||||
if status != nil && (*status < constants.PackageUsageStatusPending || *status > constants.PackageUsageStatusInvalidated) {
|
||||
return nil, errors.New(errors.CodeInvalidParam, "套餐状态非法")
|
||||
}
|
||||
|
||||
// assetType 对应 Store 中的 carrierType:card→iot_card, device→device
|
||||
carrierType := assetType
|
||||
@@ -668,7 +671,7 @@ func (s *Service) GetPackages(ctx context.Context, assetType string, id uint, pa
|
||||
carrierType = "iot_card"
|
||||
}
|
||||
|
||||
usages, err := s.packageUsageStore.ListByCarrier(ctx, carrierType, id)
|
||||
usages, err := s.packageUsageStore.ListByCarrier(ctx, carrierType, id, status)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询套餐使用记录失败")
|
||||
}
|
||||
@@ -706,7 +709,6 @@ func (s *Service) GetPackages(ctx context.Context, assetType string, id uint, pa
|
||||
pkgType = pkg.PackageType
|
||||
enableVirtualData = pkg.EnableVirtualData
|
||||
}
|
||||
|
||||
item := &dto.AssetPackageResponse{
|
||||
PackageUsageID: u.ID,
|
||||
PackageID: u.PackageID,
|
||||
@@ -784,7 +786,6 @@ func (s *Service) GetCurrentPackage(ctx context.Context, assetType string, id ui
|
||||
pkgType = pkg.PackageType
|
||||
enableVirtualData = pkg.EnableVirtualData
|
||||
}
|
||||
|
||||
return &dto.AssetPackageResponse{
|
||||
PackageUsageID: usage.ID,
|
||||
PackageID: usage.PackageID,
|
||||
|
||||
@@ -1452,6 +1452,10 @@ func (s *Service) HandlePaymentCallback(ctx context.Context, orderNo string, pay
|
||||
}
|
||||
}
|
||||
|
||||
// 回调更新成功后,同步内存对象,确保激活套餐时写入 paid_amount 快照
|
||||
actualPaidAmountSnapshot := actualPaidAmount
|
||||
order.ActualPaidAmount = &actualPaidAmountSnapshot
|
||||
|
||||
return s.activatePackage(ctx, tx, order)
|
||||
})
|
||||
|
||||
|
||||
@@ -212,8 +212,8 @@ func (s *PackageUsageStore) GetActiveOrDepletedByCarrier(ctx context.Context, ca
|
||||
return &pkg, nil
|
||||
}
|
||||
|
||||
// ListByCarrier 查询载体的所有套餐使用记录(包括所有状态)
|
||||
func (s *PackageUsageStore) ListByCarrier(ctx context.Context, carrierType string, carrierID uint) ([]*model.PackageUsage, error) {
|
||||
// ListByCarrier 查询载体的套餐使用记录(可按状态筛选)
|
||||
func (s *PackageUsageStore) ListByCarrier(ctx context.Context, carrierType string, carrierID uint, status *int) ([]*model.PackageUsage, error) {
|
||||
var usages []*model.PackageUsage
|
||||
query := s.db.WithContext(ctx).Order("priority ASC, created_at DESC")
|
||||
|
||||
@@ -222,6 +222,9 @@ func (s *PackageUsageStore) ListByCarrier(ctx context.Context, carrierType strin
|
||||
} else if carrierType == "device" {
|
||||
query = query.Where("device_id = ?", carrierID)
|
||||
}
|
||||
if status != nil {
|
||||
query = query.Where("status = ?", *status)
|
||||
}
|
||||
|
||||
if err := query.Find(&usages).Error; err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user