1
- import React , { useContext , useEffect , useRef , useState } from 'react' ;
1
+ import React , { useContext , useEffect , useRef , useMemo , useState } from 'react' ;
2
2
import { API , copy , showError , showSuccess } from '../helpers' ;
3
3
4
4
import {
@@ -10,8 +10,16 @@ import {
10
10
Table ,
11
11
Tag ,
12
12
Tooltip ,
13
+ Popover ,
14
+ ImagePreview ,
15
+ Button ,
13
16
} from '@douyinfe/semi-ui' ;
14
- import { stringToColor } from '../helpers/render.js' ;
17
+ import {
18
+ IconMore ,
19
+ IconVerify ,
20
+ IconUploadError ,
21
+ IconHelpCircle ,
22
+ } from '@douyinfe/semi-icons' ;
15
23
import { UserContext } from '../context/User/index.js' ;
16
24
import Text from '@douyinfe/semi-ui/lib/es/typography/text' ;
17
25
@@ -20,42 +28,74 @@ function renderQuotaType(type) {
20
28
switch ( type ) {
21
29
case 1 :
22
30
return (
23
- < Tag color = 'green ' size = 'large' >
31
+ < Tag color = 'teal ' size = 'large' >
24
32
按次计费
25
33
</ Tag >
26
34
) ;
27
35
case 0 :
28
36
return (
29
- < Tag color = 'blue ' size = 'large' >
37
+ < Tag color = 'violet ' size = 'large' >
30
38
按量计费
31
39
</ Tag >
32
40
) ;
33
41
default :
34
- return (
35
- < Tag color = 'white' size = 'large' >
36
- 未知
37
- </ Tag >
38
- ) ;
42
+ return '未知' ;
39
43
}
40
44
}
41
45
42
46
function renderAvailable ( available ) {
43
47
return available ? (
44
- < Tag color = 'green' size = 'large' >
45
- 可用
46
- </ Tag >
48
+ < Popover
49
+ content = {
50
+ < div style = { { padding : 8 } } > 您的分组可以使用该模型</ div >
51
+ }
52
+ position = 'top'
53
+ key = { available }
54
+ style = { {
55
+ backgroundColor : 'rgba(var(--semi-blue-4),1)' ,
56
+ borderColor : 'rgba(var(--semi-blue-4),1)' ,
57
+ color : 'var(--semi-color-white)' ,
58
+ borderWidth : 1 ,
59
+ borderStyle : 'solid' ,
60
+ } }
61
+ >
62
+ < IconVerify style = { { color : 'green' } } size = "large" />
63
+ </ Popover >
47
64
) : (
48
- < Tooltip content = '您所在的分组不可用' >
49
- < Tag color = 'red' size = 'large' >
50
- 不可用
51
- </ Tag >
52
- </ Tooltip >
65
+ < Popover
66
+ content = {
67
+ < div style = { { padding : 8 } } > 您的分组无权使用该模型</ div >
68
+ }
69
+ position = 'top'
70
+ key = { available }
71
+ style = { {
72
+ backgroundColor : 'rgba(var(--semi-blue-4),1)' ,
73
+ borderColor : 'rgba(var(--semi-blue-4),1)' ,
74
+ color : 'var(--semi-color-white)' ,
75
+ borderWidth : 1 ,
76
+ borderStyle : 'solid' ,
77
+ } }
78
+ >
79
+ < IconUploadError style = { { color : '#FFA54F' } } size = "large" />
80
+ </ Popover >
53
81
) ;
54
82
}
55
83
56
84
const ModelPricing = ( ) => {
57
85
const [ filteredValue , setFilteredValue ] = useState ( [ ] ) ;
58
86
const compositionRef = useRef ( { isComposition : false } ) ;
87
+ const [ selectedRowKeys , setSelectedRowKeys ] = useState ( [ ] ) ;
88
+ const [ modalImageUrl , setModalImageUrl ] = useState ( '' ) ;
89
+ const [ isModalOpenurl , setIsModalOpenurl ] = useState ( false ) ;
90
+
91
+ const rowSelection = useMemo (
92
+ ( ) => ( {
93
+ onChange : ( selectedRowKeys , selectedRows ) => {
94
+ setSelectedRowKeys ( selectedRowKeys ) ;
95
+ } ,
96
+ } ) ,
97
+ [ ]
98
+ ) ;
59
99
60
100
const handleChange = ( value ) => {
61
101
if ( compositionRef . current . isComposition ) {
@@ -103,7 +143,7 @@ const ModelPricing = () => {
103
143
return (
104
144
< >
105
145
< Tag
106
- color = { stringToColor ( text ) }
146
+ color = 'green'
107
147
size = 'large'
108
148
onClick = { ( ) => {
109
149
copyText ( text ) ;
@@ -114,7 +154,8 @@ const ModelPricing = () => {
114
154
</ >
115
155
) ;
116
156
} ,
117
- onFilter : ( value , record ) => record . model_name . includes ( value ) ,
157
+ onFilter : ( value , record ) =>
158
+ record . model_name . toLowerCase ( ) . includes ( value . toLowerCase ( ) ) ,
118
159
filteredValue,
119
160
} ,
120
161
{
@@ -126,18 +167,43 @@ const ModelPricing = () => {
126
167
sorter : ( a , b ) => a . quota_type - b . quota_type ,
127
168
} ,
128
169
{
129
- title : '模型倍率' ,
170
+ title : ( ) => (
171
+ < span style = { { 'display' :'flex' , 'alignItems' :'center' } } >
172
+ 倍率
173
+ < Popover
174
+ content = {
175
+ < div style = { { padding : 8 } } > 倍率是为了方便换算不同价格的模型< br /> 点击查看倍率说明</ div >
176
+ }
177
+ position = 'top'
178
+ style = { {
179
+ backgroundColor : 'rgba(var(--semi-blue-4),1)' ,
180
+ borderColor : 'rgba(var(--semi-blue-4),1)' ,
181
+ color : 'var(--semi-color-white)' ,
182
+ borderWidth : 1 ,
183
+ borderStyle : 'solid' ,
184
+ } }
185
+ >
186
+ < IconHelpCircle
187
+ onClick = { ( ) => {
188
+ setModalImageUrl ( '/ratio.png' ) ;
189
+ setIsModalOpenurl ( true ) ;
190
+ } }
191
+ />
192
+ </ Popover >
193
+ </ span >
194
+ ) ,
130
195
dataIndex : 'model_ratio' ,
131
196
render : ( text , record , index ) => {
132
- return < div > { record . quota_type === 0 ? text : 'N/A' } </ div > ;
133
- } ,
134
- } ,
135
- {
136
- title : '补全倍率' ,
137
- dataIndex : 'completion_ratio' ,
138
- render : ( text , record , index ) => {
139
- let ratio = parseFloat ( text . toFixed ( 3 ) ) ;
140
- return < div > { record . quota_type === 0 ? ratio : 'N/A' } </ div > ;
197
+ let content = text ;
198
+ let completionRatio = parseFloat ( record . completion_ratio . toFixed ( 3 ) ) ;
199
+ content = (
200
+ < >
201
+ < Text > 模型:{ record . quota_type === 0 ? text : '无' } </ Text >
202
+ < br />
203
+ < Text > 补全:{ record . quota_type === 0 ? completionRatio : '无' } </ Text >
204
+ </ >
205
+ ) ;
206
+ return < div > { content } </ div > ;
141
207
} ,
142
208
} ,
143
209
{
@@ -175,7 +241,7 @@ const ModelPricing = () => {
175
241
176
242
const setModelsFormat = ( models , groupRatio ) => {
177
243
for ( let i = 0 ; i < models . length ; i ++ ) {
178
- models [ i ] . key = i ;
244
+ models [ i ] . key = models [ i ] . model_name ;
179
245
models [ i ] . group_ratio = groupRatio ;
180
246
}
181
247
// sort by quota_type
@@ -238,15 +304,38 @@ const ModelPricing = () => {
238
304
< Layout >
239
305
{ userState . user ? (
240
306
< Banner
241
- type = 'info'
307
+ type = "success"
308
+ fullMode = { false }
309
+ closeIcon = "null"
242
310
description = { `您的分组为:${ userState . user . group } ,分组倍率为:${ groupRatio } ` }
243
311
/>
244
312
) : (
245
313
< Banner
246
314
type = 'warning'
315
+ fullMode = { false }
316
+ closeIcon = "null"
247
317
description = { `您还未登陆,显示的价格为默认分组倍率: ${ groupRatio } ` }
248
318
/>
249
319
) }
320
+ < br />
321
+ < Banner
322
+ type = "info"
323
+ fullMode = { false }
324
+ description = { < div > 按量计费费用 = 分组倍率 × 模型倍率 × (提示token数 + 补全token数 × 补全倍率)/ 500000 (单位:美元)</ div > }
325
+ closeIcon = "null"
326
+ />
327
+ < br />
328
+ < Button
329
+ theme = 'light'
330
+ type = 'tertiary'
331
+ style = { { width : 150 } }
332
+ onClick = { ( ) => {
333
+ copyText ( selectedRowKeys ) ;
334
+ } }
335
+ disabled = { selectedRowKeys == "" }
336
+ >
337
+ 复制选中模型
338
+ </ Button >
250
339
< Table
251
340
style = { { marginTop : 5 } }
252
341
columns = { columns }
@@ -256,6 +345,12 @@ const ModelPricing = () => {
256
345
pageSize : models . length ,
257
346
showSizeChanger : false ,
258
347
} }
348
+ rowSelection = { rowSelection }
349
+ />
350
+ < ImagePreview
351
+ src = { modalImageUrl }
352
+ visible = { isModalOpenurl }
353
+ onVisibleChange = { ( visible ) => setIsModalOpenurl ( visible ) }
259
354
/>
260
355
</ Layout >
261
356
</ >
0 commit comments