@@ -25,21 +25,14 @@ import {
2525 Tooltip ,
2626 Popover ,
2727 Typography ,
28- Button
2928} from '@douyinfe/semi-ui' ;
3029import {
31- timestamp2string ,
3230 renderGroup ,
3331 renderQuota ,
3432 stringToColor ,
3533 getLogOther ,
3634 renderModelTag ,
37- renderClaudeLogContent ,
38- renderLogContent ,
3935 renderModelPriceSimple ,
40- renderAudioModelPrice ,
41- renderClaudeModelPrice ,
42- renderModelPrice ,
4336} from '../../../helpers' ;
4437import { IconHelpCircle } from '@douyinfe/semi-icons' ;
4538import { Route , Sparkles } from 'lucide-react' ;
@@ -330,6 +323,142 @@ function getPromptCacheSummary(other) {
330323 } ;
331324}
332325
326+ function normalizeDetailText ( detail ) {
327+ return String ( detail || '' )
328+ . replace ( / \n \r / g, '\n' )
329+ . replace ( / \r \n / g, '\n' ) ;
330+ }
331+
332+ function getUsageLogGroupSummary ( groupRatio , userGroupRatio , t ) {
333+ const parsedUserGroupRatio = Number ( userGroupRatio ) ;
334+ const useUserGroupRatio =
335+ Number . isFinite ( parsedUserGroupRatio ) && parsedUserGroupRatio !== - 1 ;
336+ const ratio = useUserGroupRatio ? userGroupRatio : groupRatio ;
337+ if ( ratio === undefined || ratio === null || ratio === '' ) {
338+ return '' ;
339+ }
340+ return `${ useUserGroupRatio ? t ( '专属倍率' ) : t ( '分组' ) } ${ formatRatio ( ratio ) } x` ;
341+ }
342+
343+ function renderCompactDetailSummary ( summarySegments ) {
344+ const segments = Array . isArray ( summarySegments )
345+ ? summarySegments . filter ( ( segment ) => segment ?. text )
346+ : [ ] ;
347+ if ( ! segments . length ) {
348+ return null ;
349+ }
350+
351+ return (
352+ < div
353+ style = { {
354+ maxWidth : 180 ,
355+ lineHeight : 1.35 ,
356+ } }
357+ >
358+ { segments . map ( ( segment , index ) => (
359+ < Typography . Text
360+ key = { `${ segment . text } -${ index } ` }
361+ type = { segment . tone === 'secondary' ? 'tertiary' : undefined }
362+ size = { segment . tone === 'secondary' ? 'small' : undefined }
363+ style = { {
364+ display : 'block' ,
365+ maxWidth : '100%' ,
366+ fontSize : 12 ,
367+ marginTop : index === 0 ? 0 : 2 ,
368+ whiteSpace : 'nowrap' ,
369+ overflow : 'hidden' ,
370+ textOverflow : 'ellipsis' ,
371+ } }
372+ >
373+ { segment . text }
374+ </ Typography . Text >
375+ ) ) }
376+ </ div >
377+ ) ;
378+ }
379+
380+ function getUsageLogDetailSummary ( record , text , billingDisplayMode , t ) {
381+ const other = getLogOther ( record . other ) ;
382+
383+ if ( record . type === 6 ) {
384+ return {
385+ segments : [ { text : t ( '异步任务退款' ) , tone : 'primary' } ] ,
386+ } ;
387+ }
388+
389+ if ( other == null || record . type !== 2 ) {
390+ return null ;
391+ }
392+
393+ if (
394+ other ?. violation_fee === true ||
395+ Boolean ( other ?. violation_fee_code ) ||
396+ Boolean ( other ?. violation_fee_marker )
397+ ) {
398+ const feeQuota = other ?. fee_quota ?? record ?. quota ;
399+ const groupText = getUsageLogGroupSummary (
400+ other ?. group_ratio ,
401+ other ?. user_group_ratio ,
402+ t ,
403+ ) ;
404+ return {
405+ segments : [
406+ groupText ? { text : groupText , tone : 'primary' } : null ,
407+ { text : t ( '违规扣费' ) , tone : 'primary' } ,
408+ {
409+ text : `${ t ( '扣费' ) } :${ renderQuota ( feeQuota , 6 ) } ` ,
410+ tone : 'secondary' ,
411+ } ,
412+ text ? { text : `${ t ( '详情' ) } :${ text } ` , tone : 'secondary' } : null ,
413+ ] . filter ( Boolean ) ,
414+ } ;
415+ }
416+
417+ return {
418+ segments : other ?. claude
419+ ? renderModelPriceSimple (
420+ other . model_ratio ,
421+ other . model_price ,
422+ other . group_ratio ,
423+ other ?. user_group_ratio ,
424+ other . cache_tokens || 0 ,
425+ other . cache_ratio || 1.0 ,
426+ other . cache_creation_tokens || 0 ,
427+ other . cache_creation_ratio || 1.0 ,
428+ other . cache_creation_tokens_5m || 0 ,
429+ other . cache_creation_ratio_5m || other . cache_creation_ratio || 1.0 ,
430+ other . cache_creation_tokens_1h || 0 ,
431+ other . cache_creation_ratio_1h || other . cache_creation_ratio || 1.0 ,
432+ false ,
433+ 1.0 ,
434+ other ?. is_system_prompt_overwritten ,
435+ 'claude' ,
436+ billingDisplayMode ,
437+ 'segments' ,
438+ )
439+ : renderModelPriceSimple (
440+ other . model_ratio ,
441+ other . model_price ,
442+ other . group_ratio ,
443+ other ?. user_group_ratio ,
444+ other . cache_tokens || 0 ,
445+ other . cache_ratio || 1.0 ,
446+ 0 ,
447+ 1.0 ,
448+ 0 ,
449+ 1.0 ,
450+ 0 ,
451+ 1.0 ,
452+ false ,
453+ 1.0 ,
454+ other ?. is_system_prompt_overwritten ,
455+ 'openai' ,
456+ billingDisplayMode ,
457+ 'segments' ,
458+ ) ,
459+ } ;
460+ }
461+
333462export const getLogsColumns = ( {
334463 t,
335464 COLUMN_KEYS ,
@@ -375,7 +504,10 @@ export const getLogsColumns = ({
375504 }
376505
377506 return isAdminUser &&
378- ( record . type === 0 || record . type === 2 || record . type === 5 || record . type === 6 ) ? (
507+ ( record . type === 0 ||
508+ record . type === 2 ||
509+ record . type === 5 ||
510+ record . type === 6 ) ? (
379511 < Space >
380512 < span style = { { position : 'relative' , display : 'inline-block' } } >
381513 < Tooltip content = { record . channel_name || t ( '未知渠道' ) } >
@@ -466,7 +598,10 @@ export const getLogsColumns = ({
466598 title : t ( '令牌' ) ,
467599 dataIndex : 'token_name' ,
468600 render : ( text , record , index ) => {
469- return record . type === 0 || record . type === 2 || record . type === 5 || record . type === 6 ? (
601+ return record . type === 0 ||
602+ record . type === 2 ||
603+ record . type === 5 ||
604+ record . type === 6 ? (
470605 < div >
471606 < Tag
472607 color = 'grey'
@@ -489,7 +624,12 @@ export const getLogsColumns = ({
489624 title : t ( '分组' ) ,
490625 dataIndex : 'group' ,
491626 render : ( text , record , index ) => {
492- if ( record . type === 0 || record . type === 2 || record . type === 5 || record . type === 6 ) {
627+ if (
628+ record . type === 0 ||
629+ record . type === 2 ||
630+ record . type === 5 ||
631+ record . type === 6
632+ ) {
493633 if ( record . group ) {
494634 return < > { renderGroup ( record . group ) } </ > ;
495635 } else {
@@ -529,7 +669,10 @@ export const getLogsColumns = ({
529669 title : t ( '模型' ) ,
530670 dataIndex : 'model_name' ,
531671 render : ( text , record , index ) => {
532- return record . type === 0 || record . type === 2 || record . type === 5 || record . type === 6 ? (
672+ return record . type === 0 ||
673+ record . type === 2 ||
674+ record . type === 5 ||
675+ record . type === 6 ? (
533676 < > { renderModelName ( record , copyText , t ) } </ >
534677 ) : (
535678 < > </ >
@@ -596,7 +739,10 @@ export const getLogsColumns = ({
596739 cacheText = `${ t ( '缓存写' ) } ${ formatTokenCount ( cacheSummary . cacheWriteTokens ) } ` ;
597740 }
598741
599- return record . type === 0 || record . type === 2 || record . type === 5 || record . type === 6 ? (
742+ return record . type === 0 ||
743+ record . type === 2 ||
744+ record . type === 5 ||
745+ record . type === 6 ? (
600746 < div
601747 style = { {
602748 display : 'inline-flex' ,
@@ -630,7 +776,10 @@ export const getLogsColumns = ({
630776 dataIndex : 'completion_tokens' ,
631777 render : ( text , record , index ) => {
632778 return parseInt ( text ) > 0 &&
633- ( record . type === 0 || record . type === 2 || record . type === 5 || record . type === 6 ) ? (
779+ ( record . type === 0 ||
780+ record . type === 2 ||
781+ record . type === 5 ||
782+ record . type === 6 ) ? (
634783 < > { < span > { text } </ span > } </ >
635784 ) : (
636785 < > </ >
@@ -642,7 +791,14 @@ export const getLogsColumns = ({
642791 title : t ( '花费' ) ,
643792 dataIndex : 'quota' ,
644793 render : ( text , record , index ) => {
645- if ( ! ( record . type === 0 || record . type === 2 || record . type === 5 || record . type === 6 ) ) {
794+ if (
795+ ! (
796+ record . type === 0 ||
797+ record . type === 2 ||
798+ record . type === 5 ||
799+ record . type === 6
800+ )
801+ ) {
646802 return < > </ > ;
647803 }
648804 const other = getLogOther ( record . other ) ;
@@ -709,9 +865,9 @@ export const getLogsColumns = ({
709865 }
710866 if ( other . admin_info !== undefined ) {
711867 if (
712- other . admin_info . use_channel !== null &&
713- other . admin_info . use_channel !== undefined &&
714- other . admin_info . use_channel !== ''
868+ other . admin_info . use_channel !== null &&
869+ other . admin_info . use_channel !== undefined &&
870+ other . admin_info . use_channel !== ''
715871 ) {
716872 let useChannel = other . admin_info . use_channel ;
717873 let useChannelStr = useChannel . join ( '->' ) ;
@@ -727,118 +883,29 @@ export const getLogsColumns = ({
727883 title : t ( '详情' ) ,
728884 dataIndex : 'content' ,
729885 fixed : 'right' ,
886+ width : 200 ,
730887 render : ( text , record , index ) => {
731- let other = getLogOther ( record . other ) ;
732- if ( record . type === 6 ) {
733- return (
734- < Typography . Paragraph
735- ellipsis = { { rows : 2 } }
736- style = { { maxWidth : 240 } }
737- >
738- { t ( '异步任务退款' ) }
739- </ Typography . Paragraph >
740- ) ;
741- }
742- if ( other == null || record . type !== 2 ) {
743- return (
744- < Typography . Paragraph
745- ellipsis = { {
746- rows : 2 ,
747- showTooltip : {
748- type : 'popover' ,
749- opts : { style : { width : 240 } } ,
750- } ,
751- } }
752- style = { { maxWidth : 240 } }
753- >
754- { text }
755- </ Typography . Paragraph >
756- ) ;
757- }
888+ const detailSummary = getUsageLogDetailSummary (
889+ record ,
890+ text ,
891+ billingDisplayMode ,
892+ t ,
893+ ) ;
758894
759- if (
760- other ?. violation_fee === true ||
761- Boolean ( other ?. violation_fee_code ) ||
762- Boolean ( other ?. violation_fee_marker )
763- ) {
764- const feeQuota = other ?. fee_quota ?? record ?. quota ;
765- const summary = [
766- t ( '违规扣费' ) ,
767- `${ t ( '扣费' ) } :${ renderQuota ( feeQuota , 6 ) } ` ,
768- `${ t ( '分组倍率' ) } :${ formatRatio ( other ?. group_ratio ) } ` ,
769- text ? `${ t ( '详情' ) } :${ text } ` : null ,
770- ]
771- . filter ( Boolean )
772- . join ( '\n' ) ;
895+ if ( ! detailSummary ) {
773896 return (
774897 < Typography . Paragraph
775898 ellipsis = { {
776899 rows : 2 ,
777- showTooltip : {
778- type : 'popover' ,
779- opts : { style : { width : 240 } } ,
780- } ,
781900 } }
782- style = { { maxWidth : 240 , whiteSpace : 'pre-line' } }
901+ style = { { maxWidth : 200 , marginBottom : 0 } }
783902 >
784- { summary }
903+ { text }
785904 </ Typography . Paragraph >
786905 ) ;
787906 }
788907
789- let content = other ?. claude
790- ? renderModelPriceSimple (
791- other . model_ratio ,
792- other . model_price ,
793- other . group_ratio ,
794- other ?. user_group_ratio ,
795- other . cache_tokens || 0 ,
796- other . cache_ratio || 1.0 ,
797- other . cache_creation_tokens || 0 ,
798- other . cache_creation_ratio || 1.0 ,
799- other . cache_creation_tokens_5m || 0 ,
800- other . cache_creation_ratio_5m ||
801- other . cache_creation_ratio ||
802- 1.0 ,
803- other . cache_creation_tokens_1h || 0 ,
804- other . cache_creation_ratio_1h ||
805- other . cache_creation_ratio ||
806- 1.0 ,
807- false ,
808- 1.0 ,
809- other ?. is_system_prompt_overwritten ,
810- 'claude' ,
811- billingDisplayMode ,
812- )
813- : renderModelPriceSimple (
814- other . model_ratio ,
815- other . model_price ,
816- other . group_ratio ,
817- other ?. user_group_ratio ,
818- other . cache_tokens || 0 ,
819- other . cache_ratio || 1.0 ,
820- 0 ,
821- 1.0 ,
822- 0 ,
823- 1.0 ,
824- 0 ,
825- 1.0 ,
826- false ,
827- 1.0 ,
828- other ?. is_system_prompt_overwritten ,
829- 'openai' ,
830- billingDisplayMode ,
831- ) ;
832- return (
833- < Typography . Paragraph
834- ellipsis = { {
835- rows : 3 ,
836- } }
837- style = { { maxWidth : 240 , whiteSpace : 'pre-line' } }
838- >
839- { content }
840- </ Typography . Paragraph >
841- ) ;
908+ return renderCompactDetailSummary ( detailSummary . segments ) ;
842909 } ,
843910 } ,
844911 ] ;
0 commit comments