@@ -12,10 +19,10 @@ const TextInput = ({ label, name, value, onChange, placeholder, type = 'text' })
placeholder={placeholder}
onChange={(value) => onChange(value)}
value={value}
- autoComplete="new-password"
+ autoComplete='new-password'
/>
>
);
-}
+};
-export default TextInput;
\ No newline at end of file
+export default TextInput;
diff --git a/web/src/components/custom/TextNumberInput.js b/web/src/components/custom/TextNumberInput.js
index e25c7725..36e0cac0 100644
--- a/web/src/components/custom/TextNumberInput.js
+++ b/web/src/components/custom/TextNumberInput.js
@@ -12,10 +12,10 @@ const TextNumberInput = ({ label, name, value, onChange, placeholder }) => {
placeholder={placeholder}
onChange={(value) => onChange(value)}
value={value}
- autoComplete="new-password"
+ autoComplete='new-password'
/>
>
);
-}
+};
-export default TextNumberInput;
\ No newline at end of file
+export default TextNumberInput;
diff --git a/web/src/components/fetchTokenKeys.js b/web/src/components/fetchTokenKeys.js
index 46a70f15..e9cec001 100644
--- a/web/src/components/fetchTokenKeys.js
+++ b/web/src/components/fetchTokenKeys.js
@@ -13,7 +13,7 @@ async function fetchTokenKeys() {
throw new Error('Failed to fetch token keys');
}
} catch (error) {
- console.error("Error fetching token keys:", error);
+ console.error('Error fetching token keys:', error);
return [];
}
}
@@ -27,7 +27,7 @@ function getServerAddress() {
status = JSON.parse(status);
serverAddress = status.server_address || '';
} catch (error) {
- console.error("Failed to parse status from localStorage:", error);
+ console.error('Failed to parse status from localStorage:', error);
}
}
@@ -65,4 +65,4 @@ export function useTokenKeys(id) {
}, []);
return { keys, serverAddress, isLoading };
-}
\ No newline at end of file
+}
diff --git a/web/src/components/utils.js b/web/src/components/utils.js
index df009bb0..93a5fb85 100644
--- a/web/src/components/utils.js
+++ b/web/src/components/utils.js
@@ -20,13 +20,12 @@ export async function onOIDCClicked(auth_url, client_id, openInNewTab = false) {
const state = await getOAuthState();
if (!state) return;
const redirect_uri = `${window.location.origin}/oauth/oidc`;
- const response_type = "code";
- const scope = "openid profile email";
+ const response_type = 'code';
+ const scope = 'openid profile email';
const url = `${auth_url}?client_id=${client_id}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}&state=${state}`;
if (openInNewTab) {
window.open(url);
- } else
- {
+ } else {
window.location.href = url;
}
}
diff --git a/web/src/constants/channel.constants.js b/web/src/constants/channel.constants.js
index 583995e7..fa59bcce 100644
--- a/web/src/constants/channel.constants.js
+++ b/web/src/constants/channel.constants.js
@@ -3,86 +3,86 @@ export const CHANNEL_OPTIONS = [
{
value: 2,
color: 'light-blue',
- label: 'Midjourney Proxy'
+ label: 'Midjourney Proxy',
},
{
value: 5,
color: 'blue',
- label: 'Midjourney Proxy Plus'
+ label: 'Midjourney Proxy Plus',
},
{
value: 36,
color: 'purple',
- label: 'Suno API'
+ label: 'Suno API',
},
{ value: 4, color: 'grey', label: 'Ollama' },
{
value: 14,
color: 'indigo',
- label: 'Anthropic Claude'
+ label: 'Anthropic Claude',
},
{
value: 33,
color: 'indigo',
- label: 'AWS Claude'
+ label: 'AWS Claude',
},
{ value: 41, color: 'blue', label: 'Vertex AI' },
{
value: 3,
color: 'teal',
- label: 'Azure OpenAI'
+ label: 'Azure OpenAI',
},
{
value: 34,
color: 'purple',
- label: 'Cohere'
+ label: 'Cohere',
},
{ value: 39, color: 'grey', label: 'Cloudflare' },
{ value: 43, color: 'blue', label: 'DeepSeek' },
{
value: 15,
color: 'blue',
- label: '百度文心千帆'
+ label: '百度文心千帆',
},
{
value: 46,
color: 'blue',
- label: '百度文心千帆V2'
+ label: '百度文心千帆V2',
},
{
value: 17,
color: 'orange',
- label: '阿里通义千问'
+ label: '阿里通义千问',
},
{
value: 18,
color: 'blue',
- label: '讯飞星火认知'
+ label: '讯飞星火认知',
},
{
value: 16,
color: 'violet',
- label: '智谱 ChatGLM'
+ label: '智谱 ChatGLM',
},
{
value: 26,
color: 'purple',
- label: '智谱 GLM-4V'
+ label: '智谱 GLM-4V',
},
{
value: 24,
color: 'orange',
- label: 'Google Gemini'
+ label: 'Google Gemini',
},
{
value: 11,
color: 'orange',
- label: 'Google PaLM2'
+ label: 'Google PaLM2',
},
{
value: 47,
color: 'blue',
- label: 'Xinference'
+ label: 'Xinference',
},
{ value: 25, color: 'green', label: 'Moonshot' },
{ value: 20, color: 'green', label: 'OpenRouter' },
@@ -98,22 +98,22 @@ export const CHANNEL_OPTIONS = [
{
value: 22,
color: 'blue',
- label: '知识库:FastGPT'
+ label: '知识库:FastGPT',
},
{
value: 21,
color: 'purple',
- label: '知识库:AI Proxy'
+ label: '知识库:AI Proxy',
},
{
value: 44,
color: 'purple',
- label: '嵌入模型:MokaAI M3E'
+ label: '嵌入模型:MokaAI M3E',
},
{
value: 45,
color: 'blue',
- label: '字节火山方舟、豆包、DeepSeek通用'
+ label: '字节火山方舟、豆包、DeepSeek通用',
},
{
value: 48,
diff --git a/web/src/context/Style/index.js b/web/src/context/Style/index.js
index fb516e84..db9b0dd1 100644
--- a/web/src/context/Style/index.js
+++ b/web/src/context/Style/index.js
@@ -19,25 +19,25 @@ export const StyleProvider = ({ children }) => {
if ('type' in action) {
switch (action.type) {
case 'TOGGLE_SIDER':
- setState(prev => ({ ...prev, showSider: !prev.showSider }));
+ setState((prev) => ({ ...prev, showSider: !prev.showSider }));
break;
case 'SET_SIDER':
- setState(prev => ({ ...prev, showSider: action.payload }));
+ setState((prev) => ({ ...prev, showSider: action.payload }));
break;
case 'SET_MOBILE':
- setState(prev => ({ ...prev, isMobile: action.payload }));
+ setState((prev) => ({ ...prev, isMobile: action.payload }));
break;
case 'SET_SIDER_COLLAPSED':
- setState(prev => ({ ...prev, siderCollapsed: action.payload }));
- break
+ setState((prev) => ({ ...prev, siderCollapsed: action.payload }));
+ break;
case 'SET_INNER_PADDING':
- setState(prev => ({ ...prev, shouldInnerPadding: action.payload }));
+ setState((prev) => ({ ...prev, shouldInnerPadding: action.payload }));
break;
default:
- setState(prev => ({ ...prev, ...action }));
+ setState((prev) => ({ ...prev, ...action }));
}
} else {
- setState(prev => ({ ...prev, ...action }));
+ setState((prev) => ({ ...prev, ...action }));
}
};
@@ -45,7 +45,7 @@ export const StyleProvider = ({ children }) => {
const updateIsMobile = () => {
const mobileDetected = isMobile();
dispatch({ type: 'SET_MOBILE', payload: mobileDetected });
-
+
// If on mobile, we might want to auto-hide the sidebar
if (mobileDetected && state.showSider) {
dispatch({ type: 'SET_SIDER', payload: false });
@@ -57,7 +57,12 @@ export const StyleProvider = ({ children }) => {
const updateShowSider = () => {
// check pathname
const pathname = window.location.pathname;
- if (pathname === '' || pathname === '/' || pathname.includes('/home') || pathname.includes('/chat')) {
+ if (
+ pathname === '' ||
+ pathname === '/' ||
+ pathname.includes('/home') ||
+ pathname.includes('/chat')
+ ) {
dispatch({ type: 'SET_SIDER', payload: false });
dispatch({ type: 'SET_INNER_PADDING', payload: false });
} else if (pathname === '/setup') {
@@ -73,7 +78,8 @@ export const StyleProvider = ({ children }) => {
updateShowSider();
const updateSiderCollapsed = () => {
- const isCollapsed = localStorage.getItem('default_collapse_sidebar') === 'true';
+ const isCollapsed =
+ localStorage.getItem('default_collapse_sidebar') === 'true';
dispatch({ type: 'SET_SIDER_COLLAPSED', payload: isCollapsed });
};
@@ -83,7 +89,7 @@ export const StyleProvider = ({ children }) => {
const handleResize = () => {
updateIsMobile();
};
-
+
window.addEventListener('resize', handleResize);
// Cleanup event listener on component unmount
diff --git a/web/src/helpers/api.js b/web/src/helpers/api.js
index 635d63b8..84d2df1f 100644
--- a/web/src/helpers/api.js
+++ b/web/src/helpers/api.js
@@ -7,8 +7,8 @@ export let API = axios.create({
: '',
headers: {
'New-API-User': getUserIdFromLocalStorage(),
- 'Cache-Control': 'no-store'
- }
+ 'Cache-Control': 'no-store',
+ },
});
export function updateAPI() {
@@ -18,8 +18,8 @@ export function updateAPI() {
: '',
headers: {
'New-API-User': getUserIdFromLocalStorage(),
- 'Cache-Control': 'no-store'
- }
+ 'Cache-Control': 'no-store',
+ },
});
}
diff --git a/web/src/helpers/other.js b/web/src/helpers/other.js
index 3e172180..c5d8c269 100644
--- a/web/src/helpers/other.js
+++ b/web/src/helpers/other.js
@@ -1,7 +1,7 @@
-export function getLogOther(otherStr) {
- if (otherStr === undefined || otherStr === '') {
- otherStr = '{}'
- }
- let other = JSON.parse(otherStr)
- return other
-}
\ No newline at end of file
+export function getLogOther(otherStr) {
+ if (otherStr === undefined || otherStr === '') {
+ otherStr = '{}';
+ }
+ let other = JSON.parse(otherStr);
+ return other;
+}
diff --git a/web/src/helpers/render.js b/web/src/helpers/render.js
index d1396191..4d1a3113 100644
--- a/web/src/helpers/render.js
+++ b/web/src/helpers/render.js
@@ -44,7 +44,10 @@ export function renderGroup(group) {
if (await copy(group)) {
showSuccess(i18next.t('已复制:') + group);
} else {
- Modal.error({ title: t('无法复制到剪贴板,请手动复制'), content: group });
+ Modal.error({
+ title: t('无法复制到剪贴板,请手动复制'),
+ content: group,
+ });
}
}}
>
@@ -64,28 +67,37 @@ export function renderRatio(ratio) {
} else if (ratio > 1) {
color = 'blue';
}
- return
{ratio}x {i18next.t('倍率')};
+ return (
+
+ {ratio}x {i18next.t('倍率')}
+
+ );
}
-const measureTextWidth = (text, style = {
- fontSize: '14px',
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
-}, containerWidth) => {
+const measureTextWidth = (
+ text,
+ style = {
+ fontSize: '14px',
+ fontFamily:
+ '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
+ },
+ containerWidth,
+) => {
const span = document.createElement('span');
-
+
span.style.visibility = 'hidden';
span.style.position = 'absolute';
span.style.whiteSpace = 'nowrap';
span.style.fontSize = style.fontSize;
span.style.fontFamily = style.fontFamily;
-
+
span.textContent = text;
-
+
document.body.appendChild(span);
const width = span.offsetWidth;
-
+
document.body.removeChild(span);
-
+
return width;
};
@@ -94,7 +106,7 @@ export function truncateText(text, maxWidth = 200) {
return text;
}
if (!text) return text;
-
+
try {
// Handle percentage-based maxWidth
let actualMaxWidth = maxWidth;
@@ -103,19 +115,19 @@ export function truncateText(text, maxWidth = 200) {
// Use window width as fallback container width
actualMaxWidth = window.innerWidth * percentage;
}
-
+
const width = measureTextWidth(text);
if (width <= actualMaxWidth) return text;
-
+
let left = 0;
let right = text.length;
let result = text;
-
+
while (left <= right) {
const mid = Math.floor((left + right) / 2);
const truncated = text.slice(0, mid) + '...';
const currentWidth = measureTextWidth(truncated);
-
+
if (currentWidth <= actualMaxWidth) {
result = truncated;
left = mid + 1;
@@ -123,10 +135,13 @@ export function truncateText(text, maxWidth = 200) {
right = mid - 1;
}
}
-
+
return result;
} catch (error) {
- console.warn('Text measurement failed, falling back to character count', error);
+ console.warn(
+ 'Text measurement failed, falling back to character count',
+ error,
+ );
if (text.length > 20) {
return text.slice(0, 17) + '...';
}
@@ -149,11 +164,11 @@ export const renderGroupOption = (item) => {
emptyContent,
...rest
} = item;
-
+
const baseStyle = {
- display: 'flex',
- justifyContent: 'space-between',
- alignItems: 'center',
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
padding: '8px 16px',
cursor: disabled ? 'not-allowed' : 'pointer',
backgroundColor: focused ? 'var(--semi-color-fill-0)' : 'transparent',
@@ -162,8 +177,8 @@ export const renderGroupOption = (item) => {
backgroundColor: 'var(--semi-color-primary-light-default)',
}),
'&:hover': {
- backgroundColor: !disabled && 'var(--semi-color-fill-1)'
- }
+ backgroundColor: !disabled && 'var(--semi-color-fill-1)',
+ },
};
const handleClick = () => {
@@ -177,9 +192,9 @@ export const renderGroupOption = (item) => {
onMouseEnter(e);
}
};
-
+
return (
-
{
{value}
-
+
{label}
@@ -222,8 +237,7 @@ export function renderQuotaNumberWithDigit(num, digits = 2) {
}
export function renderNumberWithPoint(num) {
- if (num === undefined)
- return '';
+ if (num === undefined) return '';
num = num.toFixed(2);
if (num >= 100000) {
// Convert number to string to manipulate it
@@ -302,11 +316,14 @@ export function renderModelPrice(
cacheRatio = 1.0,
) {
if (modelPrice !== -1) {
- return i18next.t('模型价格:${{price}} * 分组倍率:{{ratio}} = ${{total}}', {
- price: modelPrice,
- ratio: groupRatio,
- total: modelPrice * groupRatio
- });
+ return i18next.t(
+ '模型价格:${{price}} * 分组倍率:{{ratio}} = ${{total}}',
+ {
+ price: modelPrice,
+ ratio: groupRatio,
+ total: modelPrice * groupRatio,
+ },
+ );
} else {
if (completionRatio === undefined) {
completionRatio = 0;
@@ -314,54 +331,72 @@ export function renderModelPrice(
let inputRatioPrice = modelRatio * 2.0;
let completionRatioPrice = modelRatio * 2.0 * completionRatio;
let cacheRatioPrice = modelRatio * 2.0 * cacheRatio;
-
+
// Calculate effective input tokens (non-cached + cached with ratio applied)
- const effectiveInputTokens = (inputTokens - cacheTokens) + (cacheTokens * cacheRatio);
-
+ const effectiveInputTokens =
+ inputTokens - cacheTokens + cacheTokens * cacheRatio;
+
let price =
(effectiveInputTokens / 1000000) * inputRatioPrice * groupRatio +
(completionTokens / 1000000) * completionRatioPrice * groupRatio;
-
+
return (
<>
- {i18next.t('提示价格:${{price}} / 1M tokens', {
- price: inputRatioPrice,
- })}
- {i18next.t('补全价格:${{price}} * {{completionRatio}} = ${{total}} / 1M tokens (补全倍率: {{completionRatio}})', {
- price: inputRatioPrice,
- total: completionRatioPrice,
- completionRatio: completionRatio
- })}
- {cacheTokens > 0 && (
- {i18next.t('缓存价格:${{price}} * {{cacheRatio}} = ${{total}} / 1M tokens (缓存倍率: {{cacheRatio}})', {
+
+ {i18next.t('提示价格:${{price}} / 1M tokens', {
price: inputRatioPrice,
- total: inputRatioPrice * cacheRatio,
- cacheRatio: cacheRatio
- })}
+ })}
+
+
+ {i18next.t(
+ '补全价格:${{price}} * {{completionRatio}} = ${{total}} / 1M tokens (补全倍率: {{completionRatio}})',
+ {
+ price: inputRatioPrice,
+ total: completionRatioPrice,
+ completionRatio: completionRatio,
+ },
+ )}
+
+ {cacheTokens > 0 && (
+
+ {i18next.t(
+ '缓存价格:${{price}} * {{cacheRatio}} = ${{total}} / 1M tokens (缓存倍率: {{cacheRatio}})',
+ {
+ price: inputRatioPrice,
+ total: inputRatioPrice * cacheRatio,
+ cacheRatio: cacheRatio,
+ },
+ )}
+
)}
- {cacheTokens > 0 ?
- i18next.t('提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}', {
- nonCacheInput: inputTokens - cacheTokens,
- cacheInput: cacheTokens,
- cachePrice: inputRatioPrice * cacheRatio,
- price: inputRatioPrice,
- completion: completionTokens,
- compPrice: completionRatioPrice,
- ratio: groupRatio,
- total: price.toFixed(6)
- }) :
- i18next.t('提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}', {
- input: inputTokens,
- price: inputRatioPrice,
- completion: completionTokens,
- compPrice: completionRatioPrice,
- ratio: groupRatio,
- total: price.toFixed(6)
- })
- }
+ {cacheTokens > 0
+ ? i18next.t(
+ '提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
+ {
+ nonCacheInput: inputTokens - cacheTokens,
+ cacheInput: cacheTokens,
+ cachePrice: inputRatioPrice * cacheRatio,
+ price: inputRatioPrice,
+ completion: completionTokens,
+ compPrice: completionRatioPrice,
+ ratio: groupRatio,
+ total: price.toFixed(6),
+ },
+ )
+ : i18next.t(
+ '提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
+ {
+ input: inputTokens,
+ price: inputRatioPrice,
+ completion: completionTokens,
+ compPrice: completionRatioPrice,
+ ratio: groupRatio,
+ total: price.toFixed(6),
+ },
+ )}
{i18next.t('仅供参考,以实际扣费为准')}
@@ -380,19 +415,22 @@ export function renderModelPriceSimple(
if (modelPrice !== -1) {
return i18next.t('价格:${{price}} * 分组:{{ratio}}', {
price: modelPrice,
- ratio: groupRatio
+ ratio: groupRatio,
});
} else {
if (cacheTokens !== 0) {
- return i18next.t('模型: {{ratio}} * 分组: {{groupRatio}} * 缓存: {{cacheRatio}}', {
- ratio: modelRatio,
- groupRatio: groupRatio,
- cacheRatio: cacheRatio
- });
+ return i18next.t(
+ '模型: {{ratio}} * 分组: {{groupRatio}} * 缓存: {{cacheRatio}}',
+ {
+ ratio: modelRatio,
+ groupRatio: groupRatio,
+ cacheRatio: cacheRatio,
+ },
+ );
} else {
return i18next.t('模型: {{ratio}} * 分组: {{groupRatio}}', {
ratio: modelRatio,
- groupRatio: groupRatio
+ groupRatio: groupRatio,
});
}
}
@@ -414,11 +452,14 @@ export function renderAudioModelPrice(
) {
// 1 ratio = $0.002 / 1K tokens
if (modelPrice !== -1) {
- return i18next.t('模型价格:${{price}} * 分组倍率:{{ratio}} = ${{total}}', {
- price: modelPrice,
- ratio: groupRatio,
- total: modelPrice * groupRatio
- });
+ return i18next.t(
+ '模型价格:${{price}} * 分组倍率:{{ratio}} = ${{total}}',
+ {
+ price: modelPrice,
+ ratio: groupRatio,
+ total: modelPrice * groupRatio,
+ },
+ );
} else {
if (completionRatio === undefined) {
completionRatio = 0;
@@ -430,81 +471,120 @@ export function renderAudioModelPrice(
let inputRatioPrice = modelRatio * 2.0;
let completionRatioPrice = modelRatio * 2.0 * completionRatio;
let cacheRatioPrice = modelRatio * 2.0 * cacheRatio;
-
+
// Calculate effective input tokens (non-cached + cached with ratio applied)
- const effectiveInputTokens = (inputTokens - cacheTokens) + (cacheTokens * cacheRatio);
-
+ const effectiveInputTokens =
+ inputTokens - cacheTokens + cacheTokens * cacheRatio;
+
let textPrice =
(effectiveInputTokens / 1000000) * inputRatioPrice * groupRatio +
- (completionTokens / 1000000) * completionRatioPrice * groupRatio
+ (completionTokens / 1000000) * completionRatioPrice * groupRatio;
let audioPrice =
(audioInputTokens / 1000000) * inputRatioPrice * audioRatio * groupRatio +
- (audioCompletionTokens / 1000000) * inputRatioPrice * audioRatio * audioCompletionRatio * groupRatio;
+ (audioCompletionTokens / 1000000) *
+ inputRatioPrice *
+ audioRatio *
+ audioCompletionRatio *
+ groupRatio;
let price = textPrice + audioPrice;
return (
<>
- {i18next.t('提示价格:${{price}} / 1M tokens', {
- price: inputRatioPrice,
- })}
- {i18next.t('补全价格:${{price}} * {{completionRatio}} = ${{total}} / 1M tokens (补全倍率: {{completionRatio}})', {
- price: inputRatioPrice,
- total: completionRatioPrice,
- completionRatio: completionRatio
- })}
- {cacheTokens > 0 && (
- {i18next.t('缓存价格:${{price}} * {{cacheRatio}} = ${{total}} / 1M tokens (缓存倍率: {{cacheRatio}})', {
+
+ {i18next.t('提示价格:${{price}} / 1M tokens', {
price: inputRatioPrice,
- total: inputRatioPrice * cacheRatio,
- cacheRatio: cacheRatio
- })}
+ })}
+
+
+ {i18next.t(
+ '补全价格:${{price}} * {{completionRatio}} = ${{total}} / 1M tokens (补全倍率: {{completionRatio}})',
+ {
+ price: inputRatioPrice,
+ total: completionRatioPrice,
+ completionRatio: completionRatio,
+ },
+ )}
+
+ {cacheTokens > 0 && (
+
+ {i18next.t(
+ '缓存价格:${{price}} * {{cacheRatio}} = ${{total}} / 1M tokens (缓存倍率: {{cacheRatio}})',
+ {
+ price: inputRatioPrice,
+ total: inputRatioPrice * cacheRatio,
+ cacheRatio: cacheRatio,
+ },
+ )}
+
)}
- {i18next.t('音频提示价格:${{price}} * {{audioRatio}} = ${{total}} / 1M tokens (音频倍率: {{audioRatio}})', {
- price: inputRatioPrice,
- total: inputRatioPrice * audioRatio,
- audioRatio: audioRatio
- })}
- {i18next.t('音频补全价格:${{price}} * {{audioRatio}} * {{audioCompRatio}} = ${{total}} / 1M tokens (音频补全倍率: {{audioCompRatio}})', {
- price: inputRatioPrice,
- total: inputRatioPrice * audioRatio * audioCompletionRatio,
- audioRatio: audioRatio,
- audioCompRatio: audioCompletionRatio
- })}
- {cacheTokens > 0 ?
- i18next.t('文字提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}', {
- nonCacheInput: inputTokens - cacheTokens,
- cacheInput: cacheTokens,
- cachePrice: inputRatioPrice * cacheRatio,
+ {i18next.t(
+ '音频提示价格:${{price}} * {{audioRatio}} = ${{total}} / 1M tokens (音频倍率: {{audioRatio}})',
+ {
price: inputRatioPrice,
- completion: completionTokens,
- compPrice: completionRatioPrice,
- total: textPrice.toFixed(6)
- }) :
- i18next.t('文字提示 {{input}} tokens / 1M tokens * ${{price}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}', {
- input: inputTokens,
- price: inputRatioPrice,
- completion: completionTokens,
- compPrice: completionRatioPrice,
- total: textPrice.toFixed(6)
- })
- }
+ total: inputRatioPrice * audioRatio,
+ audioRatio: audioRatio,
+ },
+ )}
- {i18next.t('音频提示 {{input}} tokens / 1M tokens * ${{audioInputPrice}} + 音频补全 {{completion}} tokens / 1M tokens * ${{audioCompPrice}} = ${{total}}', {
- input: audioInputTokens,
- completion: audioCompletionTokens,
- audioInputPrice: audioRatio * inputRatioPrice,
- audioCompPrice: audioRatio * audioCompletionRatio * inputRatioPrice,
- total: audioPrice.toFixed(6)
- })}
+ {i18next.t(
+ '音频补全价格:${{price}} * {{audioRatio}} * {{audioCompRatio}} = ${{total}} / 1M tokens (音频补全倍率: {{audioCompRatio}})',
+ {
+ price: inputRatioPrice,
+ total: inputRatioPrice * audioRatio * audioCompletionRatio,
+ audioRatio: audioRatio,
+ audioCompRatio: audioCompletionRatio,
+ },
+ )}
- {i18next.t('总价:文字价格 {{textPrice}} + 音频价格 {{audioPrice}} = ${{total}}', {
- total: price.toFixed(6),
- textPrice: textPrice.toFixed(6),
- audioPrice: audioPrice.toFixed(6)
- })}
+ {cacheTokens > 0
+ ? i18next.t(
+ '文字提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}',
+ {
+ nonCacheInput: inputTokens - cacheTokens,
+ cacheInput: cacheTokens,
+ cachePrice: inputRatioPrice * cacheRatio,
+ price: inputRatioPrice,
+ completion: completionTokens,
+ compPrice: completionRatioPrice,
+ total: textPrice.toFixed(6),
+ },
+ )
+ : i18next.t(
+ '文字提示 {{input}} tokens / 1M tokens * ${{price}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}',
+ {
+ input: inputTokens,
+ price: inputRatioPrice,
+ completion: completionTokens,
+ compPrice: completionRatioPrice,
+ total: textPrice.toFixed(6),
+ },
+ )}
+
+
+ {i18next.t(
+ '音频提示 {{input}} tokens / 1M tokens * ${{audioInputPrice}} + 音频补全 {{completion}} tokens / 1M tokens * ${{audioCompPrice}} = ${{total}}',
+ {
+ input: audioInputTokens,
+ completion: audioCompletionTokens,
+ audioInputPrice: audioRatio * inputRatioPrice,
+ audioCompPrice:
+ audioRatio * audioCompletionRatio * inputRatioPrice,
+ total: audioPrice.toFixed(6),
+ },
+ )}
+
+
+ {i18next.t(
+ '总价:文字价格 {{textPrice}} + 音频价格 {{audioPrice}} = ${{total}}',
+ {
+ total: price.toFixed(6),
+ textPrice: textPrice.toFixed(6),
+ audioPrice: audioPrice.toFixed(6),
+ },
+ )}
{i18next.t('仅供参考,以实际扣费为准')}
@@ -517,7 +597,9 @@ export function renderQuotaWithPrompt(quota, digits) {
let displayInCurrency = localStorage.getItem('display_in_currency');
displayInCurrency = displayInCurrency === 'true';
if (displayInCurrency) {
- return ' | ' + i18next.t('等价金额') + ': ' + renderQuota(quota, digits) + '';
+ return (
+ ' | ' + i18next.t('等价金额') + ': ' + renderQuota(quota, digits) + ''
+ );
}
return '';
}
@@ -537,7 +619,7 @@ const colors = [
'red',
'teal',
'violet',
- 'yellow'
+ 'yellow',
];
// 基础10色色板 (N ≤ 10)
@@ -551,7 +633,7 @@ const baseColors = [
'#304D77',
'#B48DEB',
'#009488',
- '#FF7DDA'
+ '#FF7DDA',
];
// 扩展20色色板 (10 < N ≤ 20)
@@ -575,7 +657,7 @@ const extendedColors = [
'#009488',
'#59BAA8',
'#FF7DDA',
- '#FFCFEE'
+ '#FFCFEE',
];
export const modelColorMap = {
@@ -631,14 +713,14 @@ export function modelToColor(modelName) {
// 2. 生成一个稳定的数字作为索引
let hash = 0;
for (let i = 0; i < modelName.length; i++) {
- hash = ((hash << 5) - hash) + modelName.charCodeAt(i);
+ hash = (hash << 5) - hash + modelName.charCodeAt(i);
hash = hash & hash; // Convert to 32-bit integer
}
hash = Math.abs(hash);
// 3. 根据模型名称长度选择不同的色板
const colorPalette = modelName.length > 10 ? extendedColors : baseColors;
-
+
// 4. 使用hash值选择颜色
const index = hash % colorPalette.length;
return colorPalette[index];
@@ -668,12 +750,15 @@ export function renderClaudeModelPrice(
const ratioLabel = false ? i18next.t('专属倍率') : i18next.t('分组倍率');
if (modelPrice !== -1) {
- return i18next.t('模型价格:${{price}} * {{ratioType}}:{{ratio}} = ${{total}}', {
- price: modelPrice,
- ratioType: ratioLabel,
- ratio: groupRatio,
- total: modelPrice * groupRatio
- });
+ return i18next.t(
+ '模型价格:${{price}} * {{ratioType}}:{{ratio}} = ${{total}}',
+ {
+ price: modelPrice,
+ ratioType: ratioLabel,
+ ratio: groupRatio,
+ total: modelPrice * groupRatio,
+ },
+ );
} else {
if (completionRatio === undefined) {
completionRatio = 0;
@@ -687,9 +772,10 @@ export function renderClaudeModelPrice(
// Calculate effective input tokens (non-cached + cached with ratio applied + cache creation with ratio applied)
const nonCachedTokens = inputTokens;
- const effectiveInputTokens = nonCachedTokens +
- (cacheTokens * cacheRatio) +
- (cacheCreationTokens * cacheCreationRatio);
+ const effectiveInputTokens =
+ nonCachedTokens +
+ cacheTokens * cacheRatio +
+ cacheCreationTokens * cacheCreationRatio;
let price =
(effectiveInputTokens / 1000000) * inputRatioPrice * groupRatio +
@@ -698,56 +784,78 @@ export function renderClaudeModelPrice(
return (
<>
- {i18next.t('提示价格:${{price}} / 1M tokens', {
- price: inputRatioPrice,
- })}
- {i18next.t('补全价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens', {
- price: inputRatioPrice,
- ratio: completionRatio,
- total: completionRatioPrice
- })}
- {cacheTokens > 0 && (
- {i18next.t('缓存价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens (缓存倍率: {{cacheRatio}})', {
+
+ {i18next.t('提示价格:${{price}} / 1M tokens', {
price: inputRatioPrice,
- ratio: cacheRatio,
- total: cacheRatioPrice,
- cacheRatio: cacheRatio
- })}
+ })}
+
+
+ {i18next.t(
+ '补全价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens',
+ {
+ price: inputRatioPrice,
+ ratio: completionRatio,
+ total: completionRatioPrice,
+ },
+ )}
+
+ {cacheTokens > 0 && (
+
+ {i18next.t(
+ '缓存价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens (缓存倍率: {{cacheRatio}})',
+ {
+ price: inputRatioPrice,
+ ratio: cacheRatio,
+ total: cacheRatioPrice,
+ cacheRatio: cacheRatio,
+ },
+ )}
+
)}
{cacheCreationTokens > 0 && (
- {i18next.t('缓存创建价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens (缓存创建倍率: {{cacheCreationRatio}})', {
- price: inputRatioPrice,
- ratio: cacheCreationRatio,
- total: cacheCreationRatioPrice,
- cacheCreationRatio: cacheCreationRatio
- })}
+
+ {i18next.t(
+ '缓存创建价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens (缓存创建倍率: {{cacheCreationRatio}})',
+ {
+ price: inputRatioPrice,
+ ratio: cacheCreationRatio,
+ total: cacheCreationRatioPrice,
+ cacheCreationRatio: cacheCreationRatio,
+ },
+ )}
+
)}
- {(cacheTokens > 0 || cacheCreationTokens > 0) ?
- i18next.t('提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * ${{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}', {
- nonCacheInput: nonCachedTokens,
- cacheInput: cacheTokens,
- cacheRatio: cacheRatio,
- cacheCreationInput: cacheCreationTokens,
- cacheCreationRatio: cacheCreationRatio,
- cachePrice: cacheRatioPrice,
- cacheCreationPrice: cacheCreationRatioPrice,
- price: inputRatioPrice,
- completion: completionTokens,
- compPrice: completionRatioPrice,
- ratio: groupRatio,
- total: price.toFixed(6)
- }) :
- i18next.t('提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}', {
- input: inputTokens,
- price: inputRatioPrice,
- completion: completionTokens,
- compPrice: completionRatioPrice,
- ratio: groupRatio,
- total: price.toFixed(6)
- })
- }
+ {cacheTokens > 0 || cacheCreationTokens > 0
+ ? i18next.t(
+ '提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * ${{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
+ {
+ nonCacheInput: nonCachedTokens,
+ cacheInput: cacheTokens,
+ cacheRatio: cacheRatio,
+ cacheCreationInput: cacheCreationTokens,
+ cacheCreationRatio: cacheCreationRatio,
+ cachePrice: cacheRatioPrice,
+ cacheCreationPrice: cacheCreationRatioPrice,
+ price: inputRatioPrice,
+ completion: completionTokens,
+ compPrice: completionRatioPrice,
+ ratio: groupRatio,
+ total: price.toFixed(6),
+ },
+ )
+ : i18next.t(
+ '提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
+ {
+ input: inputTokens,
+ price: inputRatioPrice,
+ completion: completionTokens,
+ compPrice: completionRatioPrice,
+ ratio: groupRatio,
+ total: price.toFixed(6),
+ },
+ )}
{i18next.t('仅供参考,以实际扣费为准')}
@@ -770,17 +878,20 @@ export function renderClaudeLogContent(
return i18next.t('模型价格 ${{price}},{{ratioType}} {{ratio}}', {
price: modelPrice,
ratioType: ratioLabel,
- ratio: groupRatio
+ ratio: groupRatio,
});
} else {
- return i18next.t('模型倍率 {{modelRatio}},补全倍率 {{completionRatio}},缓存倍率 {{cacheRatio}},缓存创建倍率 {{cacheCreationRatio}},{{ratioType}} {{ratio}}', {
- modelRatio: modelRatio,
- completionRatio: completionRatio,
- cacheRatio: cacheRatio,
- cacheCreationRatio: cacheCreationRatio,
- ratioType: ratioLabel,
- ratio: groupRatio
- });
+ return i18next.t(
+ '模型倍率 {{modelRatio}},补全倍率 {{completionRatio}},缓存倍率 {{cacheRatio}},缓存创建倍率 {{cacheCreationRatio}},{{ratioType}} {{ratio}}',
+ {
+ modelRatio: modelRatio,
+ completionRatio: completionRatio,
+ cacheRatio: cacheRatio,
+ cacheCreationRatio: cacheCreationRatio,
+ ratioType: ratioLabel,
+ ratio: groupRatio,
+ },
+ );
}
}
@@ -799,22 +910,25 @@ export function renderClaudeModelPriceSimple(
return i18next.t('价格:${{price}} * {{ratioType}}:{{ratio}}', {
price: modelPrice,
ratioType: ratioLabel,
- ratio: groupRatio
+ ratio: groupRatio,
});
} else {
if (cacheTokens !== 0 || cacheCreationTokens !== 0) {
- return i18next.t('模型: {{ratio}} * {{ratioType}}: {{groupRatio}} * 缓存: {{cacheRatio}}', {
- ratio: modelRatio,
- ratioType: ratioLabel,
- groupRatio: groupRatio,
- cacheRatio: cacheRatio,
- cacheCreationRatio: cacheCreationRatio
- });
+ return i18next.t(
+ '模型: {{ratio}} * {{ratioType}}: {{groupRatio}} * 缓存: {{cacheRatio}}',
+ {
+ ratio: modelRatio,
+ ratioType: ratioLabel,
+ groupRatio: groupRatio,
+ cacheRatio: cacheRatio,
+ cacheCreationRatio: cacheCreationRatio,
+ },
+ );
} else {
return i18next.t('模型: {{ratio}} * {{ratioType}}: {{groupRatio}}', {
ratio: modelRatio,
ratioType: ratioLabel,
- groupRatio: groupRatio
+ groupRatio: groupRatio,
});
}
}
@@ -824,7 +938,7 @@ export function renderLogContent(
modelRatio,
completionRatio,
modelPrice = -1,
- groupRatio
+ groupRatio,
) {
const ratioLabel = false ? i18next.t('专属倍率') : i18next.t('分组倍率');
@@ -832,14 +946,17 @@ export function renderLogContent(
return i18next.t('模型价格 ${{price}},{{ratioType}} {{ratio}}', {
price: modelPrice,
ratioType: ratioLabel,
- ratio: groupRatio
+ ratio: groupRatio,
});
} else {
- return i18next.t('模型倍率 {{modelRatio}},补全倍率 {{completionRatio}},{{ratioType}} {{ratio}}', {
- modelRatio: modelRatio,
- completionRatio: completionRatio,
- ratioType: ratioLabel,
- ratio: groupRatio
- });
+ return i18next.t(
+ '模型倍率 {{modelRatio}},补全倍率 {{completionRatio}},{{ratioType}} {{ratio}}',
+ {
+ modelRatio: modelRatio,
+ completionRatio: completionRatio,
+ ratioType: ratioLabel,
+ ratio: groupRatio,
+ },
+ );
}
}
diff --git a/web/src/helpers/utils.js b/web/src/helpers/utils.js
index a40b2079..943daed9 100644
--- a/web/src/helpers/utils.js
+++ b/web/src/helpers/utils.js
@@ -51,11 +51,11 @@ export async function copy(text) {
} catch (e) {
try {
// 构建input 执行 复制命令
- var _input = window.document.createElement("input");
+ var _input = window.document.createElement('input');
_input.value = text;
window.document.body.appendChild(_input);
_input.select();
- window.document.execCommand("Copy");
+ window.document.execCommand('Copy');
window.document.body.removeChild(_input);
} catch (e) {
okay = false;
@@ -191,7 +191,7 @@ export function timestamp2string1(timestamp, dataExportDefaultTime = 'hour') {
let day = date.getDate().toString();
let hour = date.getHours().toString();
if (day === '24') {
- console.log("timestamp", timestamp);
+ console.log('timestamp', timestamp);
}
if (month.length === 1) {
month = '0' + month;
@@ -247,7 +247,6 @@ export function verifyJSONPromise(value) {
}
}
-
export function shouldShowPrompt(id) {
let prompt = localStorage.getItem(`prompt-${id}`);
return !prompt;
diff --git a/web/src/i18n/i18n.js b/web/src/i18n/i18n.js
index f0d6687d..c1bf5860 100644
--- a/web/src/i18n/i18n.js
+++ b/web/src/i18n/i18n.js
@@ -11,16 +11,16 @@ i18n
.init({
resources: {
en: {
- translation: enTranslation
+ translation: enTranslation,
},
zh: {
- translation: zhTranslation
- }
+ translation: zhTranslation,
+ },
},
fallbackLng: 'zh',
interpolation: {
- escapeValue: false
- }
+ escapeValue: false,
+ },
});
-export default i18n;
\ No newline at end of file
+export default i18n;
diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json
index 05ed0d3e..8aaaab77 100644
--- a/web/src/i18n/locales/en.json
+++ b/web/src/i18n/locales/en.json
@@ -1065,7 +1065,7 @@
"价格:${{price}} * 分组:{{ratio}}": "Price: ${{price}} * Group: {{ratio}}",
"模型: {{ratio}} * 分组: {{groupRatio}}": "Model: {{ratio}} * Group: {{groupRatio}}",
"统计额度": "Statistical quota",
- "统计Tokens": "Statistical Tokens",
+ "统计Tokens": "Statistical Tokens",
"统计次数": "Statistical count",
"平均RPM": "Average RPM",
"平均TPM": "Average TPM",
diff --git a/web/src/i18n/locales/zh.json b/web/src/i18n/locales/zh.json
index b2cf894c..5c7904fc 100644
--- a/web/src/i18n/locales/zh.json
+++ b/web/src/i18n/locales/zh.json
@@ -10,4 +10,4 @@
"展开侧边栏": "展开侧边栏",
"关闭侧边栏": "关闭侧边栏",
"注销成功!": "注销成功!"
-}
\ No newline at end of file
+}
diff --git a/web/src/index.css b/web/src/index.css
index 75745568..c2e8ecd0 100644
--- a/web/src/index.css
+++ b/web/src/index.css
@@ -1,8 +1,8 @@
body {
margin: 0;
padding-top: 0;
- font-family: Lato, 'Helvetica Neue', Arial, Helvetica, 'Microsoft YaHei',
- sans-serif;
+ font-family:
+ Lato, 'Helvetica Neue', Arial, Helvetica, 'Microsoft YaHei', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
scrollbar-width: none;
@@ -18,7 +18,20 @@ body {
overflow: hidden;
}
-#root > section > header > section > div > div > div > div.semi-navigation-header-list-outer > div.semi-navigation-list-wrapper > ul > div > a > li > span{
+#root
+ > section
+ > header
+ > section
+ > div
+ > div
+ > div
+ > div.semi-navigation-header-list-outer
+ > div.semi-navigation-list-wrapper
+ > ul
+ > div
+ > a
+ > li
+ > span {
font-weight: 600 !important;
}
@@ -33,24 +46,56 @@ body {
.topnav {
padding: 0 8px;
}
-
+
.topnav .semi-navigation-item {
margin: 0 1px;
padding: 0 4px;
}
-
+
.topnav .semi-navigation-list-wrapper {
max-width: calc(55vw - 20px);
overflow-x: auto;
scrollbar-width: none;
}
- #root > section > header > section > div > div > div > div.semi-navigation-footer > div > a > li {
+ #root
+ > section
+ > header
+ > section
+ > div
+ > div
+ > div
+ > div.semi-navigation-footer
+ > div
+ > a
+ > li {
padding: 0 0;
}
- #root > section > header > section > div > div > div > div.semi-navigation-header-list-outer > div.semi-navigation-list-wrapper > ul > div > a > li {
+ #root
+ > section
+ > header
+ > section
+ > div
+ > div
+ > div
+ > div.semi-navigation-header-list-outer
+ > div.semi-navigation-list-wrapper
+ > ul
+ > div
+ > a
+ > li {
padding: 0 5px;
}
- #root > section > header > section > div > div > div > div.semi-navigation-footer > div:nth-child(1) > a > li {
+ #root
+ > section
+ > header
+ > section
+ > div
+ > div
+ > div
+ > div.semi-navigation-footer
+ > div:nth-child(1)
+ > a
+ > li {
padding: 0 5px;
}
.semi-navigation-footer {
@@ -96,13 +141,13 @@ body {
position: static !important;
height: 100% !important;
}
-
+
/* 确保内容区域在移动端可以正常滚动 */
#root {
overflow: visible !important;
height: 100% !important;
}
-
+
/* 隐藏在移动设备上 */
.hide-on-mobile {
display: none !important;
@@ -147,8 +192,8 @@ body::-webkit-scrollbar {
}
code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
+ font-family:
+ source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
}
.semi-navigation-item {
diff --git a/web/src/index.js b/web/src/index.js
index bc16e36b..aa709ff8 100644
--- a/web/src/index.js
+++ b/web/src/index.js
@@ -28,7 +28,7 @@ root.render(
-
+
diff --git a/web/src/pages/Channel/EditChannel.js b/web/src/pages/Channel/EditChannel.js
index 768ff90b..037f5e18 100644
--- a/web/src/pages/Channel/EditChannel.js
+++ b/web/src/pages/Channel/EditChannel.js
@@ -6,8 +6,9 @@ import {
isMobile,
showError,
showInfo,
- showSuccess, showWarning,
- verifyJSON
+ showSuccess,
+ showWarning,
+ verifyJSON,
} from '../../helpers';
import { CHANNEL_OPTIONS } from '../../constants';
import Title from '@douyinfe/semi-ui/lib/es/typography/title';
@@ -22,21 +23,22 @@ import {
Select,
TextArea,
Checkbox,
- Banner, Modal
+ Banner,
+ Modal,
} from '@douyinfe/semi-ui';
import { getChannelModels, loadChannelModels } from '../../components/utils.js';
const MODEL_MAPPING_EXAMPLE = {
- 'gpt-3.5-turbo': 'gpt-3.5-turbo-0125'
+ 'gpt-3.5-turbo': 'gpt-3.5-turbo-0125',
};
const STATUS_CODE_MAPPING_EXAMPLE = {
- 400: '500'
+ 400: '500',
};
const REGION_EXAMPLE = {
- 'default': 'us-central1',
- 'claude-3-5-sonnet-20240620': 'europe-west1'
+ default: 'us-central1',
+ 'claude-3-5-sonnet-20240620': 'europe-west1',
};
function type2secretPrompt(type) {
@@ -82,7 +84,7 @@ const EditChannel = (props) => {
groups: ['default'],
priority: 0,
weight: 0,
- tag: ''
+ tag: '',
};
const [batch, setBatch] = useState(false);
const [autoBan, setAutoBan] = useState(true);
@@ -98,12 +100,13 @@ const EditChannel = (props) => {
if (name === 'base_url' && value.endsWith('/v1')) {
Modal.confirm({
title: '警告',
- content: '不需要在末尾加/v1,New API会自动处理,添加后可能导致请求失败,是否继续?',
+ content:
+ '不需要在末尾加/v1,New API会自动处理,添加后可能导致请求失败,是否继续?',
onOk: () => {
setInputs((inputs) => ({ ...inputs, [name]: value }));
- }
- })
- return
+ },
+ });
+ return;
}
setInputs((inputs) => ({ ...inputs, [name]: value }));
if (name === 'type') {
@@ -117,7 +120,7 @@ const EditChannel = (props) => {
'mj_blend',
'mj_upscale',
'mj_describe',
- 'mj_uploads'
+ 'mj_uploads',
];
break;
case 5:
@@ -137,14 +140,11 @@ const EditChannel = (props) => {
'mj_high_variation',
'mj_low_variation',
'mj_pan',
- 'mj_uploads'
+ 'mj_uploads',
];
break;
case 36:
- localModels = [
- 'suno_music',
- 'suno_lyrics'
- ];
+ localModels = ['suno_music', 'suno_lyrics'];
break;
default:
localModels = getChannelModels(value);
@@ -180,7 +180,7 @@ const EditChannel = (props) => {
data.model_mapping = JSON.stringify(
JSON.parse(data.model_mapping),
null,
- 2
+ 2,
);
}
setInputs(data);
@@ -197,7 +197,6 @@ const EditChannel = (props) => {
setLoading(false);
};
-
const fetchUpstreamModelList = async (name) => {
// if (inputs['type'] !== 1) {
// showError(t('仅支持 OpenAI 接口格式'));
@@ -225,9 +224,9 @@ const EditChannel = (props) => {
const res = await API.post('/api/channel/fetch_models', {
base_url: inputs['base_url'],
type: inputs['type'],
- key: inputs['key']
+ key: inputs['key'],
});
-
+
if (res.data && res.data.success) {
models.push(...res.data.data);
} else {
@@ -254,7 +253,7 @@ const EditChannel = (props) => {
let res = await API.get(`/api/channel/models`);
let localModelOptions = res.data.data.map((model) => ({
label: model.id,
- value: model.id
+ value: model.id,
}));
setOriginModelOptions(localModelOptions);
setFullModels(res.data.data.map((model) => model.id));
@@ -263,7 +262,7 @@ const EditChannel = (props) => {
.filter((model) => {
return model.id.startsWith('gpt-') || model.id.startsWith('text-');
})
- .map((model) => model.id)
+ .map((model) => model.id),
);
} catch (error) {
showError(error.message);
@@ -279,8 +278,8 @@ const EditChannel = (props) => {
setGroupOptions(
res.data.data.map((group) => ({
label: group,
- value: group
- }))
+ value: group,
+ })),
);
} catch (error) {
showError(error.message);
@@ -293,7 +292,7 @@ const EditChannel = (props) => {
if (!localModelOptions.find((option) => option.label === model)) {
localModelOptions.push({
label: model,
- value: model
+ value: model,
});
}
});
@@ -304,7 +303,7 @@ const EditChannel = (props) => {
fetchModels().then();
fetchGroups().then();
if (isEdit) {
- loadChannel().then(() => {});
+ loadChannel().then(() => { });
} else {
setInputs(originInputs);
let localModels = getChannelModels(inputs.type);
@@ -330,7 +329,7 @@ const EditChannel = (props) => {
if (localInputs.base_url && localInputs.base_url.endsWith('/')) {
localInputs.base_url = localInputs.base_url.slice(
0,
- localInputs.base_url.length - 1
+ localInputs.base_url.length - 1,
);
}
if (localInputs.type === 18 && localInputs.other === '') {
@@ -348,7 +347,7 @@ const EditChannel = (props) => {
if (isEdit) {
res = await API.put(`/api/channel/`, {
...localInputs,
- id: parseInt(channelId)
+ id: parseInt(channelId),
});
} else {
res = await API.post(`/api/channel/`, localInputs);
@@ -382,7 +381,7 @@ const EditChannel = (props) => {
localModelOptions.push({
key: model,
text: model,
- value: model
+ value: model,
});
} else if (model) {
showError(t('某些模型已存在!'));
@@ -397,14 +396,15 @@ const EditChannel = (props) => {
handleInputChange('models', localModels);
};
-
return (
<>
{isEdit ? t('更新渠道信息') : t('创建新的渠道')}
+
+ {isEdit ? t('更新渠道信息') : t('创建新的渠道')}
+
}
headerStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
bodyStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
@@ -412,11 +412,11 @@ const EditChannel = (props) => {
footer={
-
{
handleInputChange('name', value);
}}
value={inputs.name}
- autoComplete="new-password"
+ autoComplete='new-password'
/>
{inputs.type !== 3 && inputs.type !== 8 && inputs.type !== 22 && inputs.type !== 36 && inputs.type !== 45 && (
<>
@@ -578,7 +585,7 @@ const EditChannel = (props) => {
{batch ? (