Просмотр исходного кода

feat: able to set top up link now

JustSong 2 лет назад
Родитель
Сommit
f97c2b4c22
6 измененных файлов с 53 добавлено и 13 удалено
  1. 12 8
      README.md
  2. 1 0
      common/constants.go
  3. 1 0
      controller/misc.go
  4. 3 0
      model/option.go
  5. 23 5
      web/src/components/SystemSetting.js
  6. 13 0
      web/src/components/TokensTable.js

+ 12 - 8
README.md

@@ -52,14 +52,18 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用
    + [x] 自定义渠道
 2. 支持通过负载均衡的方式访问多个渠道。
 3. 支持单个访问渠道设置多个 API Key,利用起来你的多个 API Key。
-4. 支持设置令牌的过期时间和使用次数。
-5. 支持 HTTP SSE。
-6. 多种用户登录注册方式:
-   + 邮箱登录注册以及通过邮箱进行密码重置。
-   + [GitHub 开放授权](https://github.com/settings/applications/new)。
-   + 微信公众号授权(需要额外部署 [WeChat Server](https://github.com/songquanpeng/wechat-server))。
-7. 支持用户管理。
-8. 未来其他大模型开放 API 后,将第一时间支持,并将其封装成同样的 API 访问方式。
+4. 支持 HTTP SSE,可以通过流式传输实现打字机效果。
+5. 支持设置令牌的过期时间和使用次数。
+6. 支持批量生成和导出兑换码,可使用兑换码为令牌进行充值。
+7. 支持为新用户设置初始配额。
+8. 支持发布公告,在线修改关于页面,设置充值链接,自定义页脚。
+9. 支持通过系统访问令牌访问管理 API。
+10. 多种用户登录注册方式:
+    + 邮箱登录注册以及通过邮箱进行密码重置。
+    + [GitHub 开放授权](https://github.com/settings/applications/new)。
+    + 微信公众号授权(需要额外部署 [WeChat Server](https://github.com/songquanpeng/wechat-server))。
+11. 支持用户管理。
+12. 未来其他大模型开放 API 后,将第一时间支持,并将其封装成同样的 API 访问方式。
 
 ## 部署
 ### 基于 Docker 进行部署

+ 1 - 0
common/constants.go

@@ -11,6 +11,7 @@ var Version = "v0.0.0"            // this hard coding will be replaced automatic
 var SystemName = "One API"
 var ServerAddress = "http://localhost:3000"
 var Footer = ""
+var TopUpLink = ""
 
 var UsingSQLite = false
 

+ 1 - 0
controller/misc.go

@@ -26,6 +26,7 @@ func GetStatus(c *gin.Context) {
 			"server_address":     common.ServerAddress,
 			"turnstile_check":    common.TurnstileCheckEnabled,
 			"turnstile_site_key": common.TurnstileSiteKey,
+			"top_up_link":        common.TopUpLink,
 		},
 	})
 	return

+ 3 - 0
model/option.go

@@ -47,6 +47,7 @@ func InitOptionMap() {
 	common.OptionMap["TurnstileSiteKey"] = ""
 	common.OptionMap["TurnstileSecretKey"] = ""
 	common.OptionMap["QuotaForNewUser"] = strconv.Itoa(common.QuotaForNewUser)
+	common.OptionMap["TopUpLink"] = common.TopUpLink
 	common.OptionMapRWMutex.Unlock()
 	options, _ := AllOption()
 	for _, option := range options {
@@ -134,5 +135,7 @@ func updateOptionMap(key string, value string) {
 		common.TurnstileSecretKey = value
 	case "QuotaForNewUser":
 		common.QuotaForNewUser, _ = strconv.Atoi(value)
+	case "TopUpLink":
+		common.TopUpLink = value
 	}
 }

+ 23 - 5
web/src/components/SystemSetting.js

@@ -25,6 +25,7 @@ const SystemSetting = () => {
     TurnstileSecretKey: '',
     RegisterEnabled: '',
     QuotaForNewUser: 0,
+    TopUpLink: ''
   });
   let originInputs = {};
   let [loading, setLoading] = useState(false);
@@ -65,7 +66,7 @@ const SystemSetting = () => {
     }
     const res = await API.put('/api/option', {
       key,
-      value,
+      value
     });
     const { success, message } = res.data;
     if (success) {
@@ -88,7 +89,8 @@ const SystemSetting = () => {
       name === 'WeChatAccountQRCodeImageURL' ||
       name === 'TurnstileSiteKey' ||
       name === 'TurnstileSecretKey' ||
-      name === 'QuotaForNewUser'
+      name === 'QuotaForNewUser' ||
+      name === 'TopUpLink'
     ) {
       setInputs((inputs) => ({ ...inputs, [name]: value }));
     } else {
@@ -101,6 +103,15 @@ const SystemSetting = () => {
     await updateOption('ServerAddress', ServerAddress);
   };
 
+  const submitOperationConfig = async () => {
+    if (originInputs['QuotaForNewUser'] !== inputs.QuotaForNewUser) {
+      await updateOption('QuotaForNewUser', inputs.QuotaForNewUser);
+    }
+    if (originInputs['TopUpLink'] !== inputs.TopUpLink) {
+      await updateOption('TopUpLink', inputs.TopUpLink);
+    }
+  }
+
   const submitSMTP = async () => {
     if (originInputs['SMTPServer'] !== inputs.SMTPServer) {
       await updateOption('SMTPServer', inputs.SMTPServer);
@@ -244,10 +255,17 @@ const SystemSetting = () => {
               min='0'
               placeholder='例如:100'
             />
+            <Form.Input
+              label='充值链接'
+              name='TopUpLink'
+              onChange={handleInputChange}
+              autoComplete='off'
+              value={inputs.TopUpLink}
+              type='link'
+              placeholder='例如发卡网站的购买链接'
+            />
           </Form.Group>
-          <Form.Button onClick={()=>{
-            updateOption('QuotaForNewUser', inputs.QuotaForNewUser).then();
-          }}>保存运营设置</Form.Button>
+          <Form.Button onClick={submitOperationConfig}>保存运营设置</Form.Button>
           <Divider />
           <Header as='h3'>
             配置 SMTP

+ 13 - 0
web/src/components/TokensTable.js

@@ -37,6 +37,7 @@ const TokensTable = () => {
   const [showTopUpModal, setShowTopUpModal] = useState(false);
   const [targetTokenIdx, setTargetTokenIdx] = useState(0);
   const [redemptionCode, setRedemptionCode] = useState('');
+  const [topUpLink, setTopUpLink] = useState('');
 
   const loadTokens = async (startIdx) => {
     const res = await API.get(`/api/token/?p=${startIdx}`);
@@ -71,6 +72,13 @@ const TokensTable = () => {
       .catch((reason) => {
         showError(reason);
       });
+    let status = localStorage.getItem('status');
+    if (status) {
+      status = JSON.parse(status);
+      if (status.top_up_link) {
+        setTopUpLink(status.top_up_link);
+      }
+    }
   }, []);
 
   const manageToken = async (id, action, idx) => {
@@ -342,6 +350,11 @@ const TokensTable = () => {
         <Modal.Content>
           <Modal.Description>
             {/*<Image src={status.wechat_qrcode} fluid />*/}
+            {
+              topUpLink && <p>
+                  <a target='_blank' href={topUpLink}>点击此处获取兑换码</a>
+              </p>
+            }
             <Form size='large'>
               <Form.Input
                 fluid