Просмотр исходного кода

🐛 fix(channel): remove duplicate model names in “Edit Channel” model dropdown (#1292)

• 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
t0ng7u 8 месяцев назад
Родитель
Сommit
c974b1053c
1 измененных файлов с 23 добавлено и 13 удалено
  1. 23 13
      web/src/pages/Channel/EditChannel.js

+ 23 - 13
web/src/pages/Channel/EditChannel.js

@@ -111,6 +111,10 @@ const EditChannel = (props) => {
   const [modalImageUrl, setModalImageUrl] = useState('');
   const [modalImageUrl, setModalImageUrl] = useState('');
   const [isModalOpenurl, setIsModalOpenurl] = useState(false);
   const [isModalOpenurl, setIsModalOpenurl] = useState(false);
   const handleInputChange = (name, value) => {
   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')) {
     if (name === 'base_url' && value.endsWith('/v1')) {
       Modal.confirm({
       Modal.confirm({
         title: '警告',
         title: '警告',
@@ -265,10 +269,14 @@ const EditChannel = (props) => {
   const fetchModels = async () => {
   const fetchModels = async () => {
     try {
     try {
       let res = await API.get(`/api/channel/models`);
       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);
       setOriginModelOptions(localModelOptions);
       setFullModels(res.data.data.map((model) => model.id));
       setFullModels(res.data.data.map((model) => model.id));
       setBasicModels(
       setBasicModels(
@@ -301,20 +309,22 @@ const EditChannel = (props) => {
   };
   };
 
 
   useEffect(() => {
   useEffect(() => {
-    // 使用 Map 来避免重复,以 value 为键
     const modelMap = new Map();
     const modelMap = new Map();
 
 
-    // 先添加原始模型选项
     originModelOptions.forEach(option => {
     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 => {
     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);
         localModels.push(model);
         localModelOptions.push({
         localModelOptions.push({
           key: model,
           key: model,
-          text: model,
+          label: model,
           value: model,
           value: model,
         });
         });
         addedModels.push(model);
         addedModels.push(model);