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

Merge remote-tracking branch 'origin/main'

CaIon 1 год назад
Родитель
Сommit
3d0f77ffb6

+ 15 - 5
controller/misc.go

@@ -120,18 +120,28 @@ func SendEmailVerification(c *gin.Context) {
 		})
 		})
 		return
 		return
 	}
 	}
-	if common.EmailDomainRestrictionEnabled {
+	if config.EmailDomainRestrictionEnabled {
+		parts := strings.Split(email, "@")
+		localPart := parts[0]
+		domainPart := parts[1]
+
+		containsSpecialSymbols := strings.Contains(localPart, "+") || strings.Count(localPart, ".") > 1
 		allowed := false
 		allowed := false
-		for _, domain := range common.EmailDomainWhitelist {
-			if strings.HasSuffix(email, "@"+domain) {
+		for _, domain := range config.EmailDomainWhitelist {
+			if domainPart == domain {
 				allowed = true
 				allowed = true
 				break
 				break
 			}
 			}
 		}
 		}
-		if !allowed {
+		if allowed && !containsSpecialSymbols {
+			c.JSON(http.StatusOK, gin.H{
+				"success": true,
+				"message": "Your email address is allowed.",
+			})
+		} else {
 			c.JSON(http.StatusOK, gin.H{
 			c.JSON(http.StatusOK, gin.H{
 				"success": false,
 				"success": false,
-				"message": "管理员启用了邮箱域名白名单,您的邮箱地址的域名不在白名单中",
+				"message": "The administrator has enabled the email domain name whitelist, and your email address is not allowed due to special symbols or it's not in the whitelist.",
 			})
 			})
 			return
 			return
 		}
 		}

+ 2 - 0
relay/channel/claude/relay-claude.go

@@ -34,6 +34,7 @@ func requestOpenAI2ClaudeComplete(textRequest dto.GeneralOpenAIRequest) *ClaudeR
 		StopSequences:     nil,
 		StopSequences:     nil,
 		Temperature:       textRequest.Temperature,
 		Temperature:       textRequest.Temperature,
 		TopP:              textRequest.TopP,
 		TopP:              textRequest.TopP,
+		TopK:              textRequest.TopK,
 		Stream:            textRequest.Stream,
 		Stream:            textRequest.Stream,
 	}
 	}
 	if claudeRequest.MaxTokensToSample == 0 {
 	if claudeRequest.MaxTokensToSample == 0 {
@@ -63,6 +64,7 @@ func requestOpenAI2ClaudeMessage(textRequest dto.GeneralOpenAIRequest) (*ClaudeR
 		StopSequences: nil,
 		StopSequences: nil,
 		Temperature:   textRequest.Temperature,
 		Temperature:   textRequest.Temperature,
 		TopP:          textRequest.TopP,
 		TopP:          textRequest.TopP,
+		TopK:          textRequest.TopK,
 		Stream:        textRequest.Stream,
 		Stream:        textRequest.Stream,
 	}
 	}
 	if claudeRequest.MaxTokens == 0 {
 	if claudeRequest.MaxTokens == 0 {

+ 1 - 0
web/.prettierrc.mjs

@@ -0,0 +1 @@
+module.exports = require("@so1ve/prettier-config");

+ 0 - 1
web/.prettierrc.mjs

@@ -1 +0,0 @@
-module.exports = require("@so1ve/prettier-config");

+ 27 - 29
web/src/helpers/render.js

@@ -8,39 +8,37 @@ export function renderText(text, limit) {
   return text;
   return text;
 }
 }
 
 
+/**
+ * Render group tags based on the input group string
+ * @param {string} group - The input group string
+ * @returns {JSX.Element} - The rendered group tags
+ */
 export function renderGroup(group) {
 export function renderGroup(group) {
   if (group === '') {
   if (group === '') {
-    return <Tag size='large'>default</Tag>;
+    return <Tag size='large' key='default'>default</Tag>;
   }
   }
-  let groups = group.split(',');
-  groups.sort();
+
+  const tagColors = {
+    'vip': 'yellow',
+    'pro': 'yellow',
+    'svip': 'red',
+    'premium': 'red'
+  };
+
+  const groups = group.split(',').sort();
+
   return (
   return (
-    <>
-      {groups.map((group) => {
-        if (group === 'vip' || group === 'pro') {
-          return (
-            <Tag size='large' color='yellow'>
-              {group}
-            </Tag>
-          );
-        } else if (group === 'svip' || group === 'premium') {
-          return (
-            <Tag size='large' color='red'>
-              {group}
-            </Tag>
-          );
-        }
-        if (group === 'default') {
-          return <Tag size='large'>{group}</Tag>;
-        } else {
-          return (
-            <Tag size='large' color={stringToColor(group)}>
-              {group}
-            </Tag>
-          );
-        }
-      })}
-    </>
+    <span key={group}>
+      {groups.map((group) => (
+        <Tag
+          size='large'
+          color={tagColors[group] || stringToColor(group)}
+          key={group}
+        >
+          {group}
+        </Tag>
+      ))}
+    </span>
   );
   );
 }
 }
 
 

+ 30 - 10
web/src/pages/Setting/index.js

@@ -1,17 +1,21 @@
-import React from 'react';
+import React, { useEffect, useState } from 'react';
+import { Layout, TabPane, Tabs } from '@douyinfe/semi-ui';
+import { useNavigate, useLocation } from 'react-router-dom';
+
 import SystemSetting from '../../components/SystemSetting';
 import SystemSetting from '../../components/SystemSetting';
 import { isRoot } from '../../helpers';
 import { isRoot } from '../../helpers';
 import OtherSetting from '../../components/OtherSetting';
 import OtherSetting from '../../components/OtherSetting';
 import PersonalSetting from '../../components/PersonalSetting';
 import PersonalSetting from '../../components/PersonalSetting';
 import OperationSetting from '../../components/OperationSetting';
 import OperationSetting from '../../components/OperationSetting';
-import { Layout, TabPane, Tabs } from '@douyinfe/semi-ui';
-
 const Setting = () => {
 const Setting = () => {
+  const navigate = useNavigate();
+  const location = useLocation();
+  const [tabActiveKey, setTabActiveKey] = useState('1');
   let panes = [
   let panes = [
     {
     {
       tab: '个人设置',
       tab: '个人设置',
       content: <PersonalSetting />,
       content: <PersonalSetting />,
-      itemKey: '1',
+      itemKey: 'personal',
     },
     },
   ];
   ];
 
 
@@ -19,28 +23,44 @@ const Setting = () => {
     panes.push({
     panes.push({
       tab: '运营设置',
       tab: '运营设置',
       content: <OperationSetting />,
       content: <OperationSetting />,
-      itemKey: '2',
+      itemKey: 'operation',
     });
     });
     panes.push({
     panes.push({
       tab: '系统设置',
       tab: '系统设置',
       content: <SystemSetting />,
       content: <SystemSetting />,
-      itemKey: '3',
+      itemKey: 'system',
     });
     });
     panes.push({
     panes.push({
       tab: '其他设置',
       tab: '其他设置',
       content: <OtherSetting />,
       content: <OtherSetting />,
-      itemKey: '4',
+      itemKey: 'other',
     });
     });
   }
   }
-
+  const onChangeTab = (key) => {
+    setTabActiveKey(key);
+    navigate(`?tab=${key}`);
+  };
+  useEffect(() => {
+    const searchParams = new URLSearchParams(window.location.search);
+    const tab = searchParams.get('tab');
+    if (tab) {
+      setTabActiveKey(tab);
+    } else {
+      onChangeTab('personal');
+    }
+  }, [location.search]);
   return (
   return (
     <div>
     <div>
       <Layout>
       <Layout>
         <Layout.Content>
         <Layout.Content>
-          <Tabs type='line' defaultActiveKey='1'>
+          <Tabs
+            type='line'
+            activeKey={tabActiveKey}
+            onChange={(key) => onChangeTab(key)}
+          >
             {panes.map((pane) => (
             {panes.map((pane) => (
               <TabPane itemKey={pane.itemKey} tab={pane.tab} key={pane.itemKey}>
               <TabPane itemKey={pane.itemKey} tab={pane.tab} key={pane.itemKey}>
-                {pane.content}
+                {tabActiveKey === pane.itemKey && pane.content}
               </TabPane>
               </TabPane>
             ))}
             ))}
           </Tabs>
           </Tabs>