@@ -28,16 +28,6 @@ const STUCK_LABEL: Record<string, string> = {
const fmtMs = ( ms : number | null ) = > ( ms == null ? '-' : ` ${ ( ms / 1000 ) . toFixed ( 1 ) } s ` ) ;
const cents = ( c : number | null ) = > ( c == null ? '-' : yuan ( c ) ) ;
// LLM 成本估算:(input + output) token / 1e6 × 每百万 token 单价(元)。单价由页面输入框配置(localStorage)。
const calcCost = ( inTok : number | null , outTok : number | null , price : number | null ) : number | null = > {
if ( price == null || Number . isNaN ( price ) ) return null ;
if ( inTok == null && outTok == null ) return null ;
return ( ( ( inTok ? ? 0 ) + ( outTok ? ? 0 ) ) / 1 _000_000 ) * price ;
} ;
const fmtCost = ( c : number | null ) = > ( c == null ? '-' : ` ¥ ${ c . toFixed ( 4 ) } ` ) ;
const fmtTok = ( inTok : number | null , outTok : number | null ) = >
inTok == null && outTok == null ? '-' : ` ${ inTok ? ? 0 } / ${ outTok ? ? 0 } ` ;
// LLM message content 常是 json.dumps 的卡片列表;能 parse 成 JSON 就缩进展开,否则原样。
function pretty ( s : string | null ) : string {
if ( ! s ) return '' ;
@@ -60,18 +50,6 @@ export default function ComparisonRecordsPage() {
const [ phone , setPhone ] = useState ( '' ) ;
const [ status , setStatus ] = useState < string | undefined > ( ) ;
const [ applied , setApplied ] = useState < Record < string , unknown > > ( { } ) ;
// LLM 单价(元/百万 token),本地持久化;仅用于前端估算成本,不入库、不影响其它页面
const [ pricePerMTok , setPricePerMTok ] = useState < number | null > ( ( ) = > {
if ( typeof window === 'undefined' ) return null ;
const v = localStorage . getItem ( 'llm_price_per_mtok' ) ;
return v != null && v !== '' ? Number ( v ) : null ;
} ) ;
const onPriceChange = ( v : number | null ) = > {
setPricePerMTok ( v ) ;
if ( typeof window === 'undefined' ) return ;
if ( v == null ) localStorage . removeItem ( 'llm_price_per_mtok' ) ;
else localStorage . setItem ( 'llm_price_per_mtok' , String ( v ) ) ;
} ;
const { items , total , page , pageSize , loading , onChange } =
usePagedList < ComparisonRecordListItem > ( '/admin/api/comparison-records' , applied ) ;
@@ -142,18 +120,6 @@ export default function ComparisonRecordsPage() {
width : 50 ,
render : ( v : number | null ) = > ( v ? < span style = { { color : '#cf1322' } } > { v } < / span > : v ? ? '-' ) ,
} ,
{
title : 'Token(入/出)' ,
key : 'tokens' ,
width : 110 ,
render : ( _ , r ) = > fmtTok ( r . input_tokens , r . output_tokens ) ,
} ,
{
title : '成本' ,
key : 'cost' ,
width : 90 ,
render : ( _ , r ) = > fmtCost ( calcCost ( r . input_tokens , r . output_tokens , pricePerMTok ) ) ,
} ,
{
title : '机型/ROM' ,
key : 'device' ,
@@ -206,15 +172,6 @@ export default function ComparisonRecordsPage() {
/ >
< Button type = "primary" onClick = { search } > 查 询 < / Button >
< Button onClick = { reset } > 重 置 < / Button >
< InputNumber
placeholder = "LLM 单价"
value = { pricePerMTok }
onChange = { onPriceChange }
min = { 0 }
step = { 0.1 }
style = { { width : 210 } }
addonAfter = "元/百万token"
/ >
< / Space >
< Table
@@ -230,7 +187,7 @@ export default function ComparisonRecordsPage() {
showTotal : ( t ) = > ` 共 ${ t } 条 ` ,
onChange ,
} }
scroll = { { x : 1520 } }
scroll = { { x : 1320 } }
onRow = { ( r ) = > ( { onClick : ( ) = > openDetail ( r . id ) , style : { cursor : 'pointer' } } ) }
/ >
@@ -247,17 +204,6 @@ export default function ComparisonRecordsPage() {
< Descriptions.Item label = "耗时" > { fmtMs ( detail . total_ms ) } < / Descriptions.Item >
< Descriptions.Item label = "步数" > { detail . step_count ? ? '-' } < / Descriptions.Item >
< Descriptions.Item label = "LLM 次数/重试" > { detail . llm_call_count ? ? '-' } / { detail . retry_count ? ? '-' } < / Descriptions.Item >
< Descriptions.Item label = "Token(入/出/合计)" >
{ detail . input_tokens == null && detail . output_tokens == null
? '-'
: ` ${ detail . input_tokens ? ? 0 } / ${ detail . output_tokens ? ? 0 } / ${ ( detail . input_tokens ? ? 0 ) + ( detail . output_tokens ? ? 0 ) } ` }
< / Descriptions.Item >
< Descriptions.Item label = "估算成本" >
{ fmtCost ( calcCost ( detail . input_tokens , detail . output_tokens , pricePerMTok ) ) }
{ pricePerMTok == null && ( detail . input_tokens != null || detail . output_tokens != null )
? < span style = { { color : '#999' , fontSize : 12 } } > ( 顶 部 填 LLM 单 价 后 显 示 ) < / span >
: null }
< / Descriptions.Item >
< Descriptions.Item label = "源平台" > { detail . source_platform_name || '-' } ( { cents ( detail . source_price_cents ) } ) < / Descriptions.Item >
< Descriptions.Item label = "最优" > { detail . best_platform_name || '-' } ( { cents ( detail . best_price_cents ) } ) < / Descriptions.Item >
< Descriptions.Item label = "省" span = { 2 } > { cents ( detail . saved_amount_cents ) } { detail . is_source_best ? '(源平台最便宜)' : '' } < / Descriptions.Item >