diff --git a/web/src/components/settings/OperationSetting.js b/web/src/components/settings/OperationSetting.js
index 7bd9bf62..f6786f95 100644
--- a/web/src/components/settings/OperationSetting.js
+++ b/web/src/components/settings/OperationSetting.js
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
-import { Card, Spin, Tabs } from '@douyinfe/semi-ui';
+import { Card, Spin } from '@douyinfe/semi-ui';
import SettingsGeneral from '../../pages/Setting/Operation/SettingsGeneral.js';
import SettingsDrawing from '../../pages/Setting/Operation/SettingsDrawing.js';
import SettingsSensitiveWords from '../../pages/Setting/Operation/SettingsSensitiveWords.js';
@@ -7,63 +7,58 @@ import SettingsLog from '../../pages/Setting/Operation/SettingsLog.js';
import SettingsDataDashboard from '../../pages/Setting/Operation/SettingsDataDashboard.js';
import SettingsMonitoring from '../../pages/Setting/Operation/SettingsMonitoring.js';
import SettingsCreditLimit from '../../pages/Setting/Operation/SettingsCreditLimit.js';
-import ModelSettingsVisualEditor from '../../pages/Setting/Operation/ModelSettingsVisualEditor.js';
-import GroupRatioSettings from '../../pages/Setting/Operation/GroupRatioSettings.js';
-import ModelRatioSettings from '../../pages/Setting/Operation/ModelRatioSettings.js';
-
-import { API, showError, showSuccess } from '../../helpers';
import SettingsChats from '../../pages/Setting/Operation/SettingsChats.js';
-import { useTranslation } from 'react-i18next';
-import ModelRatioNotSetEditor from '../../pages/Setting/Operation/ModelRationNotSetEditor.js';
+import { API, showError } from '../../helpers';
const OperationSetting = () => {
- const { t } = useTranslation();
let [inputs, setInputs] = useState({
+ /* 额度相关 */
QuotaForNewUser: 0,
+ PreConsumedQuota: 0,
QuotaForInviter: 0,
QuotaForInvitee: 0,
- QuotaRemindThreshold: 0,
- PreConsumedQuota: 0,
- StreamCacheQueueLength: 0,
- ModelRatio: '',
- CacheRatio: '',
- CompletionRatio: '',
- ModelPrice: '',
- GroupRatio: '',
- GroupGroupRatio: '',
- AutoGroups: '',
- DefaultUseAutoGroup: false,
- UserUsableGroups: '',
+
+ /* 通用设置 */
TopUpLink: '',
'general_setting.docs_link': '',
- // ChatLink2: '', // 添加的新状态变量
QuotaPerUnit: 0,
- AutomaticDisableChannelEnabled: false,
- AutomaticEnableChannelEnabled: false,
- ChannelDisableThreshold: 0,
- LogConsumeEnabled: false,
+ RetryTimes: 0,
DisplayInCurrencyEnabled: false,
DisplayTokenStatEnabled: false,
- CheckSensitiveEnabled: false,
- CheckSensitiveOnPromptEnabled: false,
- CheckSensitiveOnCompletionEnabled: '',
- StopOnSensitiveEnabled: '',
- SensitiveWords: '',
+ DefaultCollapseSidebar: false,
+ DemoSiteEnabled: false,
+ SelfUseModeEnabled: false,
+
+ /* 绘图设置 */
+ DrawingEnabled: false,
MjNotifyEnabled: false,
MjAccountFilterEnabled: false,
- MjModeClearEnabled: false,
MjForwardUrlEnabled: false,
+ MjModeClearEnabled: false,
MjActionCheckSuccessEnabled: false,
- DrawingEnabled: false,
+
+ /* 敏感词设置 */
+ CheckSensitiveEnabled: false,
+ CheckSensitiveOnPromptEnabled: false,
+ SensitiveWords: '',
+
+ /* 日志设置 */
+ LogConsumeEnabled: false,
+
+ /* 数据看板 */
DataExportEnabled: false,
DataExportDefaultTime: 'hour',
DataExportInterval: 5,
- DefaultCollapseSidebar: false, // 默认折叠侧边栏
- RetryTimes: 0,
- Chats: '[]',
- DemoSiteEnabled: false,
- SelfUseModeEnabled: false,
+
+ /* 监控设置 */
+ ChannelDisableThreshold: 0,
+ QuotaRemindThreshold: 0,
+ AutomaticDisableChannelEnabled: false,
+ AutomaticEnableChannelEnabled: false,
AutomaticDisableKeywords: '',
+
+ /* 聊天设置 */
+ Chats: '[]',
});
let [loading, setLoading] = useState(false);
@@ -74,22 +69,9 @@ const OperationSetting = () => {
if (success) {
let newInputs = {};
data.forEach((item) => {
- if (
- item.key === 'ModelRatio' ||
- item.key === 'GroupRatio' ||
- item.key === 'GroupGroupRatio' ||
- item.key === 'AutoGroups' ||
- item.key === 'UserUsableGroups' ||
- item.key === 'CompletionRatio' ||
- item.key === 'ModelPrice' ||
- item.key === 'CacheRatio'
- ) {
- item.value = JSON.stringify(JSON.parse(item.value), null, 2);
- }
if (
item.key.endsWith('Enabled') ||
- ['DefaultCollapseSidebar'].includes(item.key) ||
- ['DefaultUseAutoGroup'].includes(item.key)
+ ['DefaultCollapseSidebar'].includes(item.key)
) {
newInputs[item.key] = item.value === 'true' ? true : false;
} else {
@@ -153,24 +135,6 @@ const OperationSetting = () => {
- {/* 分组倍率设置 */}
-
-
-
- {/* 合并模型倍率设置和可视化倍率设置 */}
-
-
-
-
-
-
-
-
-
-
-
-
-
>
);
diff --git a/web/src/components/settings/RatioSetting.js b/web/src/components/settings/RatioSetting.js
new file mode 100644
index 00000000..bf97282c
--- /dev/null
+++ b/web/src/components/settings/RatioSetting.js
@@ -0,0 +1,109 @@
+import React, { useEffect, useState } from 'react';
+import { Card, Spin, Tabs } from '@douyinfe/semi-ui';
+import { useTranslation } from 'react-i18next';
+
+import GroupRatioSettings from '../../pages/Setting/Ratio/GroupRatioSettings.js';
+import ModelRatioSettings from '../../pages/Setting/Ratio/ModelRatioSettings.js';
+import ModelSettingsVisualEditor from '../../pages/Setting/Ratio/ModelSettingsVisualEditor.js';
+import ModelRatioNotSetEditor from '../../pages/Setting/Ratio/ModelRationNotSetEditor.js';
+
+import { API, showError } from '../../helpers';
+
+const RatioSetting = () => {
+ const { t } = useTranslation();
+
+ let [inputs, setInputs] = useState({
+ ModelPrice: '',
+ ModelRatio: '',
+ CacheRatio: '',
+ CompletionRatio: '',
+ GroupRatio: '',
+ GroupGroupRatio: '',
+ AutoGroups: '',
+ DefaultUseAutoGroup: false,
+ UserUsableGroups: '',
+ });
+
+ const [loading, setLoading] = useState(false);
+
+ const getOptions = async () => {
+ const res = await API.get('/api/option/');
+ const { success, message, data } = res.data;
+ if (success) {
+ let newInputs = {};
+ data.forEach((item) => {
+ if (
+ item.key === 'ModelRatio' ||
+ item.key === 'GroupRatio' ||
+ item.key === 'GroupGroupRatio' ||
+ item.key === 'AutoGroups' ||
+ item.key === 'UserUsableGroups' ||
+ item.key === 'CompletionRatio' ||
+ item.key === 'ModelPrice' ||
+ item.key === 'CacheRatio'
+ ) {
+ try {
+ item.value = JSON.stringify(JSON.parse(item.value), null, 2);
+ } catch (e) {
+ // 如果后端返回的不是合法 JSON,直接展示
+ }
+ }
+ if (['DefaultUseAutoGroup'].includes(item.key)) {
+ newInputs[item.key] = item.value === 'true' ? true : false;
+ } else {
+ newInputs[item.key] = item.value;
+ }
+ });
+ setInputs(newInputs);
+ } else {
+ showError(message);
+ }
+ };
+
+ const onRefresh = async () => {
+ try {
+ setLoading(true);
+ await getOptions();
+ } catch (error) {
+ showError('刷新失败');
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ onRefresh();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ return (
+
+ {/* 分组倍率设置 */}
+
+
+
+ {/* 模型倍率设置以及可视化编辑器 */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default RatioSetting;
\ No newline at end of file
diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json
index b456fff5..fc80f9c1 100644
--- a/web/src/i18n/locales/en.json
+++ b/web/src/i18n/locales/en.json
@@ -1588,7 +1588,7 @@
"性能指标": "Performance Indicators",
"模型数据分析": "Model Data Analysis",
"搜索无结果": "No results found",
- "仪表盘配置": "Dashboard Configuration",
+ "仪表盘设置": "Dashboard Settings",
"API信息管理,可以配置多个API地址用于状态展示和负载均衡(最多50个)": "API information management, you can configure multiple API addresses for status display and load balancing (maximum 50)",
"线路描述": "Route description",
"颜色": "Color",
diff --git a/web/src/pages/Setting/Operation/GroupRatioSettings.js b/web/src/pages/Setting/Ratio/GroupRatioSettings.js
similarity index 99%
rename from web/src/pages/Setting/Operation/GroupRatioSettings.js
rename to web/src/pages/Setting/Ratio/GroupRatioSettings.js
index 4a51a98c..3c7c754b 100644
--- a/web/src/pages/Setting/Operation/GroupRatioSettings.js
+++ b/web/src/pages/Setting/Ratio/GroupRatioSettings.js
@@ -184,16 +184,16 @@ export default function GroupRatioSettings(props) {
if (!value || value.trim() === '') {
return true; // Allow empty values
}
-
+
// First check if it's valid JSON
try {
const parsed = JSON.parse(value);
-
+
// Check if it's an array
if (!Array.isArray(parsed)) {
return false;
}
-
+
// Check if every element is a string
return parsed.every(item => typeof item === 'string');
} catch (error) {
diff --git a/web/src/pages/Setting/Operation/ModelRatioSettings.js b/web/src/pages/Setting/Ratio/ModelRatioSettings.js
similarity index 100%
rename from web/src/pages/Setting/Operation/ModelRatioSettings.js
rename to web/src/pages/Setting/Ratio/ModelRatioSettings.js
diff --git a/web/src/pages/Setting/Operation/ModelRationNotSetEditor.js b/web/src/pages/Setting/Ratio/ModelRationNotSetEditor.js
similarity index 100%
rename from web/src/pages/Setting/Operation/ModelRationNotSetEditor.js
rename to web/src/pages/Setting/Ratio/ModelRationNotSetEditor.js
diff --git a/web/src/pages/Setting/Operation/ModelSettingsVisualEditor.js b/web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.js
similarity index 100%
rename from web/src/pages/Setting/Operation/ModelSettingsVisualEditor.js
rename to web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.js
diff --git a/web/src/pages/Setting/index.js b/web/src/pages/Setting/index.js
index dc48c8dc..5572e540 100644
--- a/web/src/pages/Setting/index.js
+++ b/web/src/pages/Setting/index.js
@@ -10,6 +10,7 @@ import OperationSetting from '../../components/settings/OperationSetting.js';
import RateLimitSetting from '../../components/settings/RateLimitSetting.js';
import ModelSetting from '../../components/settings/ModelSetting.js';
import DashboardSetting from '../../components/settings/DashboardSetting.js';
+import RatioSetting from '../../components/settings/RatioSetting.js';
const Setting = () => {
const { t } = useTranslation();
@@ -24,6 +25,11 @@ const Setting = () => {
content: ,
itemKey: 'operation',
});
+ panes.push({
+ tab: t('倍率设置'),
+ content: ,
+ itemKey: 'ratio',
+ });
panes.push({
tab: t('速率限制设置'),
content: ,
@@ -45,7 +51,7 @@ const Setting = () => {
itemKey: 'other',
});
panes.push({
- tab: t('仪表盘配置'),
+ tab: t('仪表盘设置'),
content: ,
itemKey: 'dashboard',
});