统一处理百分比和系数两种折扣输入方式,增加边界保护 在金额计算中使用math.Round进行四舍五入处理 添加相关单元测试确保计算准确性
This commit is contained in:
@@ -3,6 +3,7 @@ package portal
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math"
|
||||
|
||||
"github.com/perfect-panel/server/pkg/tool"
|
||||
|
||||
@@ -43,7 +44,7 @@ func (l *PrePurchaseOrderLogic) PrePurchaseOrder(req *types.PrePurchaseOrderRequ
|
||||
discount = getDiscount(dis, req.Quantity)
|
||||
}
|
||||
price := sub.UnitPrice * req.Quantity
|
||||
amount := int64(float64(price) * discount)
|
||||
amount := int64(math.Round(float64(price) * discount))
|
||||
discountAmount := price - amount
|
||||
var coupon int64
|
||||
if req.Coupon != "" {
|
||||
|
||||
@@ -3,6 +3,7 @@ package portal
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -184,7 +185,7 @@ func (l *PurchaseCheckoutLogic) alipayF2fPayment(pay *payment.Payment, info *ord
|
||||
l.Errorw("[PurchaseCheckout] queryExchangeRate error", logger.Field("error", err.Error()))
|
||||
return "", errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "queryExchangeRate error: %s", err.Error())
|
||||
}
|
||||
convertAmount := int64(amount * 100) // Convert to cents for API
|
||||
convertAmount := int64(math.Round(amount * 100)) // Convert to cents for API
|
||||
|
||||
// Create pre-payment trade and generate QR code
|
||||
QRCode, err := client.PreCreateTrade(l.ctx, alipay.Order{
|
||||
@@ -222,7 +223,7 @@ func (l *PurchaseCheckoutLogic) stripePayment(config string, info *order.Order,
|
||||
l.Errorw("[PurchaseCheckout] queryExchangeRate error", logger.Field("error", err.Error()))
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "queryExchangeRate error: %s", err.Error())
|
||||
}
|
||||
convertAmount := int64(amount * 100) // Convert to cents for Stripe API
|
||||
convertAmount := int64(math.Round(amount * 100)) // Convert to cents for Stripe API
|
||||
|
||||
// Create Stripe payment sheet for client-side processing
|
||||
result, err := client.CreatePaymentSheet(&stripe.Order{
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/perfect-panel/server/internal/model/order"
|
||||
@@ -67,7 +68,7 @@ func (l *PurchaseLogic) Purchase(req *types.PortalPurchaseRequest) (resp *types.
|
||||
}
|
||||
price := sub.UnitPrice * req.Quantity
|
||||
// discount amount
|
||||
amount := int64(float64(price) * discount)
|
||||
amount := int64(math.Round(float64(price) * discount))
|
||||
discountAmount := price - amount
|
||||
|
||||
var couponAmount int64 = 0
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
package portal
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/perfect-panel/server/internal/model/coupon"
|
||||
"github.com/perfect-panel/server/internal/model/payment"
|
||||
"github.com/perfect-panel/server/internal/types"
|
||||
)
|
||||
|
||||
func getDiscount(discounts []types.SubscribeDiscount, inputMonths int64) float64 {
|
||||
var finalDiscount int64 = 100
|
||||
|
||||
for _, discount := range discounts {
|
||||
if inputMonths >= discount.Quantity && int64(discount.Discount*100) < finalDiscount {
|
||||
finalDiscount = int64(discount.Discount * 100)
|
||||
final := 1.0
|
||||
for _, d := range discounts {
|
||||
val := d.Discount
|
||||
if val > 1 && val <= 100 {
|
||||
val = val / 100.0
|
||||
}
|
||||
if val < 0 {
|
||||
val = 0
|
||||
}
|
||||
if inputMonths >= d.Quantity && val < final {
|
||||
final = val
|
||||
}
|
||||
}
|
||||
return float64(finalDiscount) / float64(100)
|
||||
return final
|
||||
}
|
||||
|
||||
func calculateCoupon(amount int64, couponInfo *coupon.Coupon) int64 {
|
||||
if couponInfo.Type == 1 {
|
||||
return int64(float64(amount) * (float64(couponInfo.Discount) / float64(100)))
|
||||
return int64(math.Round(float64(amount) * (float64(couponInfo.Discount) / float64(100))))
|
||||
} else {
|
||||
return min(couponInfo.Discount, amount)
|
||||
}
|
||||
@@ -39,5 +47,5 @@ func calculateFee(amount int64, config *payment.Payment) int64 {
|
||||
case 3:
|
||||
fee = float64(amount)*(float64(config.FeePercent)/float64(100)) + float64(config.FeeAmount)
|
||||
}
|
||||
return int64(fee)
|
||||
return int64(math.Round(fee))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package portal
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/perfect-panel/server/internal/types"
|
||||
)
|
||||
|
||||
func TestGetDiscount_Coefficient(t *testing.T) {
|
||||
discounts := []types.SubscribeDiscount{{Quantity: 7, Discount: 0.9}}
|
||||
got := getDiscount(discounts, 7)
|
||||
if got != 0.9 {
|
||||
t.Fatalf("expected 0.9, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDiscount_Percentage(t *testing.T) {
|
||||
discounts := []types.SubscribeDiscount{{Quantity: 7, Discount: 90}}
|
||||
got := getDiscount(discounts, 7)
|
||||
if got != 0.9 {
|
||||
t.Fatalf("expected 0.9 from 90%%, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user