fix: TieredPricingEditor 缓存价格处理优化

- 缓存价格计算精度从 2 位小数改为 4 位,支持更精细的价格
- 分离 syncToParent 和 getFinalTiers 职责:
  - syncToParent: 只同步用户实际输入的值
  - getFinalTiers: 提交时获取包含自动计算的最终数据
- GlobalModelFormDialog 和 ProviderModelFormDialog 提交时调用 getFinalTiers
This commit is contained in:
fawney19
2025-12-12 15:43:00 +08:00
parent 53bf74429e
commit 06bd178244
3 changed files with 65 additions and 19 deletions

View File

@@ -287,32 +287,32 @@ function formatTokens(tokens: number): string {
// 缓存价格自动计算
function getAutoCacheCreation(index: number): number {
const inputPrice = localTiers.value[index]?.input_price_per_1m || 0
return parseFloat((inputPrice * 1.25).toFixed(2))
return parseFloat((inputPrice * 1.25).toFixed(4))
}
function getAutoCacheRead(index: number): number {
const inputPrice = localTiers.value[index]?.input_price_per_1m || 0
return parseFloat((inputPrice * 0.1).toFixed(2))
return parseFloat((inputPrice * 0.1).toFixed(4))
}
function getAutoCache1h(index: number): number {
const inputPrice = localTiers.value[index]?.input_price_per_1m || 0
return parseFloat((inputPrice * 2).toFixed(2))
return parseFloat((inputPrice * 2).toFixed(4))
}
function getCacheCreationPlaceholder(index: number): string {
const auto = getAutoCacheCreation(index)
return auto > 0 ? auto.toFixed(2) : '自动'
return auto > 0 ? String(auto) : '自动'
}
function getCacheReadPlaceholder(index: number): string {
const auto = getAutoCacheRead(index)
return auto > 0 ? auto.toFixed(2) : '自动'
return auto > 0 ? String(auto) : '自动'
}
function getCache1hPlaceholder(index: number): string {
const auto = getAutoCache1h(index)
return auto > 0 ? auto.toFixed(2) : '自动'
return auto > 0 ? String(auto) : '自动'
}
function getCacheCreationDisplay(index: number): string | number {
@@ -346,7 +346,7 @@ function getCache1hDisplay(index: number): string | number {
return ''
}
// 同步到父组件(包含自动计算的缓存价格
// 同步到父组件(只同步用户实际输入的值,不自动填充
function syncToParent() {
if (validationError.value) return
@@ -357,6 +357,36 @@ function syncToParent() {
output_price_per_1m: t.output_price_per_1m,
}
// 缓存创建价格:只有手动设置才同步
if (cacheManuallySet[i]?.creation && t.cache_creation_price_per_1m != null) {
tier.cache_creation_price_per_1m = t.cache_creation_price_per_1m
}
// 缓存读取价格:只有手动设置才同步
if (cacheManuallySet[i]?.read && t.cache_read_price_per_1m != null) {
tier.cache_read_price_per_1m = t.cache_read_price_per_1m
}
// 缓存 TTL 价格1h 缓存)- 只有启用 1h 缓存能力且手动设置时才处理
if (props.showCache1h && cacheManuallySet[i]?.cache1h && t.cache_ttl_pricing?.length) {
tier.cache_ttl_pricing = t.cache_ttl_pricing
}
return tier
})
emit('update:modelValue', { tiers })
}
// 获取最终提交的数据(包含自动计算的缓存价格)
function getFinalTiers(): PricingTier[] {
return localTiers.value.map((t, i) => {
const tier: PricingTier = {
up_to: t.up_to,
input_price_per_1m: t.input_price_per_1m,
output_price_per_1m: t.output_price_per_1m,
}
// 缓存创建价格:手动设置则用设置值,否则自动计算
if (cacheManuallySet[i]?.creation && t.cache_creation_price_per_1m != null) {
tier.cache_creation_price_per_1m = t.cache_creation_price_per_1m
@@ -374,20 +404,21 @@ function syncToParent() {
// 缓存 TTL 价格1h 缓存)- 只有启用 1h 缓存能力时才处理
if (props.showCache1h) {
if (cacheManuallySet[i]?.cache1h && t.cache_ttl_pricing?.length) {
// 手动设置则用设置值
tier.cache_ttl_pricing = t.cache_ttl_pricing
} else if (t.input_price_per_1m > 0) {
// 否则自动计算
tier.cache_ttl_pricing = [{ ttl_minutes: 60, cache_creation_price_per_1m: getAutoCache1h(i) }]
}
}
return tier
})
emit('update:modelValue', { tiers })
}
// 暴露给父组件调用
defineExpose({
getFinalTiers,
})
function parseFloatInput(value: string | number): number {
const num = typeof value === 'string' ? parseFloat(value) : value
return isNaN(num) ? 0 : num
@@ -515,9 +546,13 @@ function removeTier(index: number) {
delete cacheManuallySet[index]
// 重新整理 cacheManuallySet 的索引
const newManuallySet: Record<number, { creation: boolean; read: boolean }> = {}
const newManuallySet: Record<
number,
{ creation: boolean; read: boolean; cache1h: boolean }
> = {}
localTiers.value.forEach((_, i) => {
newManuallySet[i] = cacheManuallySet[i] || { creation: false, read: false }
newManuallySet[i] =
cacheManuallySet[i] || { creation: false, read: false, cache1h: false }
})
Object.keys(cacheManuallySet).forEach(k => delete cacheManuallySet[Number(k)])
Object.assign(cacheManuallySet, newManuallySet)