feat: add duplicate key removal function when edit or add new channel - #1683
feat: add duplicate key removal function when edit or add new channel#1683HynoR wants to merge 5 commits into
Conversation
WalkthroughAdded a deduplicateKeys helper and a “密钥去重” button in EditChannelModal to remove duplicate newline-separated keys (preserving order), update form/state, and display success/info messages. The button is shown only when Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Modal as EditChannelModal
participant Form as Form State
participant Msg as Message UI
rect rgba(230,245,255,0.5)
User->>Modal: Click "密钥去重" button
Modal->>Form: Read current key field (or local input)
Modal->>Modal: Split by newline, trim lines, deduplicate (preserve order)
alt Duplicates removed
Modal->>Form: Update key field and internal state with unique lines
Modal->>Msg: Show success message with before/after counts
else No duplicates
Modal->>Msg: Show info message (no duplicates found)
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)
875-921: Dedup logic works; tighten normalization and avoid redundant state writes
- Normalize CRLF and only update when there’s an actual change.
- Rely on handleInputChange once to prevent double form/state writes.
- Optional: extract the routine to a helper for unit testing.
// 密钥去重函数 const deduplicateKeys = () => { const currentKey = formApiRef.current?.getValue('key') || inputs.key || ''; if (!currentKey.trim()) { showInfo(t('请先输入密钥')); return; } - // 按行分割密钥 - const keyLines = currentKey.split('\n'); + // 按行分割密钥(兼容 CRLF) + const keyLines = currentKey.split(/\r?\n/); const beforeCount = keyLines.length; // 使用哈希表去重,保持原有顺序 const keySet = new Set(); const deduplicatedKeys = []; keyLines.forEach(line => { const trimmedLine = line.trim(); if (trimmedLine && !keySet.has(trimmedLine)) { keySet.add(trimmedLine); deduplicatedKeys.push(trimmedLine); } }); const afterCount = deduplicatedKeys.length; const deduplicatedKeyText = deduplicatedKeys.join('\n'); - // 更新表单和状态 - if (formApiRef.current) { - formApiRef.current.setValue('key', deduplicatedKeyText); - } - handleInputChange('key', deduplicatedKeyText); + // 仅在有变化时更新 + if (beforeCount !== afterCount) { + handleInputChange('key', deduplicatedKeyText); + } // 显示去重结果 const message = t('去重完成:去重前 {{before}} 个密钥,去重后 {{after}} 个密钥', { before: beforeCount, after: afterCount }); if (beforeCount === afterCount) { showInfo(t('未发现重复密钥')); } else { showSuccess(message); } };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
web/src/components/table/channels/modals/EditChannelModal.jsx(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
PR: QuantumNous/new-api#1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the database stores mapped keys (display names) in the models field after applying model mapping transformations. When loading a channel, data.models contains the mapped keys, not the original model names. The filtering logic if (data.models.includes(key)) in the initialization is correct.
Applied to files:
web/src/components/table/channels/modals/EditChannelModal.jsx
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
PR: QuantumNous/new-api#1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the applyModelMapping function transforms the models list by replacing original model names (mapping values) with display names (mapping keys). The database stores this transformed list containing mapped keys. On channel load, data.models contains these mapped display names, making the initialization filter if (data.models.includes(key)) correct.
Applied to files:
web/src/components/table/channels/modals/EditChannelModal.jsx
🧬 Code graph analysis (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (2)
web/src/components/table/channels/modals/EditTagModal.jsx (3)
formApiRef(74-74)inputs(73-73)handleInputChange(77-129)web/src/helpers/utils.jsx (2)
showInfo(152-154)showSuccess(148-150)
🔇 Additional comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)
1222-1222: LGTM: flex-wrap improves responsiveness of extra actionsWrapping prevents overflow for long button groups on small viewports.
…ionally render deduplicate button
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)
1015-1042: Gated 去重 for type 41 and fixed toggle closure — LGTMThe button visibility and the state toggle now avoid stale closures and no-op UI. Looks correct.
🧹 Nitpick comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)
875-921: Harden newline handling and remove redundant form update in dedup function
- Use a CRLF-tolerant splitter.
handleInputChangealready updates the Form; the explicitsetValueis redundant.- const keyLines = currentKey.split('\n'); + const keyLines = currentKey.split(/\r?\n/); @@ - // 更新表单和状态 - if (formApiRef.current) { - formApiRef.current.setValue('key', deduplicatedKeyText); - } - handleInputChange('key', deduplicatedKeyText); + // 更新表单和状态 + handleInputChange('key', deduplicatedKeyText);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
web/src/components/table/channels/modals/EditChannelModal.jsx(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
PR: QuantumNous/new-api#1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the database stores mapped keys (display names) in the models field after applying model mapping transformations. When loading a channel, data.models contains the mapped keys, not the original model names. The filtering logic if (data.models.includes(key)) in the initialization is correct.
Applied to files:
web/src/components/table/channels/modals/EditChannelModal.jsx
📚 Learning: 2025-08-27T02:15:25.448Z
Learnt from: AAEE86
PR: QuantumNous/new-api#1658
File: web/src/components/table/channels/modals/EditChannelModal.jsx:555-569
Timestamp: 2025-08-27T02:15:25.448Z
Learning: In EditChannelModal.jsx, the applyModelMapping function transforms the models list by replacing original model names (mapping values) with display names (mapping keys). The database stores this transformed list containing mapped keys. On channel load, data.models contains these mapped display names, making the initialization filter if (data.models.includes(key)) correct.
Applied to files:
web/src/components/table/channels/modals/EditChannelModal.jsx
🧬 Code graph analysis (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (3)
web/src/components/table/tokens/modals/EditTokenModal.jsx (1)
formApiRef(62-62)web/src/components/table/channels/modals/EditTagModal.jsx (3)
formApiRef(74-74)inputs(73-73)handleInputChange(77-129)web/src/helpers/utils.jsx (2)
showInfo(152-154)showSuccess(148-150)
🔇 Additional comments (1)
web/src/components/table/channels/modals/EditChannelModal.jsx (1)
1227-1227: Flex-wrap on extraText improves layout — LGTMPrevents button/text overflow in narrow widths.
…nse in stream handler
|
@HynoR 帮忙改一下conflicts🥺 |
fix:修复上游账号为OpenAI API key时Claude Code调用缓存率低的问题
在批量添加 key 的情况下,可以在前端去重重复的密钥

Summary by CodeRabbit