diff --git a/controller/misc.go b/controller/misc.go index ac094b2..71c7419 100644 --- a/controller/misc.go +++ b/controller/misc.go @@ -120,18 +120,28 @@ func SendEmailVerification(c *gin.Context) { }) 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 - for _, domain := range common.EmailDomainWhitelist { - if strings.HasSuffix(email, "@"+domain) { + for _, domain := range config.EmailDomainWhitelist { + if domainPart == domain { allowed = true 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{ "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 } diff --git a/relay/channel/claude/relay-claude.go b/relay/channel/claude/relay-claude.go index 4de8dc0..2b5d3d2 100644 --- a/relay/channel/claude/relay-claude.go +++ b/relay/channel/claude/relay-claude.go @@ -34,6 +34,7 @@ func requestOpenAI2ClaudeComplete(textRequest dto.GeneralOpenAIRequest) *ClaudeR StopSequences: nil, Temperature: textRequest.Temperature, TopP: textRequest.TopP, + TopK: textRequest.TopK, Stream: textRequest.Stream, } if claudeRequest.MaxTokensToSample == 0 { @@ -63,6 +64,7 @@ func requestOpenAI2ClaudeMessage(textRequest dto.GeneralOpenAIRequest) (*ClaudeR StopSequences: nil, Temperature: textRequest.Temperature, TopP: textRequest.TopP, + TopK: textRequest.TopK, Stream: textRequest.Stream, } if claudeRequest.MaxTokens == 0 { diff --git a/web/.prettierrc.mjs b/web/.prettierrc.mjs new file mode 100644 index 0000000..ecae84d --- /dev/null +++ b/web/.prettierrc.mjs @@ -0,0 +1 @@ +module.exports = require("@so1ve/prettier-config"); diff --git a/web/.prettierrc.mjs b/web/.prettierrc.mjs deleted file mode 100644 index 7890fda..0000000 --- a/web/.prettierrc.mjs +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("@so1ve/prettier-config"); \ No newline at end of file diff --git a/web/src/helpers/render.js b/web/src/helpers/render.js index a71215e..cd1f8d9 100644 --- a/web/src/helpers/render.js +++ b/web/src/helpers/render.js @@ -8,39 +8,37 @@ export function renderText(text, limit) { 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) { if (group === '') { - return default; + return default; } - let groups = group.split(','); - groups.sort(); + + const tagColors = { + 'vip': 'yellow', + 'pro': 'yellow', + 'svip': 'red', + 'premium': 'red' + }; + + const groups = group.split(',').sort(); + return ( - <> - {groups.map((group) => { - if (group === 'vip' || group === 'pro') { - return ( - - {group} - - ); - } else if (group === 'svip' || group === 'premium') { - return ( - - {group} - - ); - } - if (group === 'default') { - return {group}; - } else { - return ( - - {group} - - ); - } - })} - + + {groups.map((group) => ( + + {group} + + ))} + ); } diff --git a/web/src/pages/Setting/index.js b/web/src/pages/Setting/index.js index fe38ea7..71e3cf8 100644 --- a/web/src/pages/Setting/index.js +++ b/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 { isRoot } from '../../helpers'; import OtherSetting from '../../components/OtherSetting'; import PersonalSetting from '../../components/PersonalSetting'; import OperationSetting from '../../components/OperationSetting'; -import { Layout, TabPane, Tabs } from '@douyinfe/semi-ui'; - const Setting = () => { + const navigate = useNavigate(); + const location = useLocation(); + const [tabActiveKey, setTabActiveKey] = useState('1'); let panes = [ { tab: '个人设置', content: , - itemKey: '1', + itemKey: 'personal', }, ]; @@ -19,28 +23,44 @@ const Setting = () => { panes.push({ tab: '运营设置', content: , - itemKey: '2', + itemKey: 'operation', }); panes.push({ tab: '系统设置', content: , - itemKey: '3', + itemKey: 'system', }); panes.push({ tab: '其他设置', content: , - 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 (
- + onChangeTab(key)} + > {panes.map((pane) => ( - {pane.content} + {tabActiveKey === pane.itemKey && pane.content} ))}