🗑️ chore(custom channel): Remove custom channel support from upstream ratio sync

Remove all custom channel functionality from the upstream ratio sync feature to simplify the codebase and focus on database-stored channels only.

Changes:
- Remove custom channel UI components and related state management
- Remove custom channel testing and validation logic
- Simplify ChannelSelectorModal by removing custom channel input fields
- Update API payload to only include channel_ids, removing custom_channels
- Remove custom channel processing logic from backend controller
- Update import path for DEFAULT_ENDPOINT constant

Files modified:
- web/src/pages/Setting/Ratio/UpstreamRatioSync.js
- web/src/components/settings/ChannelSelectorModal.js
- controller/ratio_sync.go

This change streamlines the ratio synchronization workflow by focusing solely on pre-configured database channels, reducing complexity and potential maintenance overhead.
This commit is contained in:
Apple\Apple
2025-06-19 15:17:05 +08:00
parent 7975cdf3bf
commit fb4ff63bad
5 changed files with 7 additions and 169 deletions

View File

@@ -3,12 +3,10 @@ import {
Modal,
Transfer,
Input,
Card,
Space,
Button,
Checkbox,
} from '@douyinfe/semi-ui';
import { IconPlus, IconClose } from '@douyinfe/semi-icons';
import { IconClose } from '@douyinfe/semi-icons';
/**
* ChannelSelectorModal
@@ -20,21 +18,13 @@ export default function ChannelSelectorModal({
visible,
onCancel,
onOk,
// 渠道选择
// 渠道选择
allChannels = [],
selectedChannelIds = [],
setSelectedChannelIds,
// 自定义渠道
customUrl,
setCustomUrl,
customEndpoint,
setCustomEndpoint,
customChannelTesting,
addCustomChannel,
// 渠道端点
channelEndpoints,
updateChannelEndpoint,
// 测试相关
}) {
// Transfer 自定义渲染
const renderSourceItem = (item) => {
@@ -107,32 +97,6 @@ export default function ChannelSelectorModal({
width={1000}
>
<Space vertical style={{ width: '100%' }}>
<Card title={t('添加自定义渠道')} className="w-full">
<Space direction="horizontal" style={{ width: '100%' }}>
<Input
placeholder={t('渠道地址https://example.com')}
value={customUrl}
onChange={setCustomUrl}
style={{ flex: 1 }}
/>
<Input
placeholder={t('接口路径')}
value={customEndpoint}
onChange={setCustomEndpoint}
style={{ width: 150 }}
/>
<Button
icon={<IconPlus />}
onClick={addCustomChannel}
loading={customChannelTesting}
disabled={!customUrl}
className="whitespace-nowrap"
>
{customChannelTesting ? t('测试中...') : t('添加')}
</Button>
</Space>
</Card>
<Transfer
style={{ width: '100%' }}
dataSource={allChannels}

View File

@@ -1 +1,3 @@
export const ITEMS_PER_PAGE = 10; // this value must keep same as the one defined in backend!
export const DEFAULT_ENDPOINT = '/api/ratio_config';

View File

@@ -1,20 +0,0 @@
export const DEFAULT_ENDPOINT = '/api/ratio_config';
/**
* buildEndpointUrl: 拼接 baseUrl 与 endpoint确保不会出现双斜杠或缺失斜杠问题。
* 使用 URL 构造函数保证协议/域名安全;若 baseUrl 非标准 URL则退回字符串拼接。
* @param {string} baseUrl - 基础地址,例如 https://api.example.com
* @param {string} endpoint - 接口路径,例如 /api/ratio_config
* @returns {string}
*/
export const buildEndpointUrl = (baseUrl, endpoint) => {
if (!baseUrl) return endpoint;
try {
return new URL(endpoint, baseUrl).toString();
} catch (_) {
// fallback 处理不规范的 baseUrl
const cleanedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
const cleanedEndpoint = endpoint.startsWith('/') ? endpoint.slice(1) : endpoint;
return `${cleanedBase}/${cleanedEndpoint}`;
}
};

View File

@@ -11,11 +11,8 @@ import {
RefreshCcw,
CheckSquare,
} from 'lucide-react';
import {
DEFAULT_ENDPOINT,
buildEndpointUrl,
} from '../../../helpers/ratio';
import { API, showError, showSuccess, showWarning } from '../../../helpers';
import { DEFAULT_ENDPOINT } from '../../../constants';
import { useTranslation } from 'react-i18next';
import {
IllustrationNoResult,
@@ -33,11 +30,6 @@ export default function UpstreamRatioSync(props) {
const [allChannels, setAllChannels] = useState([]);
const [selectedChannelIds, setSelectedChannelIds] = useState([]);
// 自定义渠道
const [customUrl, setCustomUrl] = useState('');
const [customEndpoint, setCustomEndpoint] = useState(DEFAULT_ENDPOINT);
const [customChannelTesting, setCustomChannelTesting] = useState(false);
// 渠道端点配置
const [channelEndpoints, setChannelEndpoints] = useState({}); // { channelId: endpoint }
@@ -94,86 +86,6 @@ export default function UpstreamRatioSync(props) {
}
};
// 测试自定义渠道
const testCustomChannel = async () => {
if (!customUrl) {
showWarning(t('请输入渠道地址'));
return false;
}
setCustomChannelTesting(true);
try {
const url = buildEndpointUrl(customUrl, customEndpoint);
const client = { timeout: 10000 };
const response = await fetch(url, {
method: 'GET',
signal: AbortSignal.timeout(client.timeout)
});
if (response.ok) {
const data = await response.json();
if (data.success) {
return true;
} else {
showError(t('测试失败') + `: ${data.message || t('响应格式错误')}`);
return false;
}
} else {
showError(t('测试失败') + `: HTTP ${response.status}`);
return false;
}
} catch (error) {
showError(t('测试失败') + `: ${error.message || t('请求超时')}`);
return false;
} finally {
setCustomChannelTesting(false);
}
};
// 添加自定义渠道
const addCustomChannel = async () => {
if (!customUrl) {
showWarning(t('请输入渠道地址'));
return;
}
// 先测试渠道
const testResult = await testCustomChannel();
if (!testResult) {
return;
}
let hostname;
try {
hostname = new URL(customUrl).hostname;
} catch (e) {
hostname = customUrl;
}
const customId = `custom_${Date.now()}`;
const newChannel = {
key: customId,
label: hostname,
value: customId,
disabled: false,
_originalData: {
id: customId,
name: hostname,
base_url: customUrl.endsWith('/') ? customUrl.slice(0, -1) : customUrl,
status: 1,
is_custom: true,
},
};
setAllChannels([...allChannels, newChannel]);
setSelectedChannelIds([...selectedChannelIds, customId]);
setChannelEndpoints(prev => ({ ...prev, [customId]: customEndpoint }));
setCustomUrl('');
showSuccess(t('测试成功,渠道添加成功'));
};
// 确认选择渠道
const confirmChannelSelection = () => {
const selected = allChannels
@@ -193,18 +105,9 @@ export default function UpstreamRatioSync(props) {
const fetchRatiosFromChannels = async (channelList) => {
setSyncLoading(true);
// 分离数据库渠道和自定义渠道
const dbChannels = channelList.filter(ch => !ch.is_custom);
const customChannels = channelList.filter(ch => ch.is_custom);
const payload = {
channel_ids: dbChannels.map(ch => parseInt(ch.id)),
custom_channels: customChannels.map(ch => ({
name: ch.name,
base_url: ch.base_url,
endpoint: channelEndpoints[ch.id] || DEFAULT_ENDPOINT,
})),
timeout: 10
channel_ids: channelList.map(ch => parseInt(ch.id)),
timeout: 10,
};
try {
@@ -391,12 +294,10 @@ export default function UpstreamRatioSync(props) {
title: t('模型'),
dataIndex: 'model',
fixed: 'left',
width: 160,
},
{
title: t('倍率类型'),
dataIndex: 'ratioType',
width: 140,
render: (text) => {
const typeMap = {
model_ratio: t('模型倍率'),
@@ -410,7 +311,6 @@ export default function UpstreamRatioSync(props) {
{
title: t('当前值'),
dataIndex: 'current',
width: 100,
render: (text) => (
<Tag color={text !== null && text !== undefined ? 'blue' : 'default'} shape="circle">
{text !== null && text !== undefined ? text : t('未设置')}
@@ -486,7 +386,6 @@ export default function UpstreamRatioSync(props) {
<span>{upName}</span>
),
dataIndex: upName,
width: 140,
render: (_, record) => {
const upstreamVal = record.upstreams?.[upName];
@@ -582,12 +481,6 @@ export default function UpstreamRatioSync(props) {
allChannels={allChannels}
selectedChannelIds={selectedChannelIds}
setSelectedChannelIds={setSelectedChannelIds}
customUrl={customUrl}
setCustomUrl={setCustomUrl}
customEndpoint={customEndpoint}
setCustomEndpoint={setCustomEndpoint}
customChannelTesting={customChannelTesting}
addCustomChannel={addCustomChannel}
channelEndpoints={channelEndpoints}
updateChannelEndpoint={updateChannelEndpoint}
/>