| @@ -75,7 +75,6 @@ export const OptimizedSettingsPanel = React.memo( | |||
| JSON.stringify(prevProps.previewPayload) === | |||
| JSON.stringify(nextProps.previewPayload) && | |||
| JSON.stringify(prevProps.messages) === JSON.stringify(nextProps.messages) && | |||
| JSON.stringify(prevProps.channels) === JSON.stringify(nextProps.channels) && | |||
| prevProps.mutualExclusive === nextProps.mutualExclusive | |||
| ); | |||
| }, | |||
| @@ -46,7 +46,6 @@ const SettingsPanel = ({ | |||
| onCustomRequestBodyChange, | |||
| previewPayload, | |||
| messages, | |||
| channels = [], | |||
| }) => { | |||
| const { t } = useTranslation(); | |||
| @@ -179,38 +178,6 @@ const SettingsPanel = ({ | |||
| /> | |||
| </div> | |||
| {/* 通道选择 */} | |||
| <div className={customRequestMode ? 'opacity-50' : ''}> | |||
| <div className='flex items-center gap-2 mb-2'> | |||
| <Typography.Text strong className='text-sm'> | |||
| {t('通道')} | |||
| </Typography.Text> | |||
| {customRequestMode && ( | |||
| <Typography.Text className='text-xs text-orange-600'> | |||
| ({t('已在自定义模式中忽略')}) | |||
| </Typography.Text> | |||
| )} | |||
| </div> | |||
| <Select | |||
| placeholder={t('请选择通道')} | |||
| name='channelId' | |||
| selection | |||
| filter={selectFilter} | |||
| autoClearSearchValue={false} | |||
| onChange={(value) => onInputChange('channelId', value)} | |||
| value={inputs.channelId} | |||
| autoComplete='new-password' | |||
| optionList={channels.map((ch) => ({ | |||
| value: ch.id, | |||
| label: ch.public_name || ch.name, | |||
| }))} | |||
| style={{ width: '100%' }} | |||
| dropdownStyle={{ width: '100%', maxWidth: '100%' }} | |||
| className='!rounded-lg' | |||
| disabled={customRequestMode || channels.length === 0} | |||
| /> | |||
| </div> | |||
| {/* 图片URL输入 */} | |||
| <div className={customRequestMode ? 'opacity-50' : ''}> | |||
| <ImageUrlInput | |||
| @@ -103,7 +103,6 @@ const ChannelPricingCard = ({ | |||
| hasCustomPricing: item.has_custom_pricing, | |||
| cacheRatio: item.cache_ratio, | |||
| cacheCreationRatio: item.cache_creation_ratio, | |||
| isDefault: item.is_default || false, | |||
| userRatio: item.user_ratio ?? 1.0, | |||
| })); | |||
| @@ -147,11 +146,6 @@ const ChannelPricingCard = ({ | |||
| {tag.name} | |||
| </Tag> | |||
| ))} | |||
| {record.isDefault && ( | |||
| <Tag color='amber' size='small' shape='circle'> | |||
| {t('默认')} | |||
| </Tag> | |||
| )} | |||
| </div> | |||
| ), | |||
| }, | |||
| @@ -298,18 +298,6 @@ const PricingCardView = ({ | |||
| {/* 标签区域 */} | |||
| {renderTags(model)} | |||
| {/* 默认通道标识 */} | |||
| {model.default_channel_name && ( | |||
| <Tag | |||
| color='amber' | |||
| size='small' | |||
| shape='circle' | |||
| style={{ marginTop: 4 }} | |||
| > | |||
| {t('默认')}: {model.default_channel_name} | |||
| </Tag> | |||
| )} | |||
| {/* 去体验按钮 */} | |||
| {showTryButton && ( | |||
| <Button | |||
| @@ -64,7 +64,6 @@ const EditTokenModal = (props) => { | |||
| const formApiRef = useRef(null); | |||
| const [models, setModels] = useState([]); | |||
| const [groups, setGroups] = useState([]); | |||
| const [channels, setChannels] = useState([]); | |||
| const isEdit = props.editingToken.id !== undefined; | |||
| const getInitValues = () => ({ | |||
| @@ -152,22 +151,6 @@ const EditTokenModal = (props) => { | |||
| } | |||
| }; | |||
| const loadChannels = async () => { | |||
| let res = await API.get(`/api/user/channels`); | |||
| const { success, message, data } = res.data; | |||
| if (success) { | |||
| let localChannelOptions = (data || []).map((channel) => ({ | |||
| label: channel.remark | |||
| ? `${channel.name} (${channel.remark})` | |||
| : channel.name, | |||
| value: channel.id, | |||
| })); | |||
| setChannels(localChannelOptions); | |||
| } else { | |||
| showError(t(message)); | |||
| } | |||
| }; | |||
| const loadToken = async () => { | |||
| setLoading(true); | |||
| let res = await API.get(`/api/token/${props.editingToken.id}`); | |||
| @@ -198,7 +181,6 @@ const EditTokenModal = (props) => { | |||
| } | |||
| loadModels(); | |||
| loadGroups(); | |||
| loadChannels(); | |||
| }, [props.editingToken.id]); | |||
| useEffect(() => { | |||
| @@ -85,7 +85,6 @@ export const DEFAULT_CONFIG = { | |||
| inputs: { | |||
| model: 'gpt-4o', | |||
| group: '', | |||
| channelId: 0, | |||
| temperature: 0.7, | |||
| top_p: 1, | |||
| max_tokens: 4096, | |||
| @@ -401,14 +401,6 @@ export const channelPricingApi = { | |||
| // 复制全局定价 | |||
| copyGlobal: (channelId, overwrite = false) => | |||
| API.post(`/api/channel_pricing/copy_global/${channelId}`, { overwrite }), | |||
| // 设置默认通道 | |||
| setDefault: (modelName, channelId) => | |||
| API.post('/api/channel_pricing/set_default', { model_name: modelName, channel_id: channelId }), | |||
| // 清除默认通道 | |||
| clearDefault: (modelName) => | |||
| API.delete(`/api/channel_pricing/default/${encodeURIComponent(modelName)}`), | |||
| }; | |||
| // 定价标签 API | |||
| @@ -83,7 +83,6 @@ export const usePlaygroundState = () => { | |||
| const [showSettings, setShowSettings] = useState(false); | |||
| const [models, setModels] = useState([]); | |||
| const [groups, setGroups] = useState([]); | |||
| const [channels, setChannels] = useState([]); | |||
| const [status, setStatus] = useState({}); | |||
| // 消息相关状态 - 使用加载的消息或默认消息初始化 | |||
| @@ -353,8 +352,6 @@ export const usePlaygroundState = () => { | |||
| setShowSettings, | |||
| setModels, | |||
| setGroups, | |||
| channels, | |||
| setChannels, | |||
| setStatus, | |||
| setMessage, | |||
| setDebugData, | |||
| @@ -113,8 +113,6 @@ const Playground = () => { | |||
| setShowSettings, | |||
| setModels, | |||
| setGroups, | |||
| channels, | |||
| setChannels, | |||
| setStatus, | |||
| setMessage, | |||
| setDebugData, | |||
| @@ -137,37 +135,6 @@ const Playground = () => { | |||
| // 数据加载 | |||
| useDataLoader(userState, inputs, handleInputChange, setModels, setGroups, searchParams); | |||
| // Load channels for the selected model | |||
| useEffect(() => { | |||
| if (!inputs.model) { | |||
| setChannels([]); | |||
| return; | |||
| } | |||
| let cancelled = false; | |||
| const loadChannels = async () => { | |||
| try { | |||
| const res = await API.get( | |||
| `/api/user/model_channels?model=${encodeURIComponent(inputs.model)}` | |||
| ); | |||
| if (cancelled) return; | |||
| const { success, data } = res.data; | |||
| if (success && data) { | |||
| const channelList = data.channels || []; | |||
| setChannels(channelList); | |||
| const channelId = (data.default_channel_id && data.default_channel_id > 0) | |||
| ? data.default_channel_id | |||
| : (channelList.length > 0 ? channelList[0].id : 0); | |||
| if (channelId !== inputs.channelId) { | |||
| handleInputChange('channelId', channelId); | |||
| } | |||
| } | |||
| } catch { | |||
| setChannels([]); | |||
| } | |||
| }; | |||
| loadChannels(); | |||
| return () => { cancelled = true; }; | |||
| }, [inputs.model]); | |||
| // 消息编辑 | |||
| const { | |||
| @@ -290,14 +257,10 @@ const Playground = () => { | |||
| // 自定义请求体也通过 header 传递网关字段 | |||
| const customHeaders = {}; | |||
| if (inputs.channelId && inputs.channelId > 0) { | |||
| customHeaders['X-Channel-Id'] = String(inputs.channelId); | |||
| } | |||
| if (customPayload.group) { | |||
| customHeaders['X-Group'] = customPayload.group; | |||
| delete customPayload.group; | |||
| } | |||
| delete customPayload.channel_id; | |||
| sendRequest(customPayload, customPayload.stream !== false, customHeaders); | |||
| // 发送消息后保存,传入新消息列表 | |||
| @@ -335,14 +298,10 @@ const Playground = () => { | |||
| parameterEnabled, | |||
| ); | |||
| const extraHeaders = {}; | |||
| if (inputs.channelId && inputs.channelId > 0) { | |||
| extraHeaders['X-Channel-Id'] = String(inputs.channelId); | |||
| } | |||
| if (payload.group) { | |||
| extraHeaders['X-Group'] = payload.group; | |||
| delete payload.group; | |||
| } | |||
| delete payload.channel_id; | |||
| sendRequest(payload, inputs.stream, extraHeaders); | |||
| // 禁用图片模式 | |||
| @@ -533,7 +492,6 @@ const Playground = () => { | |||
| parameterEnabled={parameterEnabled} | |||
| models={models} | |||
| groups={groups} | |||
| channels={channels} | |||
| styleState={styleState} | |||
| showSettings={showSettings} | |||
| showDebugPanel={showDebugPanel} | |||
| @@ -99,7 +99,6 @@ const CONTEXT_KEY_PRESETS = [ | |||
| { key: 'username', label: 'username' }, | |||
| { key: 'user_group', label: 'user_group' }, | |||
| { key: 'user_email', label: 'user_email' }, | |||
| { key: 'specific_channel_id', label: 'specific_channel_id' }, | |||
| ]; | |||
| const RULES_JSON_PLACEHOLDER = `[ | |||
| @@ -33,7 +33,6 @@ import { | |||
| RadioGroup, | |||
| Radio, | |||
| TreeSelect, | |||
| Tooltip, | |||
| } from '@douyinfe/semi-ui'; | |||
| import { | |||
| IconEdit, | |||
| @@ -41,7 +40,6 @@ import { | |||
| IconChevronDown, | |||
| IconChevronRight, | |||
| IconSearch, | |||
| IconStar, | |||
| } from '@douyinfe/semi-icons'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| import { channelPricingApi } from '../../../helpers/api'; | |||
| @@ -317,43 +315,6 @@ const ChannelPricingView = ({ channels, channelPricings, tags, onRefresh }) => { | |||
| )); | |||
| }, | |||
| }, | |||
| { | |||
| title: t('默认'), | |||
| key: 'isDefault', | |||
| width: 70, | |||
| render: (_, record) => { | |||
| const isDefault = record.pricing?.is_default === true; | |||
| return ( | |||
| <Tooltip content={isDefault ? t('此为该模型的默认通道') : t('设为默认通道')}> | |||
| <div className="flex items-center gap-1"> | |||
| <Button | |||
| size="small" | |||
| type={isDefault ? 'warning' : 'tertiary'} | |||
| icon={<IconStar />} | |||
| onClick={async () => { | |||
| try { | |||
| const res = isDefault | |||
| ? await channelPricingApi.clearDefault(record.modelName) | |||
| : await channelPricingApi.setDefault(record.modelName, record.channelId); | |||
| if (res.data?.success === false) { | |||
| showError(res.data.message || t('操作失败')); | |||
| return; | |||
| } | |||
| showSuccess(isDefault ? t('已取消默认通道') : t('已设为默认通道')); | |||
| onRefresh(); | |||
| } catch (e) { | |||
| showError(e); | |||
| } | |||
| }} | |||
| /> | |||
| {isDefault && ( | |||
| <span className="text-xs text-amber-500 font-medium">{t('默认')}</span> | |||
| )} | |||
| </div> | |||
| </Tooltip> | |||
| ); | |||
| }, | |||
| }, | |||
| { | |||
| title: t('操作'), | |||
| key: 'action', | |||