diff --git a/web/src/components/OperationSetting.js b/web/src/components/OperationSetting.js
index 31345a5..2529ca2 100644
--- a/web/src/components/OperationSetting.js
+++ b/web/src/components/OperationSetting.js
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { Divider, Form, Grid, Header } from 'semantic-ui-react';
-import { Card } 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';
@@ -8,6 +8,7 @@ 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 SettingsMagnification from '../pages/Setting/Operation/SettingsMagnification.js';
import {
API,
@@ -17,10 +18,7 @@ import {
verifyJSON,
} from '../helpers';
-import { useTheme } from '../context/Theme';
-
const OperationSetting = () => {
- let now = new Date();
let [inputs, setInputs] = useState({
QuotaForNewUser: 0,
QuotaForInviter: 0,
@@ -58,7 +56,7 @@ const OperationSetting = () => {
DefaultCollapseSidebar: false, // 默认折叠侧边栏
RetryTimes: 0,
});
- const [originInputs, setOriginInputs] = useState({});
+
let [loading, setLoading] = useState(false);
const getOptions = async () => {
@@ -86,271 +84,62 @@ const OperationSetting = () => {
});
setInputs(newInputs);
- setOriginInputs(newInputs);
} else {
showError(message);
}
};
-
- const theme = useTheme();
- const isDark = theme === 'dark';
+ async function onRefresh() {
+ try {
+ setLoading(true);
+ await getOptions();
+ showSuccess('刷新成功');
+ } catch (error) {
+ showError('刷新失败');
+ } finally {
+ setLoading(false);
+ }
+ }
useEffect(() => {
- getOptions().then();
+ getOptions();
}, []);
- const updateOption = async (key, value) => {
- setLoading(true);
- if (key.endsWith('Enabled')) {
- value = inputs[key] === 'true' ? 'false' : 'true';
- }
- if (key === 'DefaultCollapseSidebar') {
- value = inputs[key] === 'true' ? 'false' : 'true';
- }
- console.log(key, value);
- const res = await API.put('/api/option/', {
- key,
- value,
- });
- const { success, message } = res.data;
- if (success) {
- setInputs((inputs) => ({ ...inputs, [key]: value }));
- } else {
- showError(message);
- }
- setLoading(false);
- };
-
- const handleInputChange = async (e, { name, value }) => {
- if (
- name.endsWith('Enabled') ||
- name === 'DataExportInterval' ||
- name === 'DataExportDefaultTime' ||
- name === 'DefaultCollapseSidebar'
- ) {
- if (name === 'DataExportDefaultTime') {
- localStorage.setItem('data_export_default_time', value);
- } else if (name === 'MjNotifyEnabled') {
- localStorage.setItem('mj_notify_enabled', value);
- }
- await updateOption(name, value);
- } else {
- setInputs((inputs) => ({ ...inputs, [name]: value }));
- }
- };
-
- const submitConfig = async (group) => {
- switch (group) {
- case 'monitor':
- if (
- originInputs['ChannelDisableThreshold'] !==
- inputs.ChannelDisableThreshold
- ) {
- await updateOption(
- 'ChannelDisableThreshold',
- inputs.ChannelDisableThreshold,
- );
- }
- if (
- originInputs['QuotaRemindThreshold'] !== inputs.QuotaRemindThreshold
- ) {
- await updateOption(
- 'QuotaRemindThreshold',
- inputs.QuotaRemindThreshold,
- );
- }
- break;
- case 'ratio':
- if (originInputs['ModelRatio'] !== inputs.ModelRatio) {
- if (!verifyJSON(inputs.ModelRatio)) {
- showError('模型倍率不是合法的 JSON 字符串');
- return;
- }
- await updateOption('ModelRatio', inputs.ModelRatio);
- }
- if (originInputs['CompletionRatio'] !== inputs.CompletionRatio) {
- if (!verifyJSON(inputs.CompletionRatio)) {
- showError('模型补全倍率不是合法的 JSON 字符串');
- return;
- }
- await updateOption('CompletionRatio', inputs.CompletionRatio);
- }
- if (originInputs['GroupRatio'] !== inputs.GroupRatio) {
- if (!verifyJSON(inputs.GroupRatio)) {
- showError('分组倍率不是合法的 JSON 字符串');
- return;
- }
- await updateOption('GroupRatio', inputs.GroupRatio);
- }
- if (originInputs['ModelPrice'] !== inputs.ModelPrice) {
- if (!verifyJSON(inputs.ModelPrice)) {
- showError('模型固定价格不是合法的 JSON 字符串');
- return;
- }
- await updateOption('ModelPrice', inputs.ModelPrice);
- }
- break;
- case 'words':
- if (originInputs['SensitiveWords'] !== inputs.SensitiveWords) {
- await updateOption('SensitiveWords', inputs.SensitiveWords);
- }
- break;
- case 'quota':
- if (originInputs['QuotaForNewUser'] !== inputs.QuotaForNewUser) {
- await updateOption('QuotaForNewUser', inputs.QuotaForNewUser);
- }
- if (originInputs['QuotaForInvitee'] !== inputs.QuotaForInvitee) {
- await updateOption('QuotaForInvitee', inputs.QuotaForInvitee);
- }
- if (originInputs['QuotaForInviter'] !== inputs.QuotaForInviter) {
- await updateOption('QuotaForInviter', inputs.QuotaForInviter);
- }
- if (originInputs['PreConsumedQuota'] !== inputs.PreConsumedQuota) {
- await updateOption('PreConsumedQuota', inputs.PreConsumedQuota);
- }
- break;
- case 'general':
- if (originInputs['TopUpLink'] !== inputs.TopUpLink) {
- await updateOption('TopUpLink', inputs.TopUpLink);
- }
- if (originInputs['ChatLink'] !== inputs.ChatLink) {
- await updateOption('ChatLink', inputs.ChatLink);
- }
- if (originInputs['ChatLink2'] !== inputs.ChatLink2) {
- await updateOption('ChatLink2', inputs.ChatLink2);
- }
- if (originInputs['QuotaPerUnit'] !== inputs.QuotaPerUnit) {
- await updateOption('QuotaPerUnit', inputs.QuotaPerUnit);
- }
- if (originInputs['RetryTimes'] !== inputs.RetryTimes) {
- await updateOption('RetryTimes', inputs.RetryTimes);
- }
- break;
- }
- };
return (
<>
- {/* 通用设置 */}
-
-
-
- {/* 绘图设置 */}
-
-
-
- {/* 屏蔽词过滤设置 */}
-
-
-
- {/* 日志设置 */}
-
-
-
- {/* 数据看板 */}
-
-
-
- {/* 监控设置 */}
-
-
-
- {/* 额度设置 */}
-
-
-
-
-
- */}
- {/* */}
- {/**/}
- {/**/}
- {/* */}
- {/**/}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {
- submitConfig('ratio').then();
- }}
- >
- 保存倍率设置
-
-
-
-
+
+ {/* 通用设置 */}
+
+
+
+ {/* 绘图设置 */}
+
+
+
+ {/* 屏蔽词过滤设置 */}
+
+
+
+ {/* 日志设置 */}
+
+
+
+ {/* 数据看板 */}
+
+
+
+ {/* 监控设置 */}
+
+
+
+ {/* 额度设置 */}
+
+
+
+ {/* 倍率设置 */}
+
+
+
+
>
);
};
diff --git a/web/src/pages/Setting/Operation/SettingsMagnification.js b/web/src/pages/Setting/Operation/SettingsMagnification.js
new file mode 100644
index 0000000..3f38b37
--- /dev/null
+++ b/web/src/pages/Setting/Operation/SettingsMagnification.js
@@ -0,0 +1,193 @@
+import React, { useEffect, useState, useRef } from 'react';
+import { Button, Col, Form, Row, Spin } from '@douyinfe/semi-ui';
+import {
+ compareObjects,
+ API,
+ showError,
+ showSuccess,
+ showWarning,
+ verifyJSON,
+} from '../../../helpers';
+
+export default function SettingsMagnification(props) {
+ const [loading, setLoading] = useState(false);
+ const [inputs, setInputs] = useState({
+ ModelPrice: '',
+ ModelRatio: '',
+ CompletionRatio: '',
+ GroupRatio: '',
+ });
+ const refForm = useRef();
+ const [inputsRow, setInputsRow] = useState(inputs);
+
+ async function onSubmit() {
+ try {
+ await refForm.current.validate();
+ const updateArray = compareObjects(inputs, inputsRow);
+ if (!updateArray.length) return showWarning('你似乎并没有修改什么');
+ const requestQueue = updateArray.map((item) => {
+ let value = '';
+ if (typeof inputs[item.key] === 'boolean') {
+ value = String(inputs[item.key]);
+ } else {
+ value = inputs[item.key];
+ }
+ return API.put('/api/option/', {
+ key: item.key,
+ value,
+ });
+ });
+ setLoading(true);
+ Promise.all(requestQueue)
+ .then((res) => {
+ if (requestQueue.length === 1) {
+ if (res.includes(undefined)) return;
+ } else if (requestQueue.length > 1) {
+ if (res.includes(undefined)) return showError('部分更新失败');
+ }
+ showSuccess('更新成功');
+ })
+ .catch(() => {
+ showError('更新失败');
+ })
+ .finally(() => {
+ setLoading(false);
+ setInputsRow(structuredClone(inputs));
+ });
+ } catch (error) {
+ showError('请检查输入');
+ console.error(error);
+ } finally {
+ }
+ }
+
+ useEffect(() => {
+ const currentInputs = {};
+ for (let key in props.options) {
+ if (Object.keys(inputs).includes(key)) {
+ currentInputs[key] = props.options[key];
+ }
+ }
+ setInputs(currentInputs);
+ setInputsRow(structuredClone(currentInputs));
+ refForm.current.setValues(currentInputs);
+ }, [props.options]);
+ return (
+ <>
+
+
+
+
+ verifyJSON(value),
+ message: '不是合法的 JSON 字符串',
+ },
+ ]}
+ onChange={(value) =>
+ setInputs({
+ ...inputs,
+ ModelPrice: value,
+ })
+ }
+ />
+
+
+
+
+ verifyJSON(value),
+ message: '不是合法的 JSON 字符串',
+ },
+ ]}
+ onChange={(value) =>
+ setInputs({
+ ...inputs,
+ ModelRatio: value,
+ })
+ }
+ />
+
+
+
+
+ verifyJSON(value),
+ message: '不是合法的 JSON 字符串',
+ },
+ ]}
+ onChange={(value) =>
+ setInputs({
+ ...inputs,
+ CompletionRatio: value,
+ })
+ }
+ />
+
+
+
+
+ verifyJSON(value),
+ message: '不是合法的 JSON 字符串',
+ },
+ ]}
+ onChange={(value) =>
+ setInputs({
+ ...inputs,
+ GroupRatio: value,
+ })
+ }
+ />
+
+
+
+
+
+
+
+
+
+ >
+ );
+}