Skip to content

Commit 13f4e7e

Browse files
authored
feat(ModelPrice):优化价格页面 (#862)
* refactor(ModelPrice): 优化模型排序与页面布局 - 添加基于ownedby ID的模型排序逻辑,确保列表按指定顺序显示 - 移除标签显示数量限制,完整展示所有可用标签 - 扩大页面最大宽度至1700px,优化大屏显示效果 - 统一代码格式和样式缩进,提升代码可读性 * feat(ModelPrice): 添加模型列表分页功能 - 为模型价格页面集成分页组件,提升大量模型数据的加载性能 - 使用useMemo优化filteredModels计算,避免不必要的重复渲染 - 添加分页状态管理和页码重置逻辑,确保筛选条件变化时回到第一页 - 实现分页数据切片和页面切换处理,支持平滑滚动到顶部 - 在页面底部添加Pagination组件,优化用户体验 * feat(ModelPrice): 增加列表视图模式与页面大小选择功能 - 新增ToggleButtonGroup切换按钮组,支持卡片视图和列表视图模式切换 - 添加页面大小选择器,支持20/30/60/100条每页的灵活分页设置 - 实现完整列表视图模式,包含模型表格展示、供应商图标、类型标签和价格信息 - 集成Table组件系列(TableContainer、TableHead、TableRow等),优化数据展示结构 - 重构导入语句,将ToggleButtonGroup重命名为CustomToggleButtonGroup避免命名冲突 - 完善多语言翻译支持,新增provider、inputPrice、outputPrice等关键字段翻译 - 优化分页逻辑,当页面大小变化时自动重置到第一页并触发数据更新 * feat(ModelPrice): 增强列表视图功能 * 模型名称添加复制功能 * 显示模型标签,特别标记"热门"模型 * 优化价格列显示,按组显示价格及倍率 * 调整表格对齐方式,提升可读性
1 parent 4b5f7aa commit 13f4e7e

9 files changed

Lines changed: 471 additions & 132 deletions

File tree

web/src/i18n/locales/en_US.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@
315315
"deleteError": "Deletion failed: {{message}}",
316316
"deleteSuccess": "Delete successful!",
317317
"jsonFormatError": "JSON format error",
318+
"action": "Action",
318319
"actions": "Operation",
319320
"noDataAvailable": "No data available",
320321
"pageSize": "Number of items per page",
@@ -540,9 +541,13 @@
540541
"modelpricePage": {
541542
"availableModels": "Available Models",
542543
"channelType": "Supplier",
544+
"provider": "Provider",
543545
"group": "Group",
546+
"inputPrice": "Input Price",
547+
"outputPrice": "Output Price",
544548
"inputMultiplier": "Input Price",
545549
"model": "Model Name",
550+
"modelName": "Model Name",
546551
"noneGroup": "Current group unavailable",
547552
"outputMultiplier": "Output Price",
548553
"search": "Search model name or description",
@@ -584,7 +589,16 @@
584589
"outputModality": "Output Modality",
585590
"priceDetails": "Price Details",
586591
"priceNote": "Different groups have different prices. Switch groups in token management.",
587-
"otherInfo": "Other Information"
592+
"otherInfo": "Other Information",
593+
"totalModels": "Total {{count}} models",
594+
"noModelsFound": "No matching models found",
595+
"noModelsFoundTip": "Please try adjusting filters or search keywords",
596+
"modelId": "Model ID",
597+
"copyModelId": "Copy Model ID",
598+
"billingMethod": "Billing Method",
599+
"currentUserGroup": "Current User Group",
600+
"viewDetail": "View Details",
601+
"timeUnit": "Time"
588602
},
589603
"nova 映射": "nova mapping",
590604
"onyx 映射": "onyx mapping",

web/src/i18n/locales/ja_JP.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@
293293
"deleteError": "削除に失敗しました:{{message}}",
294294
"deleteSuccess": "削除しました!",
295295
"jsonFormatError": "JSON形式が間違っています",
296+
"action": "操作",
296297
"actions": "操作 -> 操作",
297298
"noDataAvailable": "データがありません。",
298299
"pageSize": "ページごとのアイテム数",
@@ -528,9 +529,13 @@
528529
"modelpricePage": {
529530
"availableModels": "利用可能なモデル",
530531
"channelType": "サプライヤー",
532+
"provider": "プロバイダー",
531533
"group": "グループ",
534+
"inputPrice": "入力価格",
535+
"outputPrice": "出力価格",
532536
"inputMultiplier": "価格を入力してください",
533537
"model": "モデル名",
538+
"modelName": "モデル名",
534539
"noneGroup": "現在のグループは利用できません",
535540
"outputMultiplier": "価格を出力します。",
536541
"search": "検索",
@@ -572,7 +577,16 @@
572577
"outputModality": "出力モダリティ",
573578
"priceDetails": "価格詳細",
574579
"priceNote": "グループによって価格が異なります。トークン管理でグループを切り替えてください。",
575-
"otherInfo": "その他の情報"
580+
"otherInfo": "その他の情報",
581+
"totalModels": "合計 {{count}} モデル",
582+
"noModelsFound": "一致するモデルが見つかりません",
583+
"noModelsFoundTip": "フィルタまたは検索キーワードを調整してみてください",
584+
"modelId": "モデルID",
585+
"copyModelId": "モデルIDをコピー",
586+
"billingMethod": "課金方式",
587+
"currentUserGroup": "現在のユーザーグループ",
588+
"viewDetail": "詳細を表示",
589+
"timeUnit": ""
576590
},
577591
"nova 映射": "新星マッピング",
578592
"onyx 映射": "オニキスマッピング",

web/src/i18n/locales/zh_CN.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,12 +605,16 @@
605605
},
606606
"modelpricePage": {
607607
"model": "模型名称",
608+
"modelName": "模型名称",
608609
"type": "类型",
609610
"channelType": "供应商",
611+
"provider": "供应商",
610612
"availableModels": "可用模型",
611613
"group": "分组",
612614
"free": "免费",
613615
"RPM": "API速率",
616+
"inputPrice": "输入价格",
617+
"outputPrice": "输出价格",
614618
"inputMultiplier": "输入价格",
615619
"outputMultiplier": "输出价格",
616620
"input": "输入",
@@ -650,7 +654,16 @@
650654
"outputModality": "输出模态",
651655
"priceDetails": "价格明细",
652656
"priceNote": "不同分组,对应的价格也随之不同,渠道组需要在令牌管理中切换。",
653-
"otherInfo": "其他信息"
657+
"otherInfo": "其他信息",
658+
"totalModels": "共 {{count}} 个模型",
659+
"noModelsFound": "未找到匹配的模型",
660+
"noModelsFoundTip": "请尝试调整筛选条件或搜索关键词",
661+
"modelId": "模型标识",
662+
"copyModelId": "复制模型标识",
663+
"billingMethod": "计费方式",
664+
"currentUserGroup": "当前用户组",
665+
"viewDetail": "查看详情",
666+
"timeUnit": ""
654667
},
655668
"paymentPage": {
656669
"orderList": "订单列表",
@@ -1159,6 +1172,7 @@
11591172
"deleteSuccess": "删除成功!",
11601173
"deleteError": "删除失败: {{message}}",
11611174
"jsonFormatError": "JSON 格式错误",
1175+
"action": "操作",
11621176
"pageSize": "每页条数",
11631177
"search": "搜索",
11641178
"actions": "操作",

web/src/i18n/locales/zh_HK.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@
297297
"deleteError": "刪除失敗:{{message}}",
298298
"deleteSuccess": "刪除成功!",
299299
"jsonFormatError": "JSON 格式錯誤",
300+
"action": "操作",
300301
"actions": "操作",
301302
"noDataAvailable": "冇數據可用",
302303
"pageSize": "每頁條數",
@@ -531,9 +532,13 @@
531532
"modelpricePage": {
532533
"availableModels": "可用模型",
533534
"channelType": "供應商",
535+
"provider": "供應商",
534536
"group": "分組",
537+
"inputPrice": "輸入價格",
538+
"outputPrice": "輸出價格",
535539
"inputMultiplier": "輸入價格",
536540
"model": "模型名稱",
541+
"modelName": "模型名稱",
537542
"noneGroup": "當前分組不可用",
538543
"outputMultiplier": "輸出價格",
539544
"search": "搜尋",
@@ -575,7 +580,16 @@
575580
"outputModality": "輸出模態",
576581
"priceDetails": "價格明細",
577582
"priceNote": "不同分組,對應的價格也隨之不同,渠道組需要在令牌管理中切換。",
578-
"otherInfo": "其他資訊"
583+
"otherInfo": "其他資訊",
584+
"totalModels": "共 {{count}} 個模型",
585+
"noModelsFound": "未找到匹配的模型",
586+
"noModelsFoundTip": "請嘗試調整篩選條件或搜索關鍵詞",
587+
"modelId": "模型標識",
588+
"copyModelId": "複製模型標識",
589+
"billingMethod": "計費方式",
590+
"currentUserGroup": "當前用戶組",
591+
"viewDetail": "查看詳情",
592+
"timeUnit": ""
579593
},
580594
"nova 映射": "nova 映射",
581595
"onyx 映射": "onyx 映射",

web/src/routes/OtherRoutes.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const ModelPrice = Loadable(lazy(() => import('views/ModelPrice')));
2323
const WithMargins = ({ children }) => (
2424
<Box
2525
sx={{
26-
maxWidth: '1200px',
26+
maxWidth: '1700px',
2727
margin: '0 auto',
2828
padding: { xs: 0, sm: '0 24px' }
2929
}}

web/src/views/Dashboard/component/SupportModels.jsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ const SupportModels = () => {
3232
Object.values(modelGroup).forEach((models) => models.sort());
3333

3434
const sortedModelGroup = Object.keys(modelGroup)
35-
.sort()
35+
.sort((a, b) => {
36+
const ownerA = ownedby?.find((item) => item.name === a);
37+
const ownerB = ownedby?.find((item) => item.name === b);
38+
return (ownerA?.id || 0) - (ownerB?.id || 0);
39+
})
3640
.reduce((acc, key) => {
3741
acc[key] = modelGroup[key];
3842
return acc;

web/src/views/ModelPrice/component/ModelCard.jsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ export default function ModelCard({ model, provider, modelInfo, price, group, ow
107107
</Typography>
108108
</Box>
109109
</Stack>
110-
<Tooltip title="复制模型标识">
111-
<IconButton size="small" onClick={() => copy(model, '模型标识')} sx={{ color: theme.palette.text.secondary }}>
110+
<Tooltip title={t('modelpricePage.copyModelId')}>
111+
<IconButton size="small" onClick={() => copy(model, t('modelpricePage.modelId'))} sx={{ color: theme.palette.text.secondary }}>
112112
<Icon icon="eva:copy-outline" width={18} height={18} />
113113
</IconButton>
114114
</Tooltip>
@@ -143,7 +143,7 @@ export default function ModelCard({ model, provider, modelInfo, price, group, ow
143143
{inputModalities.length > 0 && (
144144
<Box>
145145
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.5, fontSize: '0.7rem' }}>
146-
输入模态
146+
{t('modelpricePage.inputModality')}
147147
</Typography>
148148
<Stack direction="row" spacing={0.5} flexWrap="wrap" useFlexGap>
149149
{inputModalities.map((modality, index) => (
@@ -164,7 +164,7 @@ export default function ModelCard({ model, provider, modelInfo, price, group, ow
164164
{outputModalities.length > 0 && (
165165
<Box>
166166
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.5, fontSize: '0.7rem' }}>
167-
输出模态
167+
{t('modelpricePage.outputModality')}
168168
</Typography>
169169
<Stack direction="row" spacing={0.5} flexWrap="wrap" useFlexGap>
170170
{outputModalities.map((modality, index) => (
@@ -185,7 +185,7 @@ export default function ModelCard({ model, provider, modelInfo, price, group, ow
185185
{tags.length > 0 && (
186186
<Box>
187187
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.5, fontSize: '0.7rem' }}>
188-
标签
188+
{t('modelpricePage.tags')}
189189
</Typography>
190190
<Stack direction="row" spacing={0.5} flexWrap="wrap" useFlexGap>
191191
{tags.map((tag, index) => (
@@ -213,7 +213,7 @@ export default function ModelCard({ model, provider, modelInfo, price, group, ow
213213

214214
<Box>
215215
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.5, fontSize: '0.7rem' }}>
216-
计费方式
216+
{t('modelpricePage.billingMethod')}
217217
</Typography>
218218
<Stack direction="row" spacing={0.5} flexWrap="wrap" useFlexGap>
219219
{type === 'tokens' && (
@@ -238,15 +238,15 @@ export default function ModelCard({ model, provider, modelInfo, price, group, ow
238238
<Stack spacing={1}>
239239
<Stack direction="row" alignItems="center" justifyContent="space-between">
240240
<Typography variant="caption" color="text.secondary" sx={{ fontSize: '0.7rem' }}>
241-
输入价格
241+
{t('modelpricePage.inputMultiplier')}
242242
</Typography>
243243
<Label color="success" variant="outlined" sx={{ fontSize: '0.75rem', py: 0.25, px: 0.75, fontWeight: 600 }}>
244244
{formatPrice(price.input, type)}
245245
</Label>
246246
</Stack>
247247
<Stack direction="row" alignItems="center" justifyContent="space-between">
248248
<Typography variant="caption" color="text.secondary" sx={{ fontSize: '0.7rem' }}>
249-
输出价格
249+
{t('modelpricePage.outputMultiplier')}
250250
</Typography>
251251
<Label color="warning" variant="outlined" sx={{ fontSize: '0.75rem', py: 0.25, px: 0.75, fontWeight: 600 }}>
252252
{formatPrice(price.output, type)}
@@ -275,7 +275,7 @@ export default function ModelCard({ model, provider, modelInfo, price, group, ow
275275
<Box sx={{ mt: 1.5 }}>
276276
<Stack direction="row" alignItems="center" justifyContent="space-between">
277277
<Typography variant="caption" color="text.secondary" sx={{ fontSize: '0.7rem' }}>
278-
当前用户组
278+
{t('modelpricePage.currentUserGroup')}
279279
</Typography>
280280
<Stack direction="row" spacing={0.5} alignItems="center">
281281
<Label color="primary" sx={{ fontSize: '0.7rem', py: 0.25, px: 0.75 }}>
@@ -308,7 +308,7 @@ export default function ModelCard({ model, provider, modelInfo, price, group, ow
308308
fontWeight: 600
309309
}}
310310
>
311-
查看详情
311+
{t('modelpricePage.viewDetail')}
312312
</Button>
313313
</Box>
314314
</CardContent>

web/src/views/ModelPrice/component/ModelDetailModal.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export default function ModelDetailModal({ open, onClose, model, provider, model
9393
<Typography variant="body2" color="text.secondary" sx={{ fontSize: '0.875rem' }}>
9494
{model}
9595
</Typography>
96-
<IconButton size="small" onClick={() => copy(model, '模型标识')} sx={{ p: 0.5 }}>
96+
<IconButton size="small" onClick={() => copy(model, t('modelpricePage.modelId'))} sx={{ p: 0.5 }}>
9797
<Icon icon="eva:copy-outline" width={16} height={16} />
9898
</IconButton>
9999
</Stack>

0 commit comments

Comments
 (0)