From e183e3b9b023c589c7dbb8bf9c55a2503ed346c9 Mon Sep 17 00:00:00 2001 From: JustSong Date: Sat, 1 Feb 2025 23:58:55 +0800 Subject: [PATCH] feat: i18n support --- .../public/locales/en/translation.json | 37 +- .../public/locales/zh/translation.json | 37 +- web/default/src/components/LogsTable.js | 568 +++++++++--------- web/default/src/pages/Dashboard/index.js | 24 +- 4 files changed, 364 insertions(+), 302 deletions(-) diff --git a/web/default/public/locales/en/translation.json b/web/default/public/locales/en/translation.json index c767a38..f4d7493 100644 --- a/web/default/public/locales/en/translation.json +++ b/web/default/public/locales/en/translation.json @@ -292,16 +292,43 @@ }, "log": { "title": "Operation Log", + "search": "Search logs...", "usage_details": "Usage Details", "total_quota": "Total Quota Used", "click_to_view": "Click to View", + "type": { + "select": "Select Log Type", + "all": "All", + "topup": "Top Up", + "usage": "Usage", + "admin": "Admin", + "system": "System", + "test": "Test" + }, "table": { - "id": "ID", - "username": "Username", + "time": "Time", + "channel": "Channel", "type": "Type", - "content": "Content", - "amount": "Amount", - "time": "Time" + "model": "Model", + "username": "Username", + "token_name": "Token Name", + "token_name_placeholder": "Optional", + "model_name": "Model Name", + "model_name_placeholder": "Optional", + "start_time": "Start Time", + "end_time": "End Time", + "channel_id": "Channel ID", + "channel_id_placeholder": "Optional", + "username_placeholder": "Optional", + "prompt_tokens": "Prompt Tokens", + "completion_tokens": "Completion Tokens", + "quota": "Quota", + "detail": "Detail" + }, + "buttons": { + "query": "Action", + "submit": "Query", + "refresh": "Refresh" } }, "user": { diff --git a/web/default/public/locales/zh/translation.json b/web/default/public/locales/zh/translation.json index 6bad3ae..d3b80c2 100644 --- a/web/default/public/locales/zh/translation.json +++ b/web/default/public/locales/zh/translation.json @@ -292,16 +292,43 @@ }, "log": { "title": "操作日志", + "search": "搜索日志...", "usage_details": "使用明细", "total_quota": "总消耗额度", "click_to_view": "点击查看", + "type": { + "select": "选择明细分类", + "all": "全部", + "topup": "充值", + "usage": "消费", + "admin": "管理", + "system": "系统", + "test": "测试" + }, "table": { - "id": "ID", - "username": "用户名", + "time": "时间", + "channel": "渠道", "type": "类型", - "content": "内容", - "amount": "数量", - "time": "时间" + "model": "模型", + "username": "用户名", + "token_name": "令牌名称", + "token_name_placeholder": "可选值", + "model_name": "模型名称", + "model_name_placeholder": "可选值", + "start_time": "起始时间", + "end_time": "结束时间", + "channel_id": "渠道 ID", + "channel_id_placeholder": "可选值", + "username_placeholder": "可选值", + "prompt_tokens": "提示词消耗", + "completion_tokens": "补全消耗", + "quota": "额度", + "detail": "详情" + }, + "buttons": { + "query": "操作", + "submit": "查询", + "refresh": "刷新" } }, "user": { diff --git a/web/default/src/components/LogsTable.js b/web/default/src/components/LogsTable.js index 5cf7ceb..b792cf3 100644 --- a/web/default/src/components/LogsTable.js +++ b/web/default/src/components/LogsTable.js @@ -8,6 +8,7 @@ import { Segment, Select, Table, + Popup, } from 'semantic-ui-react'; import { API, @@ -46,15 +47,6 @@ const MODE_OPTIONS = [ { key: 'self', text: '当前用户', value: 'self' }, ]; -const LOG_OPTIONS = [ - { key: '0', text: '全部', value: 0 }, - { key: '1', text: '充值', value: 1 }, - { key: '2', text: '消费', value: 2 }, - { key: '3', text: '管理', value: 3 }, - { key: '4', text: '系统', value: 4 }, - { key: '5', text: '测试', value: 5 }, -]; - function renderType(type) { switch (type) { case 1: @@ -170,6 +162,15 @@ const LogsTable = () => { token: 0, }); + const LOG_OPTIONS = [ + { key: '0', text: t('log.type.all'), value: 0 }, + { key: '1', text: t('log.type.topup'), value: 1 }, + { key: '2', text: t('log.type.usage'), value: 2 }, + { key: '3', text: t('log.type.admin'), value: 3 }, + { key: '4', text: t('log.type.system'), value: 4 }, + { key: '5', text: t('log.type.test'), value: 5 }, + ]; + const handleInputChange = (e, { name, value }) => { setInputs((inputs) => ({ ...inputs, [name]: value })); }; @@ -309,296 +310,295 @@ const LogsTable = () => { return ( <> - <> -
- {t('log.usage_details')}({t('log.total_quota')}: - {showStat && renderQuota(stat.quota, t)} - {!showStat && ( - - {t('log.click_to_view')} - - )} - ) -
-
- - - - - - - 查询 - - - {isAdminUser && ( - <> - - - - - - )} -
- - - - { - sortLog('created_time'); - }} +
+ {t('log.usage_details')}({t('log.total_quota')}: + {showStat && renderQuota(stat.quota, t)} + {!showStat && ( + + {t('log.click_to_view')} + + )} + ) +
+
+ + + + + + + {t('log.buttons.submit')} + + + {isAdminUser && ( + <> + + - 时间 -
- {isAdminUser && ( - { - sortLog('channel'); - }} - width={1} - > - 渠道 - - )} + value={channel} + placeholder={t('log.table.channel_id_placeholder')} + name='channel' + onChange={handleInputChange} + /> + + + + )} + setSearchKeyword(value)} + /> + +
+ + + { + sortLog('created_time'); + }} + width={3} + > + {t('log.table.time')} + + {isAdminUser && ( { - sortLog('type'); + sortLog('channel'); }} width={1} > - 类型 + {t('log.table.channel')} - { - sortLog('model_name'); - }} - width={2} - > - 模型 - - {showUserTokenQuota() && ( - <> - {isAdminUser && ( - { - sortLog('username'); - }} - width={1} - > - 用户 - - )} + )} + { + sortLog('type'); + }} + width={1} + > + {t('log.table.type')} + + { + sortLog('model_name'); + }} + width={2} + > + {t('log.table.model')} + + {showUserTokenQuota() && ( + <> + {isAdminUser && ( { - sortLog('token_name'); + sortLog('username'); }} - width={1} + width={2} > - 令牌 + {t('log.table.username')} - { - sortLog('prompt_tokens'); - }} - width={1} - > - 提示 - - { - sortLog('completion_tokens'); - }} - width={1} - > - 补全 - - { - sortLog('quota'); - }} - width={1} - > - 额度 - - - )} - { - sortLog('content'); - }} - width={isAdminUser ? 4 : 6} - > - 详情 - - - - - - {logs - .slice( - (activePage - 1) * ITEMS_PER_PAGE, - activePage * ITEMS_PER_PAGE - ) - .map((log, idx) => { - if (log.deleted) return <>; - return ( - - - {renderTimestamp(log.created_at, log.request_id)} - - {isAdminUser && ( - - {log.channel ? ( - - ) : ( - '' - )} - - )} - {renderType(log.type)} - - {log.model_name ? renderColorLabel(log.model_name) : ''} - - {showUserTokenQuota() && ( - <> - {isAdminUser && ( - - {log.username ? ( - - ) : ( - '' - )} - - )} - - {log.token_name - ? renderColorLabel(log.token_name) - : ''} - - - - {log.prompt_tokens ? log.prompt_tokens : ''} - - - {log.completion_tokens ? log.completion_tokens : ''} - - - {log.quota ? renderQuota(log.quota, t, 6) : ''} - - - )} - - {renderDetail(log)} - - ); - })} - - - - - -
- + width={2} + > + {t('log.table.token_name')} + + { + sortLog('prompt_tokens'); + }} + width={1} + > + {t('log.table.prompt_tokens')} + + { + sortLog('completion_tokens'); + }} + width={1} + > + {t('log.table.completion_tokens')} + + { + sortLog('quota'); + }} + width={1} + > + {t('log.table.quota')} + + + )} + {t('log.table.detail')} + + + + + {logs + .slice( + (activePage - 1) * ITEMS_PER_PAGE, + activePage * ITEMS_PER_PAGE + ) + .map((log, idx) => { + if (log.deleted) return <>; + return ( + + + {renderTimestamp(log.created_at, log.request_id)} + + {isAdminUser && ( + + {log.channel ? ( + + ) : ( + '' + )} + + )} + {renderType(log.type)} + + {log.model_name ? renderColorLabel(log.model_name) : ''} + + {showUserTokenQuota() && ( + <> + {isAdminUser && ( + + {log.username ? ( + + ) : ( + '' + )} + + )} + + {log.token_name ? renderColorLabel(log.token_name) : ''} + + + + {log.prompt_tokens ? log.prompt_tokens : ''} + + + {log.completion_tokens ? log.completion_tokens : ''} + + + {log.quota ? renderQuota(log.quota, t, 6) : ''} + + + )} + + {renderDetail(log)} + + ); + })} + + + + + +