Skip to content

feat: add multi-key management - #1498

Merged
Calcium-Ion merged 4 commits into
alphafrom
multi-key-manage
Aug 4, 2025
Merged

feat: add multi-key management#1498
Calcium-Ion merged 4 commits into
alphafrom
multi-key-manage

Conversation

@Calcium-Ion

@Calcium-Ion Calcium-Ion commented Aug 4, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Added a multi-key management modal for channels, enabling users to view, enable, disable, and delete keys with detailed status, reasons, and timestamps.
    • Introduced a new API endpoint for managing keys in multi-key channels, supporting status retrieval, individual and bulk key enable/disable, and deletion of auto-disabled keys.
  • Improvements

    • Updated channel table controls for unified enable/disable and edit actions, with direct access to multi-key management for relevant channels.
  • Bug Fixes

    • Ensured channel info resets key disable reasons and timestamps correctly in API responses.
  • User Interface

    • Enhanced channel management table and modals for clearer multi-key channel operations and better usability.

@coderabbitai

coderabbitai Bot commented Aug 4, 2025

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

This update introduces comprehensive multi-key management for channels in both backend and frontend. The backend adds new API endpoints, data structures, and logic for managing multiple keys per channel, including enabling, disabling, and deleting keys, as well as tracking reasons and timestamps for key status changes. The frontend incorporates a new modal interface for multi-key management, updates table components to support modal control, and extends hooks and state management accordingly.

Changes

Cohort / File(s) Change Summary
Backend: Multi-Key Management API & Logic
controller/channel.go, model/channel.go, model/channel_cache.go
Added helper to clear multi-key info, new API endpoint (ManageMultiKeys) for key management actions, and supporting request/response types. Enhanced channel structs with fields for multi-key settings, reasons, and timestamps. Exported GetKeys. Updated multi-key update logic to track disable reasons/times. Adjusted cache initialization to use new method name.
Backend: Routing
router/api-router.go
Registered new /channel/multi_key/manage POST route with admin authentication pointing to the new multi-key management handler.
Frontend: Table Columns & Operations
web/src/components/table/channels/ChannelsColumnDefs.js, web/src/components/table/channels/ChannelsTable.jsx
Updated columns and operations to support multi-key management modal. Added props for modal control. Unified enable/disable and edit controls, and provided a dedicated trigger for multi-key management for relevant channels.
Frontend: Channels Table Page
web/src/components/table/channels/index.jsx
Imported and rendered the new MultiKeyManageModal component, wiring it to state and handlers from channels data.
Frontend: Multi-Key Management Modal
web/src/components/table/channels/modals/MultiKeyManageModal.jsx
Added a new modal component for managing multi-key channels, supporting viewing key statuses, enabling/disabling keys, and deleting auto-disabled keys, with pagination and status statistics.
Frontend: State Management Hook
web/src/hooks/channels/useChannelsData.js
Introduced state and setters for controlling the multi-key management modal and current channel, exposing them via the hook's return object.

Sequence Diagram(s)

sequenceDiagram
    participant AdminUser as Admin User
    participant Frontend as Frontend (Channels Table & Modal)
    participant API as Backend API (ManageMultiKeys)
    participant DB as Database

    AdminUser->>Frontend: Click "Multi-key management" on a channel
    Frontend->>API: POST /channel/multi_key/manage (action: get_key_status, channel_id, pagination)
    API->>DB: Fetch channel and key status
    API->>Frontend: Return key statuses, reasons, times, stats

    AdminUser->>Frontend: Click "Disable" or "Enable" on a key
    Frontend->>API: POST /channel/multi_key/manage (action: disable_key/enable_key, channel_id, key_index, reason)
    API->>DB: Update key status, reason, timestamp
    API->>Frontend: Return success/error

    AdminUser->>Frontend: Click "Delete auto-disabled keys"
    Frontend->>API: POST /channel/multi_key/manage (action: delete_disabled_keys, channel_id)
    API->>DB: Remove auto-disabled keys, update channel
    API->>Frontend: Return success/error

    Frontend->>AdminUser: Update modal UI with latest key statuses
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰✨
In a warren of channels, keys multiply,
Now a rabbit can manage with just a sigh—
Enable, disable, reasons in tow,
With modals and tables, the statuses show.
Multi-key magic, all neat and precise,
This hop in the code makes management nice!
🗝️🌱

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e2a04f and 12b4e80.

📒 Files selected for processing (2)
  • controller/channel.go (6 hunks)
  • web/src/components/table/channels/modals/MultiKeyManageModal.jsx (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch multi-key-manage

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 10b0441 and 8357b15.

📒 Files selected for processing (9)
  • controller/channel.go (6 hunks)
  • model/channel.go (8 hunks)
  • model/channel_cache.go (1 hunks)
  • router/api-router.go (1 hunks)
  • web/src/components/table/channels/ChannelsColumnDefs.js (3 hunks)
  • web/src/components/table/channels/ChannelsTable.jsx (3 hunks)
  • web/src/components/table/channels/index.jsx (2 hunks)
  • web/src/components/table/channels/modals/MultiKeyManageModal.jsx (1 hunks)
  • web/src/hooks/channels/useChannelsData.js (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
controller/channel.go (4)
model/channel.go (3)
  • Channel (19-53)
  • ChannelInfo (55-63)
  • GetChannelById (322-337)
common/gin.go (1)
  • ApiError (91-96)
common/utils.go (1)
  • GetTimestamp (192-194)
model/channel_cache.go (1)
  • InitChannelCache (22-87)
router/api-router.go (1)
controller/channel.go (1)
  • ManageMultiKeys (1084-1368)
model/channel.go (2)
constant/multi_key_mode.go (1)
  • MultiKeyMode (3-3)
common/utils.go (1)
  • GetTimestamp (192-194)
web/src/components/table/channels/ChannelsColumnDefs.js (1)
web/src/hooks/channels/useChannelsData.js (1)
  • manageChannel (373-417)
🔇 Additional comments (19)
router/api-router.go (1)

123-123: LGTM!

The new multi-key management route is properly integrated under the existing channel group with appropriate admin authentication middleware. The route follows established naming conventions and patterns.

model/channel_cache.go (1)

73-73: LGTM!

The method call change from getKeys() to GetKeys() correctly updates to use the newly exported method, maintaining the same functionality while enabling cross-package access for multi-key management features.

web/src/components/table/channels/ChannelsTable.jsx (3)

60-62: LGTM!

The new multi-key management props are properly destructured from the input parameters with clear, descriptive names.


85-87: LGTM!

The props are correctly passed to the getChannelsColumns function, enabling the column definitions to access multi-key management functionality.


106-108: LGTM!

The new props are properly included in the dependency array, ensuring the columns will re-render when multi-key management state changes.

web/src/components/table/channels/index.jsx (2)

33-33: LGTM!

The import is properly placed alongside other modal imports, following the established pattern.


58-63: LGTM!

The MultiKeyManageModal is properly integrated with correct props for visibility control, current channel data, and event handlers. The structure follows the existing modal pattern consistently.

web/src/hooks/channels/useChannelsData.js (2)

86-88: LGTM!

The new state variables for multi-key management are properly initialized following React best practices and established naming conventions in the codebase.


892-896: LGTM!

The multi-key management states are correctly added to the hook's return object, making them available to consuming components with proper state and setter access.

web/src/components/table/channels/modals/MultiKeyManageModal.jsx (1)

328-465: Extensive hardcoded Chinese text in modal UI

The modal component has numerous hardcoded Chinese strings that should use internationalization.

Key areas needing translation:

  • Modal title (line 333): '多密钥管理''Multi-key Management'
  • Button labels (lines 342, 348, 361): '关闭''Close', '刷新''Refresh', etc.
  • Confirmation dialogs (lines 352-354)
  • Statistics template (line 376)
  • Multi-key mode labels (line 386): '随机''Random', '轮询''Polling'
  • Pagination text (lines 412-416, 421, 444-446)
  • Empty state messages (lines 458-459)

Example fixes:

-<span>{t('多密钥管理')} - {channel?.name}</span>
+<span>{t('Multi-key Management')} - {channel?.name}</span>

-<Button onClick={onCancel}>{t('关闭')}</Button>
+<Button onClick={onCancel}>{t('Close')}</Button>

-title={t('确定要删除所有已自动禁用的密钥吗?')}
+title={t('Are you sure you want to delete all auto-disabled keys?')}

Likely an incorrect or invalid review comment.

model/channel.go (9)

44-44: LGTM: New Settings field added appropriately.

The addition of the Settings field follows the existing pattern in the Channel struct and supports the multi-key management functionality.


59-60: LGTM: Multi-key tracking fields properly designed.

The new optional fields MultiKeyDisabledReason and MultiKeyDisabledTime are well-designed:

  • Use appropriate data types (map[int]string and map[int]int64)
  • Include omitempty JSON tags to keep responses clean when empty
  • Follow consistent naming conventions with existing fields

76-76: LGTM: Method exported correctly.

The change from getKeys() to GetKeys() properly exports the method to support external usage while maintaining the same functionality.


107-107: LGTM: Method call updated correctly.

The call to the newly exported GetKeys() method is correctly updated.


534-534: LGTM: Function signature enhanced appropriately.

The addition of the reason parameter to handlerMultiKeyUpdate supports the new requirement to track disable reasons.


535-535: LGTM: Method call updated correctly.

The call to the newly exported GetKeys() method is correctly updated.


553-560: LGTM: Disabled key tracking implementation is solid.

The implementation properly:

  • Initializes maps when nil to avoid panics
  • Records both reason and timestamp for disabled keys
  • Uses common.GetTimestamp() for consistent time tracking
  • Only tracks disable information when status is not enabled

The logic is thread-safe within the context of the existing channelStatusLock usage.


583-583: LGTM: Function call updated with reason parameter.

The call to handlerMultiKeyUpdate correctly passes the reason parameter to support the enhanced functionality.


614-614: LGTM: Function call updated with reason parameter.

The call to handlerMultiKeyUpdate correctly passes the reason parameter to support the enhanced functionality.

Comment thread controller/channel.go
Comment on lines +1095 to +1105
"success": false,
"message": "渠道不存在",
})
return
}

if !channel.ChannelInfo.IsMultiKey {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "该渠道不是多密钥模式",
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Hardcoded Chinese error messages

Error messages should use internationalization for consistency.

Apply this diff to fix the error messages:

 if err != nil {
   c.JSON(http.StatusOK, gin.H{
     "success": false,
-    "message": "渠道不存在",
+    "message": "Channel not found",
   })
   return
 }

 if !channel.ChannelInfo.IsMultiKey {
   c.JSON(http.StatusOK, gin.H{
     "success": false,
-    "message": "该渠道不是多密钥模式",
+    "message": "This channel is not in multi-key mode",
   })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"success": false,
"message": "渠道不存在",
})
return
}
if !channel.ChannelInfo.IsMultiKey {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "该渠道不是多密钥模式",
})
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "Channel not found",
})
return
}
if !channel.ChannelInfo.IsMultiKey {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "This channel is not in multi-key mode",
})
}
🤖 Prompt for AI Agents
In controller/channel.go around lines 1095 to 1105, the error messages are
hardcoded in Chinese, which breaks internationalization consistency. Replace the
hardcoded Chinese strings with calls to the internationalization function (e.g.,
i18n.T or similar) to fetch the localized message keys instead of literal
strings. This ensures error messages are properly translated based on user
locale settings.

Comment thread controller/channel.go
Comment on lines +1154 to +1160
case 1:
enabledCount++
case 2:
manualDisabledCount++
case 3:
autoDisabledCount++
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Magic numbers for key status values

The code uses magic numbers (1, 2, 3) for key status values without constants.

Consider defining constants for better maintainability:

const (
    KeyStatusEnabled = 1
    KeyStatusManuallyDisabled = 2
    KeyStatusAutoDisabled = 3
)

Then use these constants throughout the code instead of magic numbers.

🤖 Prompt for AI Agents
In controller/channel.go around lines 1154 to 1160, replace the magic numbers 1,
2, and 3 used for key status values with defined constants. Define constants
such as KeyStatusEnabled = 1, KeyStatusManuallyDisabled = 2, and
KeyStatusAutoDisabled = 3 at the top of the file or in a relevant constants
section, then update the switch cases to use these constants instead of raw
numbers for better readability and maintainability.

Comment thread controller/channel.go
Comment on lines +1207 to +1221
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "未指定要禁用的密钥索引",
})
return
}

keyIndex := *request.KeyIndex
if keyIndex < 0 || keyIndex >= channel.ChannelInfo.MultiKeySize {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "密钥索引超出范围",
})
return
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

More hardcoded Chinese text in API responses

Multiple locations have hardcoded Chinese text that should be in English for API consistency.

Key locations needing fixes:

  • Line 1209: "未指定要禁用的密钥索引""Key index not specified for disabling"
  • Line 1218: "密钥索引超出范围""Key index out of range"
  • Line 1235: "手动禁用""Manually disabled"
  • Line 1246: "密钥已禁用""Key disabled successfully"
  • Line 1254: "未指定要启用的密钥索引""Key index not specified for enabling"
  • Line 1263: "密钥索引超出范围""Key index out of range"
  • Line 1288: "密钥已启用""Key enabled successfully"
  • Line 1335: "没有需要删除的自动禁用密钥""No auto-disabled keys to delete"
  • Line 1356: "已删除 %d 个自动禁用的密钥""Deleted %d auto-disabled keys"
  • Line 1364: "不支持的操作""Unsupported action"

Also applies to: 1235-1235, 1252-1265, 1309-1310, 1364-1364

🤖 Prompt for AI Agents
In controller/channel.go from lines 1207 to 1221 and other specified lines
(1235, 1246, 1254, 1263, 1288, 1335, 1356, 1364), replace all hardcoded Chinese
text in API JSON response messages with their English equivalents for
consistency. For example, change "未指定要禁用的密钥索引" to "Key index not specified for
disabling", "密钥索引超出范围" to "Key index out of range", and similarly update all
other listed messages accordingly.

node: 'item',
name: t('启用全部密钥'),
onClick: () => manageChannel(record.id, 'enable_all', record),
name: t('多key管理'),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Hardcoded Chinese text in dropdown menu

The menu item name should use translation for consistency with the rest of the UI.

Apply this diff to fix the internationalization:

-name: t('多key管理'),
+name: t('Multi-key Management'),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: t('多key管理'),
name: t('Multi-key Management'),
🤖 Prompt for AI Agents
In web/src/components/table/channels/ChannelsColumnDefs.js at line 547, the menu
item name is hardcoded in Chinese, which breaks UI consistency. Replace the
hardcoded string with a call to the translation function t() using the
appropriate translation key to ensure the text is internationalized like the
rest of the UI.

Comment on lines +98 to +101
} catch (error) {
console.error(error);
showError(t('获取密钥状态失败'));
} finally {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Inconsistent internationalization

The error message is hardcoded in Chinese while the rest of the component uses the translation function t().

Apply this diff to fix the internationalization:

 } catch (error) {
   console.error(error);
-  showError(t('获取密钥状态失败'));
+  showError(t('Failed to get key status'));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
console.error(error);
showError(t('获取密钥状态失败'));
} finally {
} catch (error) {
console.error(error);
showError(t('Failed to get key status'));
} finally {
🤖 Prompt for AI Agents
In web/src/components/table/channels/modals/MultiKeyManageModal.jsx around lines
98 to 101, the error message inside showError is hardcoded in Chinese instead of
using the translation function t(). Replace the hardcoded string with a call to
t() passing the Chinese message as the key to ensure consistent
internationalization across the component.

Comment on lines +145 to +153
showSuccess(t('密钥已启用'));
await loadKeyStatus(currentPage, pageSize); // Reload current page
onRefresh && onRefresh(); // Refresh parent component
} else {
showError(res.data.message);
}
} catch (error) {
showError(t('启用密钥失败'));
} finally {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Inconsistent internationalization in enable key messages

The success and error messages are hardcoded in Chinese.

Apply this diff to fix the internationalization:

 if (res.data.success) {
-  showSuccess(t('密钥已启用'));
+  showSuccess(t('Key enabled successfully'));
   await loadKeyStatus(currentPage, pageSize); // Reload current page
   onRefresh && onRefresh(); // Refresh parent component
 } else {
   showError(res.data.message);
 }
 } catch (error) {
-  showError(t('启用密钥失败'));
+  showError(t('Failed to enable key'));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
showSuccess(t('密钥已启用'));
await loadKeyStatus(currentPage, pageSize); // Reload current page
onRefresh && onRefresh(); // Refresh parent component
} else {
showError(res.data.message);
}
} catch (error) {
showError(t('启用密钥失败'));
} finally {
if (res.data.success) {
- showSuccess(t('密钥已启用'));
+ showSuccess(t('Key enabled successfully'));
await loadKeyStatus(currentPage, pageSize); // Reload current page
onRefresh && onRefresh(); // Refresh parent component
} else {
showError(res.data.message);
}
} catch (error) {
- showError(t('启用密钥失败'));
+ showError(t('Failed to enable key'));
} finally {
🤖 Prompt for AI Agents
In web/src/components/table/channels/modals/MultiKeyManageModal.jsx around lines
145 to 153, the success and error messages for enabling keys are hardcoded in
Chinese. Replace the hardcoded Chinese strings with calls to the translation
function t() using appropriate translation keys to ensure consistent
internationalization across the application.

Comment on lines +177 to +179
} catch (error) {
showError(t('删除禁用密钥失败'));
} finally {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Inconsistent internationalization in delete error message

The error message is hardcoded in Chinese.

Apply this diff to fix the internationalization:

 } catch (error) {
-  showError(t('删除禁用密钥失败'));
+  showError(t('Failed to delete disabled keys'));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
showError(t('删除禁用密钥失败'));
} finally {
} catch (error) {
showError(t('Failed to delete disabled keys'));
} finally {
🤖 Prompt for AI Agents
In web/src/components/table/channels/modals/MultiKeyManageModal.jsx around lines
177 to 179, the error message in the catch block is hardcoded in Chinese, which
breaks internationalization consistency. Replace the hardcoded Chinese string
with a call to the translation function t() passing the appropriate key for the
delete error message, ensuring the message is properly internationalized.

Comment on lines +219 to +230
const renderStatusTag = (status) => {
switch (status) {
case 1:
return <Tag color='green' shape='circle'>{t('已启用')}</Tag>;
case 2:
return <Tag color='red' shape='circle'>{t('已禁用')}</Tag>;
case 3:
return <Tag color='orange' shape='circle'>{t('自动禁用')}</Tag>;
default:
return <Tag color='grey' shape='circle'>{t('未知状态')}</Tag>;
}
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Hardcoded Chinese text in status tags

All status tag labels are hardcoded in Chinese instead of using translations.

Apply this diff to fix the internationalization:

 const renderStatusTag = (status) => {
   switch (status) {
     case 1:
-      return <Tag color='green' shape='circle'>{t('已启用')}</Tag>;
+      return <Tag color='green' shape='circle'>{t('Enabled')}</Tag>;
     case 2:
-      return <Tag color='red' shape='circle'>{t('已禁用')}</Tag>;
+      return <Tag color='red' shape='circle'>{t('Disabled')}</Tag>;
     case 3:
-      return <Tag color='orange' shape='circle'>{t('自动禁用')}</Tag>;
+      return <Tag color='orange' shape='circle'>{t('Auto-disabled')}</Tag>;
     default:
-      return <Tag color='grey' shape='circle'>{t('未知状态')}</Tag>;
+      return <Tag color='grey' shape='circle'>{t('Unknown status')}</Tag>;
   }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const renderStatusTag = (status) => {
switch (status) {
case 1:
return <Tag color='green' shape='circle'>{t('已启用')}</Tag>;
case 2:
return <Tag color='red' shape='circle'>{t('已禁用')}</Tag>;
case 3:
return <Tag color='orange' shape='circle'>{t('自动禁用')}</Tag>;
default:
return <Tag color='grey' shape='circle'>{t('未知状态')}</Tag>;
}
};
const renderStatusTag = (status) => {
switch (status) {
case 1:
return <Tag color='green' shape='circle'>{t('Enabled')}</Tag>;
case 2:
return <Tag color='red' shape='circle'>{t('Disabled')}</Tag>;
case 3:
return <Tag color='orange' shape='circle'>{t('Auto-disabled')}</Tag>;
default:
return <Tag color='grey' shape='circle'>{t('Unknown status')}</Tag>;
}
};
🤖 Prompt for AI Agents
In web/src/components/table/channels/modals/MultiKeyManageModal.jsx around lines
219 to 230, the status tag labels are hardcoded in Chinese. To fix this, replace
the hardcoded Chinese strings with calls to the translation function t() using
appropriate translation keys instead of direct Chinese text. This ensures the
labels are internationalized and can be translated based on the user's locale.

Comment thread web/src/components/table/channels/modals/MultiKeyManageModal.jsx
Comment thread web/src/components/table/channels/modals/MultiKeyManageModal.jsx
@Calcium-Ion
Calcium-Ion merged commit c9d4cdc into alpha Aug 4, 2025
1 of 2 checks passed
x22x22 pushed a commit to x22x22/new-api that referenced this pull request Apr 24, 2026
@coderabbitai coderabbitai Bot mentioned this pull request May 6, 2026
11 tasks
jiutubaba pushed a commit to jiutubaba/fx-api that referenced this pull request May 17, 2026
do not normalize model for openai API token based accounts
@coderabbitai coderabbitai Bot mentioned this pull request Jun 27, 2026
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant