mirror of
				https://github.com/songquanpeng/one-api.git
				synced 2025-11-04 15:53:42 +08:00 
			
		
		
		
	feat: i18n support
This commit is contained in:
		@@ -596,6 +596,77 @@
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "operation": {
 | 
			
		||||
      "quota": {
 | 
			
		||||
        "title": "Quota Settings",
 | 
			
		||||
        "new_user": "Initial Quota for New Users",
 | 
			
		||||
        "new_user_placeholder": "e.g.: 100",
 | 
			
		||||
        "pre_consume": "Pre-consumed Quota per Request",
 | 
			
		||||
        "pre_consume_placeholder": "Refund or charge difference after request",
 | 
			
		||||
        "inviter_reward": "Reward Quota for Inviter",
 | 
			
		||||
        "inviter_reward_placeholder": "e.g.: 2000",
 | 
			
		||||
        "invitee_reward": "Reward Quota for Using Invite Code",
 | 
			
		||||
        "invitee_reward_placeholder": "e.g.: 1000",
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "save": "Save Quota Settings"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "ratio": {
 | 
			
		||||
        "title": "Ratio Settings",
 | 
			
		||||
        "model": {
 | 
			
		||||
          "title": "Model Ratio",
 | 
			
		||||
          "placeholder": "A JSON text where keys are model names and values are ratios"
 | 
			
		||||
        },
 | 
			
		||||
        "completion": {
 | 
			
		||||
          "title": "Completion Ratio",
 | 
			
		||||
          "placeholder": "A JSON text where keys are model names and values are ratios. These ratios are the proportion of completion to prompt ratio, which can override One API's internal ratios"
 | 
			
		||||
        },
 | 
			
		||||
        "group": {
 | 
			
		||||
          "title": "Group Ratio",
 | 
			
		||||
          "placeholder": "A JSON text where keys are group names and values are ratios"
 | 
			
		||||
        },
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "save": "Save Ratio Settings"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "log": {
 | 
			
		||||
        "title": "Log Settings",
 | 
			
		||||
        "enable_consume": "Enable Quota Consumption Logging",
 | 
			
		||||
        "target_time": "Target Time",
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "clean": "Clean Historical Logs"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "monitor": {
 | 
			
		||||
        "title": "Monitor Settings",
 | 
			
		||||
        "max_response_time": "Maximum Response Time",
 | 
			
		||||
        "max_response_time_placeholder": "In seconds, channels exceeding this time during testing will be automatically disabled",
 | 
			
		||||
        "quota_reminder": "Quota Reminder Threshold",
 | 
			
		||||
        "quota_reminder_placeholder": "Users will receive email reminders when quota falls below this value",
 | 
			
		||||
        "auto_disable": "Automatically Disable Channel on Failure",
 | 
			
		||||
        "auto_enable": "Automatically Enable Channel on Success",
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "save": "Save Monitor Settings"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "general": {
 | 
			
		||||
        "title": "General Settings",
 | 
			
		||||
        "topup_link": "Top-up Link",
 | 
			
		||||
        "topup_link_placeholder": "e.g.: Card selling website purchase link",
 | 
			
		||||
        "chat_link": "Chat Page Link",
 | 
			
		||||
        "chat_link_placeholder": "e.g.: ChatGPT Next Web deployment address",
 | 
			
		||||
        "quota_per_unit": "Quota per Dollar",
 | 
			
		||||
        "quota_per_unit_placeholder": "Quota exchangeable per unit of currency",
 | 
			
		||||
        "retry_times": "Retry Times on Failure",
 | 
			
		||||
        "retry_times_placeholder": "Number of retry attempts on failure",
 | 
			
		||||
        "display_in_currency": "Display Quota in Currency Format",
 | 
			
		||||
        "display_token_stat": "Show Token Quota Instead of User Quota in Billing APIs",
 | 
			
		||||
        "approximate_token": "Use Approximate Method to Estimate Token Count",
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "save": "Save General Settings"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -596,6 +596,77 @@
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "operation": {
 | 
			
		||||
      "quota": {
 | 
			
		||||
        "title": "额度设置",
 | 
			
		||||
        "new_user": "新用户初始额度",
 | 
			
		||||
        "new_user_placeholder": "例如:100",
 | 
			
		||||
        "pre_consume": "请求预扣费额度",
 | 
			
		||||
        "pre_consume_placeholder": "请求结束后多退少补",
 | 
			
		||||
        "inviter_reward": "邀请新用户奖励额度",
 | 
			
		||||
        "inviter_reward_placeholder": "例如:2000",
 | 
			
		||||
        "invitee_reward": "新用户使用邀请码奖励额度",
 | 
			
		||||
        "invitee_reward_placeholder": "例如:1000",
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "save": "保存额度设置"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "ratio": {
 | 
			
		||||
        "title": "倍率设置",
 | 
			
		||||
        "model": {
 | 
			
		||||
          "title": "模型倍率",
 | 
			
		||||
          "placeholder": "为一个 JSON 文本,键为模型名称,值为倍率"
 | 
			
		||||
        },
 | 
			
		||||
        "completion": {
 | 
			
		||||
          "title": "补全倍率",
 | 
			
		||||
          "placeholder": "为一个 JSON 文本,键为模型名称,值为倍率,此处的倍率设置是模型补全倍率相较于提示倍率的比例,使用该设置可强制覆盖 One API 的内部比例"
 | 
			
		||||
        },
 | 
			
		||||
        "group": {
 | 
			
		||||
          "title": "分组倍率",
 | 
			
		||||
          "placeholder": "为一个 JSON 文本,键为分组名称,值为倍率"
 | 
			
		||||
        },
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "save": "保存倍率设置"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "log": {
 | 
			
		||||
        "title": "日志设置",
 | 
			
		||||
        "enable_consume": "启用额度消费日志记录",
 | 
			
		||||
        "target_time": "目标时间",
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "clean": "清理历史日志"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "monitor": {
 | 
			
		||||
        "title": "监控设置",
 | 
			
		||||
        "max_response_time": "最长响应时间",
 | 
			
		||||
        "max_response_time_placeholder": "单位秒,当运行渠道全部测试时,超过此时间将自动禁用渠道",
 | 
			
		||||
        "quota_reminder": "额度提醒阈值",
 | 
			
		||||
        "quota_reminder_placeholder": "低于此额度时将发送邮件提醒用户",
 | 
			
		||||
        "auto_disable": "失败时自动禁用渠道",
 | 
			
		||||
        "auto_enable": "成功时自动启用渠道",
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "save": "保存监控设置"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "general": {
 | 
			
		||||
        "title": "通用设置",
 | 
			
		||||
        "topup_link": "充值链接",
 | 
			
		||||
        "topup_link_placeholder": "例如发卡网站的购买链接",
 | 
			
		||||
        "chat_link": "聊天页面链接",
 | 
			
		||||
        "chat_link_placeholder": "例如 ChatGPT Next Web 的部署地址",
 | 
			
		||||
        "quota_per_unit": "单位美元额度",
 | 
			
		||||
        "quota_per_unit_placeholder": "一单位货币能兑换的额度",
 | 
			
		||||
        "retry_times": "失败重试次数",
 | 
			
		||||
        "retry_times_placeholder": "失败重试次数",
 | 
			
		||||
        "display_in_currency": "以货币形式显示额度",
 | 
			
		||||
        "display_token_stat": "Billing 相关 API 显示令牌额度而非用户额度",
 | 
			
		||||
        "approximate_token": "使用近似的方式估算 token 数以减少计算量",
 | 
			
		||||
        "buttons": {
 | 
			
		||||
          "save": "保存通用设置"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,10 @@
 | 
			
		||||
import React, { useEffect, useState } from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
import { Divider, Form, Grid, Header } from 'semantic-ui-react';
 | 
			
		||||
import { API, showError, showSuccess, timestamp2string, verifyJSON } from '../helpers';
 | 
			
		||||
 | 
			
		||||
const OperationSetting = () => {
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  let now = new Date();
 | 
			
		||||
  let [inputs, setInputs] = useState({
 | 
			
		||||
    QuotaForNewUser: 0,
 | 
			
		||||
@@ -160,39 +162,201 @@ const OperationSetting = () => {
 | 
			
		||||
      <Grid.Column>
 | 
			
		||||
        <Form loading={loading}>
 | 
			
		||||
          <Header as='h3'>
 | 
			
		||||
            通用设置
 | 
			
		||||
            {t('setting.operation.quota.title')}
 | 
			
		||||
          </Header>
 | 
			
		||||
          <Form.Group widths='equal'>
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label={t('setting.operation.quota.new_user')}
 | 
			
		||||
              name='QuotaForNewUser'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.QuotaForNewUser}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder={t('setting.operation.quota.new_user_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label={t('setting.operation.quota.pre_consume')}
 | 
			
		||||
              name='PreConsumedQuota'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.PreConsumedQuota}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder={t('setting.operation.quota.pre_consume_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label={t('setting.operation.quota.inviter_reward')}
 | 
			
		||||
              name='QuotaForInviter'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.QuotaForInviter}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder={t('setting.operation.quota.inviter_reward_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label={t('setting.operation.quota.invitee_reward')}
 | 
			
		||||
              name='QuotaForInvitee'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.QuotaForInvitee}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder={t('setting.operation.quota.invitee_reward_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Button onClick={() => {
 | 
			
		||||
            submitConfig('quota').then();
 | 
			
		||||
          }}>
 | 
			
		||||
            {t('setting.operation.quota.buttons.save')}
 | 
			
		||||
          </Form.Button>
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <Header as='h3'>
 | 
			
		||||
            {t('setting.operation.ratio.title')}
 | 
			
		||||
          </Header>
 | 
			
		||||
          <Form.Group widths='equal'>
 | 
			
		||||
            <Form.TextArea
 | 
			
		||||
              label={t('setting.operation.ratio.model.title')}
 | 
			
		||||
              name='ModelRatio'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.ModelRatio}
 | 
			
		||||
              placeholder={t('setting.operation.ratio.model.placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Group widths='equal'>
 | 
			
		||||
            <Form.TextArea
 | 
			
		||||
              label={t('setting.operation.ratio.completion.title')}
 | 
			
		||||
              name='CompletionRatio'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.CompletionRatio}
 | 
			
		||||
              placeholder={t('setting.operation.ratio.completion.placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Group widths='equal'>
 | 
			
		||||
            <Form.TextArea
 | 
			
		||||
              label={t('setting.operation.ratio.group.title')}
 | 
			
		||||
              name='GroupRatio'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.GroupRatio}
 | 
			
		||||
              placeholder={t('setting.operation.ratio.group.placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Button onClick={() => {
 | 
			
		||||
            submitConfig('ratio').then();
 | 
			
		||||
          }}>
 | 
			
		||||
            {t('setting.operation.ratio.buttons.save')}
 | 
			
		||||
          </Form.Button>
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <Header as='h3'>{t('setting.operation.log.title')}</Header>
 | 
			
		||||
          <Form.Group inline>
 | 
			
		||||
            <Form.Checkbox
 | 
			
		||||
              checked={inputs.LogConsumeEnabled === 'true'}
 | 
			
		||||
              label={t('setting.operation.log.enable_consume')}
 | 
			
		||||
              name='LogConsumeEnabled'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Group widths={4}>
 | 
			
		||||
            <Form.Input 
 | 
			
		||||
              label={t('setting.operation.log.target_time')} 
 | 
			
		||||
              value={historyTimestamp} 
 | 
			
		||||
              type='datetime-local'
 | 
			
		||||
              name='history_timestamp'
 | 
			
		||||
              onChange={(e, { name, value }) => {
 | 
			
		||||
                setHistoryTimestamp(value);
 | 
			
		||||
              }} 
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Button onClick={() => {
 | 
			
		||||
            deleteHistoryLogs().then();
 | 
			
		||||
          }}>
 | 
			
		||||
            {t('setting.operation.log.buttons.clean')}
 | 
			
		||||
          </Form.Button>
 | 
			
		||||
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <Header as='h3'>{t('setting.operation.monitor.title')}</Header>
 | 
			
		||||
          <Form.Group widths={3}>
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label={t('setting.operation.monitor.max_response_time')}
 | 
			
		||||
              name='ChannelDisableThreshold'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.ChannelDisableThreshold}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder={t('setting.operation.monitor.max_response_time_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label={t('setting.operation.monitor.quota_reminder')}
 | 
			
		||||
              name='QuotaRemindThreshold'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.QuotaRemindThreshold}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder={t('setting.operation.monitor.quota_reminder_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Group inline>
 | 
			
		||||
            <Form.Checkbox
 | 
			
		||||
              checked={inputs.AutomaticDisableChannelEnabled === 'true'}
 | 
			
		||||
              label={t('setting.operation.monitor.auto_disable')}
 | 
			
		||||
              name='AutomaticDisableChannelEnabled'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Checkbox
 | 
			
		||||
              checked={inputs.AutomaticEnableChannelEnabled === 'true'}
 | 
			
		||||
              label={t('setting.operation.monitor.auto_enable')}
 | 
			
		||||
              name='AutomaticEnableChannelEnabled'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Button onClick={() => {
 | 
			
		||||
            submitConfig('monitor').then();
 | 
			
		||||
          }}>
 | 
			
		||||
            {t('setting.operation.monitor.buttons.save')}
 | 
			
		||||
          </Form.Button>
 | 
			
		||||
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <Header as='h3'>{t('setting.operation.general.title')}</Header>
 | 
			
		||||
          <Form.Group widths={4}>
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='充值链接'
 | 
			
		||||
              label={t('setting.operation.general.topup_link')}
 | 
			
		||||
              name='TopUpLink'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.TopUpLink}
 | 
			
		||||
              type='link'
 | 
			
		||||
              placeholder='例如发卡网站的购买链接'
 | 
			
		||||
              placeholder={t('setting.operation.general.topup_link_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='聊天页面链接'
 | 
			
		||||
              label={t('setting.operation.general.chat_link')}
 | 
			
		||||
              name='ChatLink'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.ChatLink}
 | 
			
		||||
              type='link'
 | 
			
		||||
              placeholder='例如 ChatGPT Next Web 的部署地址'
 | 
			
		||||
              placeholder={t('setting.operation.general.chat_link_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='单位美元额度'
 | 
			
		||||
              label={t('setting.operation.general.quota_per_unit')}
 | 
			
		||||
              name='QuotaPerUnit'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.QuotaPerUnit}
 | 
			
		||||
              type='number'
 | 
			
		||||
              step='0.01'
 | 
			
		||||
              placeholder='一单位货币能兑换的额度'
 | 
			
		||||
              placeholder={t('setting.operation.general.quota_per_unit_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='失败重试次数'
 | 
			
		||||
              label={t('setting.operation.general.retry_times')}
 | 
			
		||||
              name='RetryTimes'
 | 
			
		||||
              type={'number'}
 | 
			
		||||
              step='1'
 | 
			
		||||
@@ -200,186 +364,34 @@ const OperationSetting = () => {
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.RetryTimes}
 | 
			
		||||
              placeholder='失败重试次数'
 | 
			
		||||
              placeholder={t('setting.operation.general.retry_times_placeholder')}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Group inline>
 | 
			
		||||
            <Form.Checkbox
 | 
			
		||||
              checked={inputs.DisplayInCurrencyEnabled === 'true'}
 | 
			
		||||
              label='以货币形式显示额度'
 | 
			
		||||
              label={t('setting.operation.general.display_in_currency')}
 | 
			
		||||
              name='DisplayInCurrencyEnabled'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Checkbox
 | 
			
		||||
              checked={inputs.DisplayTokenStatEnabled === 'true'}
 | 
			
		||||
              label='Billing 相关 API 显示令牌额度而非用户额度'
 | 
			
		||||
              label={t('setting.operation.general.display_token_stat')}
 | 
			
		||||
              name='DisplayTokenStatEnabled'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Checkbox
 | 
			
		||||
              checked={inputs.ApproximateTokenEnabled === 'true'}
 | 
			
		||||
              label='使用近似的方式估算 token 数以减少计算量'
 | 
			
		||||
              label={t('setting.operation.general.approximate_token')}
 | 
			
		||||
              name='ApproximateTokenEnabled'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Button onClick={() => {
 | 
			
		||||
            submitConfig('general').then();
 | 
			
		||||
          }}>保存通用设置</Form.Button>
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <Header as='h3'>
 | 
			
		||||
            日志设置
 | 
			
		||||
          </Header>
 | 
			
		||||
          <Form.Group inline>
 | 
			
		||||
            <Form.Checkbox
 | 
			
		||||
              checked={inputs.LogConsumeEnabled === 'true'}
 | 
			
		||||
              label='启用额度消费日志记录'
 | 
			
		||||
              name='LogConsumeEnabled'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Group widths={4}>
 | 
			
		||||
            <Form.Input label='目标时间' value={historyTimestamp} type='datetime-local'
 | 
			
		||||
                        name='history_timestamp'
 | 
			
		||||
                        onChange={(e, { name, value }) => {
 | 
			
		||||
                          setHistoryTimestamp(value);
 | 
			
		||||
                        }} />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Button onClick={() => {
 | 
			
		||||
            deleteHistoryLogs().then();
 | 
			
		||||
          }}>清理历史日志</Form.Button>
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <Header as='h3'>
 | 
			
		||||
            监控设置
 | 
			
		||||
          </Header>
 | 
			
		||||
          <Form.Group widths={3}>
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='最长响应时间'
 | 
			
		||||
              name='ChannelDisableThreshold'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.ChannelDisableThreshold}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder='单位秒,当运行渠道全部测试时,超过此时间将自动禁用渠道'
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='额度提醒阈值'
 | 
			
		||||
              name='QuotaRemindThreshold'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.QuotaRemindThreshold}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder='低于此额度时将发送邮件提醒用户'
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Group inline>
 | 
			
		||||
            <Form.Checkbox
 | 
			
		||||
              checked={inputs.AutomaticDisableChannelEnabled === 'true'}
 | 
			
		||||
              label='失败时自动禁用渠道'
 | 
			
		||||
              name='AutomaticDisableChannelEnabled'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Checkbox
 | 
			
		||||
              checked={inputs.AutomaticEnableChannelEnabled === 'true'}
 | 
			
		||||
              label='成功时自动启用渠道'
 | 
			
		||||
              name='AutomaticEnableChannelEnabled'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Button onClick={() => {
 | 
			
		||||
            submitConfig('monitor').then();
 | 
			
		||||
          }}>保存监控设置</Form.Button>
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <Header as='h3'>
 | 
			
		||||
            额度设置
 | 
			
		||||
          </Header>
 | 
			
		||||
          <Form.Group widths={4}>
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='新用户初始额度'
 | 
			
		||||
              name='QuotaForNewUser'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.QuotaForNewUser}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder='例如:100'
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='请求预扣费额度'
 | 
			
		||||
              name='PreConsumedQuota'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.PreConsumedQuota}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder='请求结束后多退少补'
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='邀请新用户奖励额度'
 | 
			
		||||
              name='QuotaForInviter'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.QuotaForInviter}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder='例如:2000'
 | 
			
		||||
            />
 | 
			
		||||
            <Form.Input
 | 
			
		||||
              label='新用户使用邀请码奖励额度'
 | 
			
		||||
              name='QuotaForInvitee'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.QuotaForInvitee}
 | 
			
		||||
              type='number'
 | 
			
		||||
              min='0'
 | 
			
		||||
              placeholder='例如:1000'
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Button onClick={() => {
 | 
			
		||||
            submitConfig('quota').then();
 | 
			
		||||
          }}>保存额度设置</Form.Button>
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <Header as='h3'>
 | 
			
		||||
            倍率设置
 | 
			
		||||
          </Header>
 | 
			
		||||
          <Form.Group widths='equal'>
 | 
			
		||||
            <Form.TextArea
 | 
			
		||||
              label='模型倍率'
 | 
			
		||||
              name='ModelRatio'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.ModelRatio}
 | 
			
		||||
              placeholder='为一个 JSON 文本,键为模型名称,值为倍率'
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Group widths='equal'>
 | 
			
		||||
            <Form.TextArea
 | 
			
		||||
              label='补全倍率'
 | 
			
		||||
              name='CompletionRatio'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.CompletionRatio}
 | 
			
		||||
              placeholder='为一个 JSON 文本,键为模型名称,值为倍率,此处的倍率设置是模型补全倍率相较于提示倍率的比例,使用该设置可强制覆盖 One API 的内部比例'
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Group widths='equal'>
 | 
			
		||||
            <Form.TextArea
 | 
			
		||||
              label='分组倍率'
 | 
			
		||||
              name='GroupRatio'
 | 
			
		||||
              onChange={handleInputChange}
 | 
			
		||||
              style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
 | 
			
		||||
              autoComplete='new-password'
 | 
			
		||||
              value={inputs.GroupRatio}
 | 
			
		||||
              placeholder='为一个 JSON 文本,键为分组名称,值为倍率'
 | 
			
		||||
            />
 | 
			
		||||
          </Form.Group>
 | 
			
		||||
          <Form.Button onClick={() => {
 | 
			
		||||
            submitConfig('ratio').then();
 | 
			
		||||
          }}>保存倍率设置</Form.Button>
 | 
			
		||||
          }}>
 | 
			
		||||
            {t('setting.operation.general.buttons.save')}
 | 
			
		||||
          </Form.Button>
 | 
			
		||||
        </Form>
 | 
			
		||||
      </Grid.Column>
 | 
			
		||||
    </Grid>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user