🗑️ 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:
@@ -66,7 +66,6 @@ func FetchUpstreamRatios(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
upstreams = append(upstreams, req.CustomChannels...)
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
ch := make(chan upstreamResult, len(upstreams))
|
ch := make(chan upstreamResult, len(upstreams))
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ import {
|
|||||||
Modal,
|
Modal,
|
||||||
Transfer,
|
Transfer,
|
||||||
Input,
|
Input,
|
||||||
Card,
|
|
||||||
Space,
|
Space,
|
||||||
Button,
|
|
||||||
Checkbox,
|
Checkbox,
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
import { IconPlus, IconClose } from '@douyinfe/semi-icons';
|
import { IconClose } from '@douyinfe/semi-icons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ChannelSelectorModal
|
* ChannelSelectorModal
|
||||||
@@ -20,21 +18,13 @@ export default function ChannelSelectorModal({
|
|||||||
visible,
|
visible,
|
||||||
onCancel,
|
onCancel,
|
||||||
onOk,
|
onOk,
|
||||||
// 渠道与选择
|
// 渠道选择
|
||||||
allChannels = [],
|
allChannels = [],
|
||||||
selectedChannelIds = [],
|
selectedChannelIds = [],
|
||||||
setSelectedChannelIds,
|
setSelectedChannelIds,
|
||||||
// 自定义渠道
|
|
||||||
customUrl,
|
|
||||||
setCustomUrl,
|
|
||||||
customEndpoint,
|
|
||||||
setCustomEndpoint,
|
|
||||||
customChannelTesting,
|
|
||||||
addCustomChannel,
|
|
||||||
// 渠道端点
|
// 渠道端点
|
||||||
channelEndpoints,
|
channelEndpoints,
|
||||||
updateChannelEndpoint,
|
updateChannelEndpoint,
|
||||||
// 测试相关
|
|
||||||
}) {
|
}) {
|
||||||
// Transfer 自定义渲染
|
// Transfer 自定义渲染
|
||||||
const renderSourceItem = (item) => {
|
const renderSourceItem = (item) => {
|
||||||
@@ -107,32 +97,6 @@ export default function ChannelSelectorModal({
|
|||||||
width={1000}
|
width={1000}
|
||||||
>
|
>
|
||||||
<Space vertical style={{ width: '100%' }}>
|
<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
|
<Transfer
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
dataSource={allChannels}
|
dataSource={allChannels}
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
export const ITEMS_PER_PAGE = 10; // this value must keep same as the one defined in backend!
|
export const ITEMS_PER_PAGE = 10; // this value must keep same as the one defined in backend!
|
||||||
|
|
||||||
|
export const DEFAULT_ENDPOINT = '/api/ratio_config';
|
||||||
@@ -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}`;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -11,11 +11,8 @@ import {
|
|||||||
RefreshCcw,
|
RefreshCcw,
|
||||||
CheckSquare,
|
CheckSquare,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import {
|
|
||||||
DEFAULT_ENDPOINT,
|
|
||||||
buildEndpointUrl,
|
|
||||||
} from '../../../helpers/ratio';
|
|
||||||
import { API, showError, showSuccess, showWarning } from '../../../helpers';
|
import { API, showError, showSuccess, showWarning } from '../../../helpers';
|
||||||
|
import { DEFAULT_ENDPOINT } from '../../../constants';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
IllustrationNoResult,
|
IllustrationNoResult,
|
||||||
@@ -33,11 +30,6 @@ export default function UpstreamRatioSync(props) {
|
|||||||
const [allChannels, setAllChannels] = useState([]);
|
const [allChannels, setAllChannels] = useState([]);
|
||||||
const [selectedChannelIds, setSelectedChannelIds] = 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 }
|
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 confirmChannelSelection = () => {
|
||||||
const selected = allChannels
|
const selected = allChannels
|
||||||
@@ -193,18 +105,9 @@ export default function UpstreamRatioSync(props) {
|
|||||||
const fetchRatiosFromChannels = async (channelList) => {
|
const fetchRatiosFromChannels = async (channelList) => {
|
||||||
setSyncLoading(true);
|
setSyncLoading(true);
|
||||||
|
|
||||||
// 分离数据库渠道和自定义渠道
|
|
||||||
const dbChannels = channelList.filter(ch => !ch.is_custom);
|
|
||||||
const customChannels = channelList.filter(ch => ch.is_custom);
|
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
channel_ids: dbChannels.map(ch => parseInt(ch.id)),
|
channel_ids: channelList.map(ch => parseInt(ch.id)),
|
||||||
custom_channels: customChannels.map(ch => ({
|
timeout: 10,
|
||||||
name: ch.name,
|
|
||||||
base_url: ch.base_url,
|
|
||||||
endpoint: channelEndpoints[ch.id] || DEFAULT_ENDPOINT,
|
|
||||||
})),
|
|
||||||
timeout: 10
|
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -391,12 +294,10 @@ export default function UpstreamRatioSync(props) {
|
|||||||
title: t('模型'),
|
title: t('模型'),
|
||||||
dataIndex: 'model',
|
dataIndex: 'model',
|
||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
width: 160,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('倍率类型'),
|
title: t('倍率类型'),
|
||||||
dataIndex: 'ratioType',
|
dataIndex: 'ratioType',
|
||||||
width: 140,
|
|
||||||
render: (text) => {
|
render: (text) => {
|
||||||
const typeMap = {
|
const typeMap = {
|
||||||
model_ratio: t('模型倍率'),
|
model_ratio: t('模型倍率'),
|
||||||
@@ -410,7 +311,6 @@ export default function UpstreamRatioSync(props) {
|
|||||||
{
|
{
|
||||||
title: t('当前值'),
|
title: t('当前值'),
|
||||||
dataIndex: 'current',
|
dataIndex: 'current',
|
||||||
width: 100,
|
|
||||||
render: (text) => (
|
render: (text) => (
|
||||||
<Tag color={text !== null && text !== undefined ? 'blue' : 'default'} shape="circle">
|
<Tag color={text !== null && text !== undefined ? 'blue' : 'default'} shape="circle">
|
||||||
{text !== null && text !== undefined ? text : t('未设置')}
|
{text !== null && text !== undefined ? text : t('未设置')}
|
||||||
@@ -486,7 +386,6 @@ export default function UpstreamRatioSync(props) {
|
|||||||
<span>{upName}</span>
|
<span>{upName}</span>
|
||||||
),
|
),
|
||||||
dataIndex: upName,
|
dataIndex: upName,
|
||||||
width: 140,
|
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
const upstreamVal = record.upstreams?.[upName];
|
const upstreamVal = record.upstreams?.[upName];
|
||||||
|
|
||||||
@@ -582,12 +481,6 @@ export default function UpstreamRatioSync(props) {
|
|||||||
allChannels={allChannels}
|
allChannels={allChannels}
|
||||||
selectedChannelIds={selectedChannelIds}
|
selectedChannelIds={selectedChannelIds}
|
||||||
setSelectedChannelIds={setSelectedChannelIds}
|
setSelectedChannelIds={setSelectedChannelIds}
|
||||||
customUrl={customUrl}
|
|
||||||
setCustomUrl={setCustomUrl}
|
|
||||||
customEndpoint={customEndpoint}
|
|
||||||
setCustomEndpoint={setCustomEndpoint}
|
|
||||||
customChannelTesting={customChannelTesting}
|
|
||||||
addCustomChannel={addCustomChannel}
|
|
||||||
channelEndpoints={channelEndpoints}
|
channelEndpoints={channelEndpoints}
|
||||||
updateChannelEndpoint={updateChannelEndpoint}
|
updateChannelEndpoint={updateChannelEndpoint}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user