让 C 端在续费前展示当前应付价格
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m11s

Constraint: 续费展示价必须与当前销售渠道的生效零售价一致
Rejected: 新增专用续费报价接口 | 现有资产信息已承载续费入口上下文
Confidence: high
Scope-risk: narrow
Directive: 下单时仍须重新校验续费资格和最终价格
Tested: go build ./internal/handler/app
Not-tested: 按用户要求未添加或运行测试
This commit is contained in:
2026-07-30 16:23:03 +08:00
parent faf973accb
commit e2687de338
4 changed files with 34 additions and 0 deletions

View File

@@ -191,6 +191,10 @@ func (h *ClientAssetHandler) GetAssetInfo(c *fiber.Ctx) error {
if err != nil {
return err
}
renewalPrice, err := h.getRenewalPrice(resolved.SkipPermissionCtx, currentPackageID, resolved.SellerShopID)
if err != nil {
return err
}
if h.paymentMethodPolicy == nil {
return errors.New(errors.CodeNoPaymentConfig)
}
@@ -239,6 +243,7 @@ func (h *ClientAssetHandler) GetAssetInfo(c *fiber.Ctx) error {
ActivatedAt: resolved.Asset.ActivatedAt,
CurrentPackage: resolved.Asset.CurrentPackage,
CurrentPackageID: currentPackageID,
RenewalPrice: renewalPrice,
CurrentPackageUsageID: resolved.Asset.CurrentPackageUsageID,
CurrentPackageActivatedAt: resolved.Asset.CurrentPackageActivatedAt,
CurrentPackageExpiresAt: resolved.Asset.CurrentPackageExpiresAt,
@@ -302,6 +307,26 @@ func (h *ClientAssetHandler) getCurrentPackageID(ctx context.Context, usageID *u
return usage.PackageID, nil
}
func (h *ClientAssetHandler) getRenewalPrice(ctx context.Context, packageID, sellerShopID uint) (int64, error) {
if packageID == 0 {
return 0, nil
}
pkg, err := h.packageStore.GetByID(ctx, packageID)
if err != nil {
return 0, errors.Wrap(errors.CodeDatabaseError, err, "查询续费套餐失败")
}
if sellerShopID == 0 {
return packageprice.PackageEffectiveRetailPrice(pkg), nil
}
allocation, err := h.shopPackageAllocationStore.GetByShopAndPackageForSystem(ctx, sellerShopID, packageID)
if err != nil {
return 0, errors.Wrap(errors.CodeDatabaseError, err, "查询续费套餐价格失败")
}
return packageprice.AllocationEffectiveRetailPrice(allocation), nil
}
func (h *ClientAssetHandler) dispatchAssetReadObservations(ctx context.Context, asset *dto.AssetResolveResponse) {
if h.observationSeries == nil || asset == nil {
return