Bläddra i källkod

🎨 refactor: Refactor RatioSetting: integrate Group Ratio Settings into tabs

* Moved `GroupRatioSettings` component inside the existing Tabs as a new **Group Ratios** tab.
* Removed the standalone `Card` that previously wrapped `GroupRatioSettings`.
* Re-formatted JSX props for `ModelRatioSettings` and `GroupRatioSettings` to improve readability.
* Consolidates all ratio-related settings into a single tabbed view for a cleaner and more consistent UI.
t0ng7u 8 månader sedan
förälder
incheckning
f7f1be9df2

+ 10 - 5
web/src/components/settings/RatioSetting.js

@@ -84,7 +84,16 @@ const RatioSetting = () => {
       <Card style={{ marginTop: '10px' }}>
         <Tabs type='card'>
           <Tabs.TabPane tab={t('模型倍率设置')} itemKey='model'>
-            <ModelRatioSettings options={inputs} refresh={onRefresh} />
+            <ModelRatioSettings
+              options={inputs}
+              refresh={onRefresh}
+            />
+          </Tabs.TabPane>
+          <Tabs.TabPane tab={t('分组倍率设置')} itemKey='group'>
+            <GroupRatioSettings
+              options={inputs}
+              refresh={onRefresh}
+            />
           </Tabs.TabPane>
           <Tabs.TabPane tab={t('可视化倍率设置')} itemKey='visual'>
             <ModelSettingsVisualEditor
@@ -106,10 +115,6 @@ const RatioSetting = () => {
           </Tabs.TabPane>
         </Tabs>
       </Card>
-      {/* 分组倍率设置 */}
-      <Card style={{ marginTop: '10px' }}>
-        <GroupRatioSettings options={inputs} refresh={onRefresh} />
-      </Card>
     </Spin>
   );
 };

+ 1 - 1
web/src/i18n/locales/en.json

@@ -1263,7 +1263,7 @@
   " 吗?": "?",
   "修改子渠道优先级": "Modify sub-channel priority",
   "确定要修改所有子渠道优先级为 ": "Confirm to modify all sub-channel priorities to ",
-  "分组设置": "Group settings",
+  "分组倍率设置": "Group ratio settings",
   "用户可选分组": "User selectable groups",
   "保存分组倍率设置": "Save group ratio settings",
   "模型倍率设置": "Model ratio settings",

+ 120 - 122
web/src/pages/Setting/Ratio/GroupRatioSettings.js

@@ -96,133 +96,131 @@ export default function GroupRatioSettings(props) {
         getFormApi={(formAPI) => (refForm.current = formAPI)}
         style={{ marginBottom: 15 }}
       >
-        <Form.Section text={t('分组设置')}>
-          <Row gutter={16}>
-            <Col xs={24} sm={16}>
-              <Form.TextArea
-                label={t('分组倍率')}
-                placeholder={t('为一个 JSON 文本,键为分组名称,值为倍率')}
-                extraText={t(
-                  '分组倍率设置,可以在此处新增分组或修改现有分组的倍率,格式为 JSON 字符串,例如:{"vip": 0.5, "test": 1},表示 vip 分组的倍率为 0.5,test 分组的倍率为 1',
-                )}
-                field={'GroupRatio'}
-                autosize={{ minRows: 6, maxRows: 12 }}
-                trigger='blur'
-                stopValidateWithError
-                rules={[
-                  {
-                    validator: (rule, value) => verifyJSON(value),
-                    message: t('不是合法的 JSON 字符串'),
-                  },
-                ]}
-                onChange={(value) =>
-                  setInputs({ ...inputs, GroupRatio: value })
-                }
-              />
-            </Col>
-          </Row>
-          <Row gutter={16}>
-            <Col xs={24} sm={16}>
-              <Form.TextArea
-                label={t('用户可选分组')}
-                placeholder={t('为一个 JSON 文本,键为分组名称,值为分组描述')}
-                extraText={t(
-                  '用户新建令牌时可选的分组,格式为 JSON 字符串,例如:{"vip": "VIP 用户", "test": "测试"},表示用户可以选择 vip 分组和 test 分组',
-                )}
-                field={'UserUsableGroups'}
-                autosize={{ minRows: 6, maxRows: 12 }}
-                trigger='blur'
-                stopValidateWithError
-                rules={[
-                  {
-                    validator: (rule, value) => verifyJSON(value),
-                    message: t('不是合法的 JSON 字符串'),
-                  },
-                ]}
-                onChange={(value) =>
-                  setInputs({ ...inputs, UserUsableGroups: value })
-                }
-              />
-            </Col>
-          </Row>
-          <Row gutter={16}>
-            <Col xs={24} sm={16}>
-              <Form.TextArea
-                label={t('分组特殊倍率')}
-                placeholder={t('为一个 JSON 文本')}
-                extraText={t(
-                  '键为分组名称,值为另一个 JSON 对象,键为分组名称,值为该分组的用户的特殊分组倍率,例如:{"vip": {"default": 0.5, "test": 1}},表示 vip 分组的用户在使用default分组的令牌时倍率为0.5,使用test分组时倍率为1',
-                )}
-                field={'GroupGroupRatio'}
-                autosize={{ minRows: 6, maxRows: 12 }}
-                trigger='blur'
-                stopValidateWithError
-                rules={[
-                  {
-                    validator: (rule, value) => verifyJSON(value),
-                    message: t('不是合法的 JSON 字符串'),
-                  },
-                ]}
-                onChange={(value) =>
-                  setInputs({ ...inputs, GroupGroupRatio: value })
-                }
-              />
-            </Col>
-          </Row>
-          <Row gutter={16}>
-            <Col xs={24} sm={16}>
-              <Form.TextArea
-                label={t('自动分组auto,从第一个开始选择')}
-                placeholder={t('为一个 JSON 文本')}
-                field={'AutoGroups'}
-                autosize={{ minRows: 6, maxRows: 12 }}
-                trigger='blur'
-                stopValidateWithError
-                rules={[
-                  {
-                    validator: (rule, value) => {
-                      if (!value || value.trim() === '') {
-                        return true; // Allow empty values
-                      }
-
-                      // First check if it's valid JSON
-                      try {
-                        const parsed = JSON.parse(value);
+        <Row gutter={16}>
+          <Col xs={24} sm={16}>
+            <Form.TextArea
+              label={t('分组倍率')}
+              placeholder={t('为一个 JSON 文本,键为分组名称,值为倍率')}
+              extraText={t(
+                '分组倍率设置,可以在此处新增分组或修改现有分组的倍率,格式为 JSON 字符串,例如:{"vip": 0.5, "test": 1},表示 vip 分组的倍率为 0.5,test 分组的倍率为 1',
+              )}
+              field={'GroupRatio'}
+              autosize={{ minRows: 6, maxRows: 12 }}
+              trigger='blur'
+              stopValidateWithError
+              rules={[
+                {
+                  validator: (rule, value) => verifyJSON(value),
+                  message: t('不是合法的 JSON 字符串'),
+                },
+              ]}
+              onChange={(value) =>
+                setInputs({ ...inputs, GroupRatio: value })
+              }
+            />
+          </Col>
+        </Row>
+        <Row gutter={16}>
+          <Col xs={24} sm={16}>
+            <Form.TextArea
+              label={t('用户可选分组')}
+              placeholder={t('为一个 JSON 文本,键为分组名称,值为分组描述')}
+              extraText={t(
+                '用户新建令牌时可选的分组,格式为 JSON 字符串,例如:{"vip": "VIP 用户", "test": "测试"},表示用户可以选择 vip 分组和 test 分组',
+              )}
+              field={'UserUsableGroups'}
+              autosize={{ minRows: 6, maxRows: 12 }}
+              trigger='blur'
+              stopValidateWithError
+              rules={[
+                {
+                  validator: (rule, value) => verifyJSON(value),
+                  message: t('不是合法的 JSON 字符串'),
+                },
+              ]}
+              onChange={(value) =>
+                setInputs({ ...inputs, UserUsableGroups: value })
+              }
+            />
+          </Col>
+        </Row>
+        <Row gutter={16}>
+          <Col xs={24} sm={16}>
+            <Form.TextArea
+              label={t('分组特殊倍率')}
+              placeholder={t('为一个 JSON 文本')}
+              extraText={t(
+                '键为分组名称,值为另一个 JSON 对象,键为分组名称,值为该分组的用户的特殊分组倍率,例如:{"vip": {"default": 0.5, "test": 1}},表示 vip 分组的用户在使用default分组的令牌时倍率为0.5,使用test分组时倍率为1',
+              )}
+              field={'GroupGroupRatio'}
+              autosize={{ minRows: 6, maxRows: 12 }}
+              trigger='blur'
+              stopValidateWithError
+              rules={[
+                {
+                  validator: (rule, value) => verifyJSON(value),
+                  message: t('不是合法的 JSON 字符串'),
+                },
+              ]}
+              onChange={(value) =>
+                setInputs({ ...inputs, GroupGroupRatio: value })
+              }
+            />
+          </Col>
+        </Row>
+        <Row gutter={16}>
+          <Col xs={24} sm={16}>
+            <Form.TextArea
+              label={t('自动分组auto,从第一个开始选择')}
+              placeholder={t('为一个 JSON 文本')}
+              field={'AutoGroups'}
+              autosize={{ minRows: 6, maxRows: 12 }}
+              trigger='blur'
+              stopValidateWithError
+              rules={[
+                {
+                  validator: (rule, value) => {
+                    if (!value || value.trim() === '') {
+                      return true; // Allow empty values
+                    }
 
-                        // Check if it's an array
-                        if (!Array.isArray(parsed)) {
-                          return false;
-                        }
+                    // First check if it's valid JSON
+                    try {
+                      const parsed = JSON.parse(value);
 
-                        // Check if every element is a string
-                        return parsed.every(item => typeof item === 'string');
-                      } catch (error) {
+                      // Check if it's an array
+                      if (!Array.isArray(parsed)) {
                         return false;
                       }
-                    },
-                    message: t('必须是有效的 JSON 字符串数组,例如:["g1","g2"]'),
+
+                      // Check if every element is a string
+                      return parsed.every(item => typeof item === 'string');
+                    } catch (error) {
+                      return false;
+                    }
                   },
-                ]}
-                onChange={(value) =>
-                  setInputs({ ...inputs, AutoGroups: value })
-                }
-              />
-            </Col>
-          </Row>
-          <Row gutter={16}>
-            <Col span={16}>
-              <Form.Switch
-                label={t(
-                  '创建令牌默认选择auto分组,初始令牌也将设为auto(否则留空,为用户默认分组)',
-                )}
-                field={'DefaultUseAutoGroup'}
-                onChange={(value) =>
-                  setInputs({ ...inputs, DefaultUseAutoGroup: value })
-                }
-              />
-            </Col>
-          </Row>
-        </Form.Section>
+                  message: t('必须是有效的 JSON 字符串数组,例如:["g1","g2"]'),
+                },
+              ]}
+              onChange={(value) =>
+                setInputs({ ...inputs, AutoGroups: value })
+              }
+            />
+          </Col>
+        </Row>
+        <Row gutter={16}>
+          <Col span={16}>
+            <Form.Switch
+              label={t(
+                '创建令牌默认选择auto分组,初始令牌也将设为auto(否则留空,为用户默认分组)',
+              )}
+              field={'DefaultUseAutoGroup'}
+              onChange={(value) =>
+                setInputs({ ...inputs, DefaultUseAutoGroup: value })
+              }
+            />
+          </Col>
+        </Row>
       </Form>
       <Button onClick={onSubmit}>{t('保存分组倍率设置')}</Button>
     </Spin>

+ 99 - 101
web/src/pages/Setting/Ratio/ModelRatioSettings.js

@@ -118,107 +118,105 @@ export default function ModelRatioSettings(props) {
         getFormApi={(formAPI) => (refForm.current = formAPI)}
         style={{ marginBottom: 15 }}
       >
-        <Form.Section>
-          <Row gutter={16}>
-            <Col xs={24} sm={16}>
-              <Form.TextArea
-                label={t('模型固定价格')}
-                extraText={t('一次调用消耗多少刀,优先级大于模型倍率')}
-                placeholder={t(
-                  '为一个 JSON 文本,键为模型名称,值为一次调用消耗多少刀,比如 "gpt-4-gizmo-*": 0.1,一次消耗0.1刀',
-                )}
-                field={'ModelPrice'}
-                autosize={{ minRows: 6, maxRows: 12 }}
-                trigger='blur'
-                stopValidateWithError
-                rules={[
-                  {
-                    validator: (rule, value) => verifyJSON(value),
-                    message: '不是合法的 JSON 字符串',
-                  },
-                ]}
-                onChange={(value) =>
-                  setInputs({ ...inputs, ModelPrice: value })
-                }
-              />
-            </Col>
-          </Row>
-          <Row gutter={16}>
-            <Col xs={24} sm={16}>
-              <Form.TextArea
-                label={t('模型倍率')}
-                placeholder={t('为一个 JSON 文本,键为模型名称,值为倍率')}
-                field={'ModelRatio'}
-                autosize={{ minRows: 6, maxRows: 12 }}
-                trigger='blur'
-                stopValidateWithError
-                rules={[
-                  {
-                    validator: (rule, value) => verifyJSON(value),
-                    message: '不是合法的 JSON 字符串',
-                  },
-                ]}
-                onChange={(value) =>
-                  setInputs({ ...inputs, ModelRatio: value })
-                }
-              />
-            </Col>
-          </Row>
-          <Row gutter={16}>
-            <Col xs={24} sm={16}>
-              <Form.TextArea
-                label={t('提示缓存倍率')}
-                placeholder={t('为一个 JSON 文本,键为模型名称,值为倍率')}
-                field={'CacheRatio'}
-                autosize={{ minRows: 6, maxRows: 12 }}
-                trigger='blur'
-                stopValidateWithError
-                rules={[
-                  {
-                    validator: (rule, value) => verifyJSON(value),
-                    message: '不是合法的 JSON 字符串',
-                  },
-                ]}
-                onChange={(value) =>
-                  setInputs({ ...inputs, CacheRatio: value })
-                }
-              />
-            </Col>
-          </Row>
-          <Row gutter={16}>
-            <Col xs={24} sm={16}>
-              <Form.TextArea
-                label={t('模型补全倍率(仅对自定义模型有效)')}
-                extraText={t('仅对自定义模型有效')}
-                placeholder={t('为一个 JSON 文本,键为模型名称,值为倍率')}
-                field={'CompletionRatio'}
-                autosize={{ minRows: 6, maxRows: 12 }}
-                trigger='blur'
-                stopValidateWithError
-                rules={[
-                  {
-                    validator: (rule, value) => verifyJSON(value),
-                    message: '不是合法的 JSON 字符串',
-                  },
-                ]}
-                onChange={(value) =>
-                  setInputs({ ...inputs, CompletionRatio: value })
-                }
-              />
-            </Col>
-          </Row>
-          <Row gutter={16}>
-            <Col span={16}>
-              <Form.Switch
-                label={t('暴露倍率接口')}
-                field={'ExposeRatioEnabled'}
-                onChange={(value) =>
-                  setInputs({ ...inputs, ExposeRatioEnabled: value })
-                }
-              />
-            </Col>
-          </Row>
-        </Form.Section>
+        <Row gutter={16}>
+          <Col xs={24} sm={16}>
+            <Form.TextArea
+              label={t('模型固定价格')}
+              extraText={t('一次调用消耗多少刀,优先级大于模型倍率')}
+              placeholder={t(
+                '为一个 JSON 文本,键为模型名称,值为一次调用消耗多少刀,比如 "gpt-4-gizmo-*": 0.1,一次消耗0.1刀',
+              )}
+              field={'ModelPrice'}
+              autosize={{ minRows: 6, maxRows: 12 }}
+              trigger='blur'
+              stopValidateWithError
+              rules={[
+                {
+                  validator: (rule, value) => verifyJSON(value),
+                  message: '不是合法的 JSON 字符串',
+                },
+              ]}
+              onChange={(value) =>
+                setInputs({ ...inputs, ModelPrice: value })
+              }
+            />
+          </Col>
+        </Row>
+        <Row gutter={16}>
+          <Col xs={24} sm={16}>
+            <Form.TextArea
+              label={t('模型倍率')}
+              placeholder={t('为一个 JSON 文本,键为模型名称,值为倍率')}
+              field={'ModelRatio'}
+              autosize={{ minRows: 6, maxRows: 12 }}
+              trigger='blur'
+              stopValidateWithError
+              rules={[
+                {
+                  validator: (rule, value) => verifyJSON(value),
+                  message: '不是合法的 JSON 字符串',
+                },
+              ]}
+              onChange={(value) =>
+                setInputs({ ...inputs, ModelRatio: value })
+              }
+            />
+          </Col>
+        </Row>
+        <Row gutter={16}>
+          <Col xs={24} sm={16}>
+            <Form.TextArea
+              label={t('提示缓存倍率')}
+              placeholder={t('为一个 JSON 文本,键为模型名称,值为倍率')}
+              field={'CacheRatio'}
+              autosize={{ minRows: 6, maxRows: 12 }}
+              trigger='blur'
+              stopValidateWithError
+              rules={[
+                {
+                  validator: (rule, value) => verifyJSON(value),
+                  message: '不是合法的 JSON 字符串',
+                },
+              ]}
+              onChange={(value) =>
+                setInputs({ ...inputs, CacheRatio: value })
+              }
+            />
+          </Col>
+        </Row>
+        <Row gutter={16}>
+          <Col xs={24} sm={16}>
+            <Form.TextArea
+              label={t('模型补全倍率(仅对自定义模型有效)')}
+              extraText={t('仅对自定义模型有效')}
+              placeholder={t('为一个 JSON 文本,键为模型名称,值为倍率')}
+              field={'CompletionRatio'}
+              autosize={{ minRows: 6, maxRows: 12 }}
+              trigger='blur'
+              stopValidateWithError
+              rules={[
+                {
+                  validator: (rule, value) => verifyJSON(value),
+                  message: '不是合法的 JSON 字符串',
+                },
+              ]}
+              onChange={(value) =>
+                setInputs({ ...inputs, CompletionRatio: value })
+              }
+            />
+          </Col>
+        </Row>
+        <Row gutter={16}>
+          <Col span={16}>
+            <Form.Switch
+              label={t('暴露倍率接口')}
+              field={'ExposeRatioEnabled'}
+              onChange={(value) =>
+                setInputs({ ...inputs, ExposeRatioEnabled: value })
+              }
+            />
+          </Col>
+        </Row>
       </Form>
       <Space>
         <Button onClick={onSubmit}>{t('保存模型倍率设置')}</Button>