优化价格处理逻辑,新增浮点数比较函数以提高价格比较的准确性。同时重构了临时字段更新逻辑,简化了代码结构,提升了可读性和维护性。

This commit is contained in:
wood chen 2025-04-15 00:18:03 +08:00
parent 49b8dce625
commit 7963ac8294
2 changed files with 63 additions and 43 deletions

View File

@ -2,6 +2,7 @@ package handlers
import ( import (
"fmt" "fmt"
"math"
"net/http" "net/http"
"strconv" "strconv"
"time" "time"
@ -107,6 +108,13 @@ func GetPrices(c *gin.Context) {
func ProcessPrice(price models.Price, existingPrice *models.Price, isAdmin bool, username string) (models.Price, bool, error) { func ProcessPrice(price models.Price, existingPrice *models.Price, isAdmin bool, username string) (models.Price, bool, error) {
// 如果是更新操作且存在现有记录 // 如果是更新操作且存在现有记录
if existingPrice != nil { if existingPrice != nil {
// 使用更精确的浮点数比较函数
priceEqual := func(a, b float64) bool {
// 使用epsilon值进行浮点数比较考虑到价格通常精确到小数点后4位
epsilon := 0.00001
return math.Abs(a-b) < epsilon
}
// 检查价格是否有变化 // 检查价格是否有变化
if isAdmin { if isAdmin {
// 管理员直接更新主字段,检查是否有实际变化 // 管理员直接更新主字段,检查是否有实际变化
@ -115,8 +123,8 @@ func ProcessPrice(price models.Price, existingPrice *models.Price, isAdmin bool,
existingPrice.BillingType == price.BillingType && existingPrice.BillingType == price.BillingType &&
existingPrice.ChannelType == price.ChannelType && existingPrice.ChannelType == price.ChannelType &&
existingPrice.Currency == price.Currency && existingPrice.Currency == price.Currency &&
existingPrice.InputPrice == price.InputPrice && priceEqual(existingPrice.InputPrice, price.InputPrice) &&
existingPrice.OutputPrice == price.OutputPrice && priceEqual(existingPrice.OutputPrice, price.OutputPrice) &&
existingPrice.PriceSource == price.PriceSource { existingPrice.PriceSource == price.PriceSource {
// 没有变化,不需要更新 // 没有变化,不需要更新
return *existingPrice, false, nil return *existingPrice, false, nil
@ -149,47 +157,51 @@ func ProcessPrice(price models.Price, existingPrice *models.Price, isAdmin bool,
return *existingPrice, true, nil return *existingPrice, true, nil
} else { } else {
// 普通用户更新临时字段,检查是否有实际变化 // 普通用户更新临时字段,检查是否有实际变化
// 创建临时值的指针
modelPtr := &price.Model
modelTypePtr := &price.ModelType
billingTypePtr := &price.BillingType
channelTypePtr := &price.ChannelType
currencyPtr := &price.Currency
inputPricePtr := &price.InputPrice
outputPricePtr := &price.OutputPrice
priceSourcePtr := &price.PriceSource
// 检查临时字段与现有主字段是否相同 // 先检查与主字段比较是否有变化
if (existingPrice.Model == price.Model && hasChanges := false
existingPrice.ModelType == price.ModelType &&
existingPrice.BillingType == price.BillingType && if existingPrice.Model != price.Model ||
existingPrice.ChannelType == price.ChannelType && existingPrice.ModelType != price.ModelType ||
existingPrice.Currency == price.Currency && existingPrice.BillingType != price.BillingType ||
existingPrice.InputPrice == price.InputPrice && existingPrice.ChannelType != price.ChannelType ||
existingPrice.OutputPrice == price.OutputPrice && existingPrice.Currency != price.Currency ||
existingPrice.PriceSource == price.PriceSource) || !priceEqual(existingPrice.InputPrice, price.InputPrice) ||
// 或者检查临时字段与现有临时字段是否相同 !priceEqual(existingPrice.OutputPrice, price.OutputPrice) ||
(existingPrice.TempModel != nil && *existingPrice.TempModel == price.Model && existingPrice.PriceSource != price.PriceSource {
existingPrice.TempModelType != nil && *existingPrice.TempModelType == price.ModelType && hasChanges = true
existingPrice.TempBillingType != nil && *existingPrice.TempBillingType == price.BillingType && }
existingPrice.TempChannelType != nil && *existingPrice.TempChannelType == price.ChannelType &&
existingPrice.TempCurrency != nil && *existingPrice.TempCurrency == price.Currency && // 如果与主字段有变化,再检查与临时字段比较是否有变化
existingPrice.TempInputPrice != nil && *existingPrice.TempInputPrice == price.InputPrice && if hasChanges && existingPrice.TempModel != nil {
existingPrice.TempOutputPrice != nil && *existingPrice.TempOutputPrice == price.OutputPrice && // 检查是否与已有的临时字段相同
existingPrice.TempPriceSource != nil && *existingPrice.TempPriceSource == price.PriceSource) { if *existingPrice.TempModel == price.Model &&
// 没有变化,不需要更新 (existingPrice.TempModelType == nil || *existingPrice.TempModelType == price.ModelType) &&
(existingPrice.TempBillingType == nil || *existingPrice.TempBillingType == price.BillingType) &&
(existingPrice.TempChannelType == nil || *existingPrice.TempChannelType == price.ChannelType) &&
(existingPrice.TempCurrency == nil || *existingPrice.TempCurrency == price.Currency) &&
(existingPrice.TempInputPrice == nil || priceEqual(*existingPrice.TempInputPrice, price.InputPrice)) &&
(existingPrice.TempOutputPrice == nil || priceEqual(*existingPrice.TempOutputPrice, price.OutputPrice)) &&
(existingPrice.TempPriceSource == nil || *existingPrice.TempPriceSource == price.PriceSource) {
// 与之前提交的临时值相同,不需要更新
hasChanges = false
}
}
// 如果没有实际变化,直接返回
if !hasChanges {
return *existingPrice, false, nil return *existingPrice, false, nil
} }
// 有变化,更新临时字段 // 有变化,更新临时字段
existingPrice.TempModel = modelPtr existingPrice.TempModel = &price.Model
existingPrice.TempModelType = modelTypePtr existingPrice.TempModelType = &price.ModelType
existingPrice.TempBillingType = billingTypePtr existingPrice.TempBillingType = &price.BillingType
existingPrice.TempChannelType = channelTypePtr existingPrice.TempChannelType = &price.ChannelType
existingPrice.TempCurrency = currencyPtr existingPrice.TempCurrency = &price.Currency
existingPrice.TempInputPrice = inputPricePtr existingPrice.TempInputPrice = &price.InputPrice
existingPrice.TempOutputPrice = outputPricePtr existingPrice.TempOutputPrice = &price.OutputPrice
existingPrice.TempPriceSource = priceSourcePtr existingPrice.TempPriceSource = &price.PriceSource
existingPrice.Status = "pending" existingPrice.Status = "pending"
existingPrice.UpdatedBy = &username existingPrice.UpdatedBy = &username
@ -212,7 +224,6 @@ func ProcessPrice(price models.Price, existingPrice *models.Price, isAdmin bool,
return price, false, err return price, false, err
} }
return price, true, nil return price, true, nil
} }
} }

View File

@ -51,12 +51,12 @@ func GetPriceRates(c *gin.Context) {
if price.Currency == "USD" { if price.Currency == "USD" {
// 如果是美元除以2 // 如果是美元除以2
inputRate = price.InputPrice / 2 inputRate = round(price.InputPrice/2, 2)
outputRate = price.OutputPrice / 2 outputRate = round(price.OutputPrice/2, 2)
} else { } else {
// 如果是人民币或其他货币除以14 // 如果是人民币或其他货币除以14
inputRate = price.InputPrice / 14 inputRate = round(price.InputPrice/14, 2)
outputRate = price.OutputPrice / 14 outputRate = round(price.OutputPrice/14, 2)
} }
// 创建当前价格的PriceRate // 创建当前价格的PriceRate
@ -104,3 +104,12 @@ func GetPriceRates(c *gin.Context) {
func ClearRatesCache() { func ClearRatesCache() {
database.GlobalCache.Delete("price_rates") database.GlobalCache.Delete("price_rates")
} }
// round 四舍五入到指定小数位
func round(num float64, precision int) float64 {
precision10 := float64(1)
for i := 0; i < precision; i++ {
precision10 *= 10
}
return float64(int(num*precision10+0.5)) / precision10
}