Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
client
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
486ee646
authored
Sep 17, 2026
by
renyizhao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
价格展示修改
parent
b40dc588
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
87 additions
and
12 deletions
+87
-12
src/views/computingResource/resourceList.vue
+55
-6
src/views/console/components/model-card.vue
+32
-6
No files found.
src/views/computingResource/resourceList.vue
View file @
486ee646
...
...
@@ -106,10 +106,12 @@
<
template
#
default=
"{ row }"
>
<div
v-if=
"Number(row?.quotaType) === 1"
>
-
</div>
<div
v-else-if=
"row?.billingMode === 'tiered_expr' && row?.tiers && row.tiers.length > 0"
>
<b>
¥
{{
formatPrice
(
row
.
tiers
[
0
].
inputRatio
)
}}
/ 1M
</b>
<b>
{{
formatDynamicRange
(
row
.
tiers
)
}}
</b>
<span
style=
"margin-left: 2px; color: #999; font-size: 12px;"
>
/ 1M
</span>
</div>
<div
v-else
>
<b>
¥
{{
formatPrice
(
row
.
inputPrice
)
}}
/ 1M
</b>
<b>
¥
{{
formatPrice
(
row
.
inputPrice
)
}}
</b>
<span
style=
"margin-left: 2px; color: #999; font-size: 12px;"
>
/ 1M
</span>
</div>
</
template
>
</el-table-column>
...
...
@@ -117,10 +119,12 @@
<
template
#
default=
"{ row }"
>
<div
v-if=
"Number(row?.quotaType) === 1"
>
-
</div>
<div
v-else-if=
"row?.billingMode === 'tiered_expr' && row?.tiers && row.tiers.length > 0"
>
<b>
¥
{{
formatPrice
(
row
.
tiers
[
0
].
outputRatio
)
}}
/ 1M
</b>
<b>
{{
formatDynamicRange
(
row
.
tiers
)
}}
</b>
<span
style=
"margin-left: 2px; color: #999; font-size: 12px;"
>
/ 1M
</span>
</div>
<div
v-else
>
<b>
¥
{{
formatPrice
(
row
.
outputPrice
)
}}
/ 1M
</b>
<b>
¥
{{
formatPrice
(
row
.
outputPrice
)
}}
</b>
<span
style=
"margin-left: 2px; color: #999; font-size: 12px;"
>
/ 1M
</span>
</div>
</
template
>
</el-table-column>
...
...
@@ -469,8 +473,8 @@
<div
class=
"tier-name"
>
{{
tier
.
name
}}
</div>
<div
v-if=
"tier.conditionDesc"
class=
"tier-condition"
>
{{
tier
.
conditionDesc
}}
</div>
</div>
<div
class=
"tier-cell price-cell"
>
{{
formatModelPrice
(
tier
.
inputRatio
)
}}
</div>
<div
class=
"tier-cell price-cell"
>
{{
formatModelPrice
(
tier
.
outputRatio
)
}}
</div>
<div
class=
"tier-cell price-cell"
>
{{
formatModelPrice
(
getTierDisplayPrice
(
tier
,
'input'
)
)
}}
</div>
<div
class=
"tier-cell price-cell"
>
{{
formatModelPrice
(
getTierDisplayPrice
(
tier
,
'output'
)
)
}}
</div>
<div
v-for=
"col in tierExtraPriceColumns"
:key=
"col.key"
class=
"tier-cell price-cell"
>
{{
tier
[
col
.
key
]
!=
null
&&
tier
[
col
.
key
]
>
0
?
formatModelPrice
(
tier
[
col
.
key
])
:
'-'
}}
</div>
...
...
@@ -628,6 +632,18 @@ function formatModelPrice(price) {
return
num
.
toFixed
(
4
)
}
// 提取动态计费档位的展示价格:seedance 风格优先用 tokensMultiplier(每百万 token 价格),
// 其次才是 inputRatio/outputRatio
function
getTierDisplayPrice
(
tier
,
side
)
{
if
(
!
tier
)
return
null
if
(
tier
.
tokensMultiplier
!=
null
&&
Number
(
tier
.
tokensMultiplier
)
>
0
)
{
return
tier
.
tokensMultiplier
}
if
(
side
===
'output'
)
return
tier
.
outputRatio
!=
null
?
tier
.
outputRatio
:
null
if
(
side
===
'input'
)
return
tier
.
inputRatio
!=
null
?
tier
.
inputRatio
:
null
return
tier
.
inputRatio
!=
null
?
tier
.
inputRatio
:
null
}
// 格式化条件描述
function
formatConditionDesc
(
desc
)
{
if
(
!
desc
)
return
''
...
...
@@ -704,6 +720,10 @@ const tierExtraPriceColumns = computed(() => {
if
(
tiers
.
some
(
t
=>
t
.
audioOutputRatio
!=
null
&&
t
.
audioOutputRatio
>
0
))
{
columns
.
push
({
key
:
'audioOutputRatio'
,
label
:
'音频输出'
})
}
// 检查 tokensMultiplier(seedance 风格:u("tokens") * X / 1000000 中的 X)
if
(
tiers
.
some
(
t
=>
t
.
tokensMultiplier
!=
null
&&
Number
(
t
.
tokensMultiplier
)
>
0
))
{
columns
.
push
({
key
:
'tokensMultiplier'
,
label
:
'每百万token价格'
})
}
return
columns
})
...
...
@@ -1125,6 +1145,35 @@ function formatPrice(price) {
return
num
.
toFixed
(
4
).
replace
(
/
\.?
0+$/
,
''
)
}
// 动态计费模型汇总价格范围:聚合所有 tiers 中有值的价格字段(按 tokensMultiplier > inputRatio > outputRatio 优先级),
// 返回 { min, max, same }。same=true 表示所有档价格一致,可退化为单值展示。
function
getDynamicPriceRange
(
tiers
)
{
if
(
!
Array
.
isArray
(
tiers
)
||
tiers
.
length
===
0
)
return
null
let
min
=
Infinity
let
max
=
-
Infinity
const
candidateFields
=
[
'tokensMultiplier'
,
'inputRatio'
,
'outputRatio'
]
for
(
const
tier
of
tiers
)
{
if
(
!
tier
)
continue
for
(
const
field
of
candidateFields
)
{
const
v
=
Number
(
tier
[
field
])
if
(
Number
.
isFinite
(
v
)
&&
v
>
0
)
{
if
(
v
<
min
)
min
=
v
if
(
v
>
max
)
max
=
v
}
}
}
if
(
min
===
Infinity
||
max
===
-
Infinity
)
return
null
return
{
min
,
max
,
same
:
min
===
max
}
}
// 渲染动态计费模型的价格范围文案。与 NewAPI 卡片一致:单档展示 ¥X,多档展示 ¥X ~ ¥Y。
function
formatDynamicRange
(
tiers
)
{
const
range
=
getDynamicPriceRange
(
tiers
)
if
(
!
range
)
return
'¥-'
if
(
range
.
same
)
return
`¥
${
formatPrice
(
range
.
min
)}
`
return
`¥
${
formatPrice
(
range
.
min
)}
~ ¥
${
formatPrice
(
range
.
max
)}
`
}
function
billingTagText
(
model
)
{
if
(
Number
(
model
?.
quotaType
)
===
1
)
return
'按次收费'
if
(
model
?.
billingMode
===
'tiered_expr'
)
return
'动态计费'
...
...
src/views/console/components/model-card.vue
View file @
486ee646
...
...
@@ -39,13 +39,10 @@
<template
v-if=
"isPerCall"
>
<span>
每次调用
<b>
¥
{{
formatPrice
(
model
.
inputPrice
)
}}
</b></span>
</
template
>
<!-- 分档计费:显示
第一档
-->
<!-- 分档计费:显示
价格范围(与 NewAPI 卡片一致:¥X ~ ¥Y / 1M token)
-->
<
template
v-else-if=
"hasTieredPrice"
>
<span>
输入价格:
<b>
¥
{{
formatPrice
(
model
.
tiers
[
0
].
inputRatio
)
}}
</b></span>
<span
class=
"unit"
>
/ 1M
</span>
<span
class=
"divider"
></span>
<span>
输出价格:
<b>
¥
{{
formatPrice
(
model
.
tiers
[
0
].
outputRatio
)
}}
</b></span>
<span
class=
"unit"
>
/ 1M
</span>
<span>
动态价格:
<b>
{{
formatDynamicRange
(
model
.
tiers
)
}}
</b></span>
<span
class=
"unit"
>
/ 1M token
</span>
</
template
>
<!-- 按量计费:输入/输出 -->
<
template
v-else
>
...
...
@@ -134,6 +131,35 @@ function formatPrice(price) {
if
(
Number
.
isNaN
(
num
))
return
'-'
return
num
.
toFixed
(
4
).
replace
(
/
\.?
0+$/
,
''
)
}
// 动态计费模型汇总价格范围:聚合所有 tiers 中有值的价格字段(按 tokensMultiplier > inputRatio > outputRatio 优先级),
// 返回 { min, max, same }。same=true 表示所有档价格一致,可退化为单值展示。
function
getDynamicPriceRange
(
tiers
)
{
if
(
!
Array
.
isArray
(
tiers
)
||
tiers
.
length
===
0
)
return
null
let
min
=
Infinity
let
max
=
-
Infinity
const
candidateFields
=
[
'tokensMultiplier'
,
'inputRatio'
,
'outputRatio'
]
for
(
const
tier
of
tiers
)
{
if
(
!
tier
)
continue
for
(
const
field
of
candidateFields
)
{
const
v
=
Number
(
tier
[
field
])
if
(
Number
.
isFinite
(
v
)
&&
v
>
0
)
{
if
(
v
<
min
)
min
=
v
if
(
v
>
max
)
max
=
v
}
}
}
if
(
min
===
Infinity
||
max
===
-
Infinity
)
return
null
return
{
min
,
max
,
same
:
min
===
max
}
}
// 渲染动态计费模型的价格范围文案:单档 ¥X,多档 ¥X ~ ¥Y。
function
formatDynamicRange
(
tiers
)
{
const
range
=
getDynamicPriceRange
(
tiers
)
if
(
!
range
)
return
'¥-'
if
(
range
.
same
)
return
`¥
${
formatPrice
(
range
.
min
)}
`
return
`¥
${
formatPrice
(
range
.
min
)}
~ ¥
${
formatPrice
(
range
.
max
)}
`
}
</
script
>
<
style
scoped
lang=
"scss"
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment