Merge remote-tracking branch 'origin/main'

This commit is contained in:
CaIon
2024-04-03 23:51:32 +08:00
6 changed files with 75 additions and 45 deletions

View File

@@ -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 { for _, domain := range config.EmailDomainWhitelist {
if strings.HasSuffix(email, "@"+domain) { 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
} }

View File

@@ -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
web/.prettierrc.mjs Normal file
View File

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

View File

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

View File

@@ -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 (
<> <span key={group}>
{groups.map((group) => { {groups.map((group) => (
if (group === 'vip' || group === 'pro') { <Tag
return ( size='large'
<Tag size='large' color='yellow'> color={tagColors[group] || stringToColor(group)}
key={group}
>
{group} {group}
</Tag> </Tag>
); ))}
} else if (group === 'svip' || group === 'premium') { </span>
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>
);
}
})}
</>
); );
} }

View File

@@ -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>