index.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. Copyright (C) 2025 QuantumNous
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. For commercial licensing, please contact support@quantumnous.com
  14. */
  15. import React, { useEffect, useState } from 'react';
  16. import { Layout, TabPane, Tabs } from '@douyinfe/semi-ui';
  17. import { useNavigate, useLocation } from 'react-router-dom';
  18. import { useTranslation } from 'react-i18next';
  19. import {
  20. Settings,
  21. Calculator,
  22. Gauge,
  23. Shapes,
  24. Cog,
  25. MoreHorizontal,
  26. LayoutDashboard,
  27. MessageSquare,
  28. Palette,
  29. CreditCard
  30. } from 'lucide-react';
  31. import SystemSetting from '../../components/settings/SystemSetting.js';
  32. import { isRoot } from '../../helpers';
  33. import OtherSetting from '../../components/settings/OtherSetting';
  34. import OperationSetting from '../../components/settings/OperationSetting.js';
  35. import RateLimitSetting from '../../components/settings/RateLimitSetting.js';
  36. import ModelSetting from '../../components/settings/ModelSetting.js';
  37. import DashboardSetting from '../../components/settings/DashboardSetting.js';
  38. import RatioSetting from '../../components/settings/RatioSetting.js';
  39. import ChatsSetting from '../../components/settings/ChatsSetting.js';
  40. import DrawingSetting from '../../components/settings/DrawingSetting.js';
  41. import PaymentSetting from '../../components/settings/PaymentSetting.js';
  42. const Setting = () => {
  43. const { t } = useTranslation();
  44. const navigate = useNavigate();
  45. const location = useLocation();
  46. const [tabActiveKey, setTabActiveKey] = useState('1');
  47. let panes = [];
  48. if (isRoot()) {
  49. panes.push({
  50. tab: (
  51. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  52. <Settings size={18} />
  53. {t('运营设置')}
  54. </span>
  55. ),
  56. content: <OperationSetting />,
  57. itemKey: 'operation',
  58. });
  59. panes.push({
  60. tab: (
  61. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  62. <LayoutDashboard size={18} />
  63. {t('仪表盘设置')}
  64. </span>
  65. ),
  66. content: <DashboardSetting />,
  67. itemKey: 'dashboard',
  68. });
  69. panes.push({
  70. tab: (
  71. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  72. <MessageSquare size={18} />
  73. {t('聊天设置')}
  74. </span>
  75. ),
  76. content: <ChatsSetting />,
  77. itemKey: 'chats',
  78. });
  79. panes.push({
  80. tab: (
  81. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  82. <Palette size={18} />
  83. {t('绘图设置')}
  84. </span>
  85. ),
  86. content: <DrawingSetting />,
  87. itemKey: 'drawing',
  88. });
  89. panes.push({
  90. tab: (
  91. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  92. <CreditCard size={18} />
  93. {t('支付设置')}
  94. </span>
  95. ),
  96. content: <PaymentSetting />,
  97. itemKey: 'payment',
  98. });
  99. panes.push({
  100. tab: (
  101. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  102. <Calculator size={18} />
  103. {t('倍率设置')}
  104. </span>
  105. ),
  106. content: <RatioSetting />,
  107. itemKey: 'ratio',
  108. });
  109. panes.push({
  110. tab: (
  111. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  112. <Gauge size={18} />
  113. {t('速率限制设置')}
  114. </span>
  115. ),
  116. content: <RateLimitSetting />,
  117. itemKey: 'ratelimit',
  118. });
  119. panes.push({
  120. tab: (
  121. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  122. <Shapes size={18} />
  123. {t('模型相关设置')}
  124. </span>
  125. ),
  126. content: <ModelSetting />,
  127. itemKey: 'models',
  128. });
  129. panes.push({
  130. tab: (
  131. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  132. <Cog size={18} />
  133. {t('系统设置')}
  134. </span>
  135. ),
  136. content: <SystemSetting />,
  137. itemKey: 'system',
  138. });
  139. panes.push({
  140. tab: (
  141. <span style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
  142. <MoreHorizontal size={18} />
  143. {t('其他设置')}
  144. </span>
  145. ),
  146. content: <OtherSetting />,
  147. itemKey: 'other',
  148. });
  149. }
  150. const onChangeTab = (key) => {
  151. setTabActiveKey(key);
  152. navigate(`?tab=${key}`);
  153. };
  154. useEffect(() => {
  155. const searchParams = new URLSearchParams(window.location.search);
  156. const tab = searchParams.get('tab');
  157. if (tab) {
  158. setTabActiveKey(tab);
  159. } else {
  160. onChangeTab('operation');
  161. }
  162. }, [location.search]);
  163. return (
  164. <div className="mt-[60px] px-2">
  165. <Layout>
  166. <Layout.Content>
  167. <Tabs
  168. type='card'
  169. collapsible
  170. activeKey={tabActiveKey}
  171. onChange={(key) => onChangeTab(key)}
  172. >
  173. {panes.map((pane) => (
  174. <TabPane itemKey={pane.itemKey} tab={pane.tab} key={pane.itemKey}>
  175. {tabActiveKey === pane.itemKey && pane.content}
  176. </TabPane>
  177. ))}
  178. </Tabs>
  179. </Layout.Content>
  180. </Layout>
  181. </div>
  182. );
  183. };
  184. export default Setting;