Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions web/src/components/table/channels/modals/EditChannelModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,24 @@ const EditChannelModal = (props) => {
return [];
}
}, [inputs.model_mapping]);
const redirectModelKeyList = useMemo(() => {
const mapping = inputs.model_mapping;
if (typeof mapping !== 'string') return [];
const trimmed = mapping.trim();
if (!trimmed) return [];
try {
const parsed = JSON.parse(trimmed);
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
return [];
}
const keys = Object.keys(parsed)
.map((key) => key.trim())
.filter((key) => key);
return Array.from(new Set(keys));
} catch (error) {
return [];
}
}, [inputs.model_mapping]);
const upstreamDetectedModels = useMemo(
() =>
Array.from(
Expand Down Expand Up @@ -3842,6 +3860,7 @@ const EditChannelModal = (props) => {
models={fetchedModels}
selected={inputs.models}
redirectModels={redirectModelList}
redirectSourceModels={redirectModelKeyList}
onConfirm={(selectedModels) => {
handleInputChange('models', selectedModels);
showSuccess(t('模型列表已更新'));
Expand Down
63 changes: 56 additions & 7 deletions web/src/components/table/channels/modals/ModelSelectModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const ModelSelectModal = ({
models = [],
selected = [],
redirectModels = [],
redirectSourceModels = [],
onConfirm,
onCancel,
}) => {
Expand All @@ -54,6 +55,14 @@ const ModelSelectModal = ({
if (typeof model === 'object' && model.model_name) return model.model_name;
return String(model ?? '');
};
const normalizeModelList = (modelList = []) =>
Array.from(
new Set(
(modelList || [])
.map((model) => getModelName(model).trim())
.filter(Boolean),
),
);

const normalizedSelected = useMemo(
() => (selected || []).map(getModelName),
Expand All @@ -78,6 +87,10 @@ const ModelSelectModal = ({
),
[redirectModels],
);
const normalizedRedirectSourceSet = useMemo(
() => new Set(normalizeModelList(redirectSourceModels)),
[redirectSourceModels],
);
const normalizedSelectedSet = useMemo(() => {
const set = new Set();
(selected || []).forEach((model) => {
Expand Down Expand Up @@ -116,6 +129,16 @@ const ModelSelectModal = ({
const existingModels = filteredModels.filter((model) =>
isExistingModel(model),
);
const fetchedModelSet = useMemo(
() => new Set(normalizeModelList(models)),
[models],
);
const removedModels = normalizeModelList(selected).filter(
(model) =>
!fetchedModelSet.has(model) &&
!normalizedRedirectSourceSet.has(model) &&
model.toLowerCase().includes(keyword.toLowerCase()),
);

// 同步外部选中值
useEffect(() => {
Expand All @@ -127,11 +150,15 @@ const ModelSelectModal = ({
// 当模型列表变化时,设置默认tab
useEffect(() => {
if (visible) {
// 默认显示新获取模型tab,如果没有新模型则显示已有模型
const hasNewModels = newModels.length > 0;
setActiveTab(hasNewModels ? 'new' : 'existing');
if (newModels.length > 0) {
setActiveTab('new');
} else if (removedModels.length > 0) {
setActiveTab('removed');
} else {
setActiveTab('existing');
}
}
}, [visible, newModels.length, selected]);
}, [visible, newModels.length, removedModels.length, selected]);

const handleOk = () => {
onConfirm && onConfirm(checkedList);
Expand Down Expand Up @@ -197,6 +224,14 @@ const ModelSelectModal = ({
},
]
: []),
...(removedModels.length > 0
? [
{
tab: `${t('上游已删除的模型')} (${removedModels.length})`,
itemKey: 'removed',
},
]
: []),
];

// 处理分类全选/取消全选
Expand Down Expand Up @@ -343,9 +378,11 @@ const ModelSelectModal = ({
showClear
/>

<Spin spinning={!models || models.length === 0}>
<Spin
spinning={!models || (models.length === 0 && removedModels.length === 0)}
>
<div style={{ maxHeight: 400, overflowY: 'auto', paddingRight: 8 }}>
{filteredModels.length === 0 ? (
{filteredModels.length === 0 && removedModels.length === 0 ? (
<Empty
image={
<IllustrationNoResult style={{ width: 150, height: 150 }} />
Expand All @@ -369,6 +406,14 @@ const ModelSelectModal = ({
{renderModelsByCategory(existingModelsByCategory, 'existing')}
</div>
)}
{activeTab === 'removed' && removedModels.length > 0 && (
<div>
{renderModelsByCategory(
categorizeModels(removedModels),
'removed',
)}
</div>
)}
</Checkbox.Group>
)}
</div>
Expand All @@ -382,7 +427,11 @@ const ModelSelectModal = ({
<div className='flex items-center justify-end gap-2'>
{(() => {
const currentModels =
activeTab === 'new' ? newModels : existingModels;
activeTab === 'new'
? newModels
: activeTab === 'removed'
? removedModels
: existingModels;
const currentSelected = currentModels.filter((model) =>
checkedList.includes(model),
).length;
Expand Down