Jelajahi Sumber

🐛 fix: preserve key data when editing channels & update MultiKeySize correctly

Backend
• `model/channel.go`
  – On multi-key channel updates, recalculate `MultiKeySize` from the current key list.
  – If the request omits `key`, fetch existing keys from DB to avoid resetting the count to `0/0`.
  – Remove out-of-range entries from `MultiKeyStatusList` to keep data consistent.

Frontend
• `web/src/pages/Channel/EditChannel.js`
  – Vertex AI channels no longer require re-uploading a key file in edit mode.
  – When no new key is provided during editing, exclude the `key` field from the payload to prevent overwriting the stored value.

These changes ensure that editing a channel no longer zeroes out the enabled key counter and that Vertex AI channels can be modified without mandatory key re-submission.
t0ng7u 7 bulan lalu
induk
melakukan
d22ee5d451
2 mengubah file dengan 35 tambahan dan 10 penghapusan
  1. 13 1
      model/channel.go
  2. 22 9
      web/src/pages/Channel/EditChannel.js

+ 13 - 1
model/channel.go

@@ -398,7 +398,19 @@ func (channel *Channel) Insert() error {
 func (channel *Channel) Update() error {
 func (channel *Channel) Update() error {
 	// 如果是多密钥渠道,则根据当前 key 列表重新计算 MultiKeySize,避免编辑密钥后数量未同步
 	// 如果是多密钥渠道,则根据当前 key 列表重新计算 MultiKeySize,避免编辑密钥后数量未同步
 	if channel.ChannelInfo.IsMultiKey {
 	if channel.ChannelInfo.IsMultiKey {
-		keys := channel.getKeys()
+		var keyStr string
+		if channel.Key != "" {
+			keyStr = channel.Key
+		} else {
+			// 如果当前未提供 key,读取数据库中的现有 key
+			if existing, err := GetChannelById(channel.Id, true); err == nil {
+				keyStr = existing.Key
+			}
+		}
+		keys := []string{}
+		if keyStr != "" {
+			keys = strings.Split(strings.Trim(keyStr, "\n"), "\n")
+		}
 		channel.ChannelInfo.MultiKeySize = len(keys)
 		channel.ChannelInfo.MultiKeySize = len(keys)
 		// 清理超过新 key 数量范围的状态数据,防止索引越界
 		// 清理超过新 key 数量范围的状态数据,防止索引越界
 		if channel.ChannelInfo.MultiKeyStatusList != nil {
 		if channel.ChannelInfo.MultiKeyStatusList != nil {

+ 22 - 9
web/src/pages/Channel/EditChannel.js

@@ -441,8 +441,9 @@ const EditChannel = (props) => {
 
 
     if (localInputs.type === 41) {
     if (localInputs.type === 41) {
       let keys = vertexKeys;
       let keys = vertexKeys;
-      if (keys.length === 0) {
-        // 确保提交时也能解析,避免因异步延迟导致 keys 为空
+
+      // 若当前未选择文件,尝试从已上传文件列表解析(异步读取)
+      if (keys.length === 0 && vertexFileList.length > 0) {
         try {
         try {
           const parsed = await Promise.all(
           const parsed = await Promise.all(
             vertexFileList.map(async (item) => {
             vertexFileList.map(async (item) => {
@@ -459,17 +460,29 @@ const EditChannel = (props) => {
         }
         }
       }
       }
 
 
+      // 创建模式必须上传密钥;编辑模式可选
       if (keys.length === 0) {
       if (keys.length === 0) {
-        showInfo(t('请上传密钥文件!'));
-        return;
-      }
-
-      if (batch) {
-        localInputs.key = JSON.stringify(keys);
+        if (!isEdit) {
+          showInfo(t('请上传密钥文件!'));
+          return;
+        } else {
+          // 编辑模式且未上传新密钥,不修改 key
+          delete localInputs.key;
+        }
       } else {
       } else {
-        localInputs.key = JSON.stringify(keys[0]);
+        // 有新密钥,则覆盖
+        if (batch) {
+          localInputs.key = JSON.stringify(keys);
+        } else {
+          localInputs.key = JSON.stringify(keys[0]);
+        }
       }
       }
     }
     }
+
+    // 如果是编辑模式且 key 为空字符串,避免提交空值覆盖旧密钥
+    if (isEdit && (!localInputs.key || localInputs.key.trim() === '')) {
+      delete localInputs.key;
+    }
     delete localInputs.vertex_files;
     delete localInputs.vertex_files;
 
 
     if (!isEdit && (!localInputs.name || !localInputs.key)) {
     if (!isEdit && (!localInputs.name || !localInputs.key)) {