From c974b1053c126960b30a91c4db30e0fbf5db44c4 Mon Sep 17 00:00:00 2001 From: t0ng7u Date: Tue, 24 Jun 2025 00:25:29 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(channel):=20remove=20duplica?= =?UTF-8?q?te=20model=20names=20in=20=E2=80=9CEdit=20Channel=E2=80=9D=20mo?= =?UTF-8?q?del=20dropdown=20(#1292)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Unify the Select option structure as `{ key, label, value }`; add missing `key` to prevent duplicated rendering by Semi-UI. • Trim and deduplicate the `models` array via `Set` inside `handleInputChange`, ensuring state always contains unique values. • In the options-merging `useEffect`, use a `Map` keyed by `value` (after `trim`) to guarantee a unique `optionList` when combining backend data with currently selected models. • Apply the same structure and de-duplication when: – Fetching models from `/api/channel/models` – Adding custom models (`addCustomModels`) – Fetching upstream model lists (`fetchUpstreamModelList`) • Replace obsolete `text` field with `label` in custom option objects for consistency. No backend changes are required; the fix is entirely front-end. Closes #1292 --- web/src/pages/Channel/EditChannel.js | 36 ++++++++++++++++++---------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/web/src/pages/Channel/EditChannel.js b/web/src/pages/Channel/EditChannel.js index 2e8baddf..178902a1 100644 --- a/web/src/pages/Channel/EditChannel.js +++ b/web/src/pages/Channel/EditChannel.js @@ -111,6 +111,10 @@ const EditChannel = (props) => { const [modalImageUrl, setModalImageUrl] = useState(''); const [isModalOpenurl, setIsModalOpenurl] = useState(false); const handleInputChange = (name, value) => { + if (name === 'models' && Array.isArray(value)) { + value = Array.from(new Set(value.map((m) => (m || '').trim()))); + } + if (name === 'base_url' && value.endsWith('/v1')) { Modal.confirm({ title: '警告', @@ -265,10 +269,14 @@ const EditChannel = (props) => { const fetchModels = async () => { try { let res = await API.get(`/api/channel/models`); - let localModelOptions = res.data.data.map((model) => ({ - label: model.id, - value: model.id, - })); + const localModelOptions = res.data.data.map((model) => { + const id = (model.id || '').trim(); + return { + key: id, + label: id, + value: id, + }; + }); setOriginModelOptions(localModelOptions); setFullModels(res.data.data.map((model) => model.id)); setBasicModels( @@ -301,20 +309,22 @@ const EditChannel = (props) => { }; useEffect(() => { - // 使用 Map 来避免重复,以 value 为键 const modelMap = new Map(); - // 先添加原始模型选项 originModelOptions.forEach(option => { - modelMap.set(option.value, option); + const v = (option.value || '').trim(); + if (!modelMap.has(v)) { + modelMap.set(v, option); + } }); - // 再添加当前选中的模型(如果不存在) inputs.models.forEach(model => { - if (!modelMap.has(model)) { - modelMap.set(model, { - label: model, - value: model, + const v = (model || '').trim(); + if (!modelMap.has(v)) { + modelMap.set(v, { + key: v, + label: v, + value: v, }); } }); @@ -403,7 +413,7 @@ const EditChannel = (props) => { localModels.push(model); localModelOptions.push({ key: model, - text: model, + label: model, value: model, }); addedModels.push(model);