From 09b31c460dbb78af173e0b3b905844dd25a3c47f Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Sun, 1 Mar 2026 19:37:26 +0800 Subject: [PATCH] feat: add ConfigRouteManagerDialog component for managing routing configurations - Implemented a new dialog component for managing routes associated with configurations, allowing users to view, delete, and save routes. - Enhanced the ProviderSelector component with improved styling for better readability. - Updated English and Chinese localization files to include new strings for the route manager and profile sidebar. - Refactored ConfigPage.vue to integrate the new route management dialog and improve layout responsiveness. - Added methods for handling route management, including fetching, saving, and removing routes. --- astrbot/core/platform/astrbot_message.py | 35 +- .../config/ConfigProfileSidebar.vue | 213 ++++++ .../config/ConfigRouteManagerDialog.vue | 236 +++++++ .../components/shared/ProviderSelector.vue | 1 + .../i18n/locales/en-US/features/config.json | 20 + .../i18n/locales/zh-CN/features/config.json | 20 + dashboard/src/views/ConfigPage.vue | 666 +++++++++++++----- 7 files changed, 1016 insertions(+), 175 deletions(-) create mode 100644 dashboard/src/components/config/ConfigProfileSidebar.vue create mode 100644 dashboard/src/components/config/ConfigRouteManagerDialog.vue diff --git a/astrbot/core/platform/astrbot_message.py b/astrbot/core/platform/astrbot_message.py index 3db53fd484..e9f2267a8a 100644 --- a/astrbot/core/platform/astrbot_message.py +++ b/astrbot/core/platform/astrbot_message.py @@ -48,18 +48,29 @@ def __str__(self) -> str: class AstrBotMessage: - """AstrBot 的消息对象""" + """Represents a message received from the platform, after parsing and normalization. + This is the main message object that will be passed to plugins and handlers.""" - type: MessageType # 消息类型 - self_id: str # 机器人的识别id - session_id: str # 会话id。取决于 unique_session 的设置。 - message_id: str # 消息id - group: Group | None # 群组 - sender: MessageMember # 发送者 - message: list[BaseMessageComponent] # 消息链使用 Nakuru 的消息链格式 - message_str: str # 最直观的纯文本消息字符串 + type: MessageType + """GroupMessage, FriendMessage, etc""" + self_id: str + """Bot's ID""" + session_id: str + """Session ID, which is the last part of UMO""" + message_id: str + """Message ID""" + group: Group | None + """The group info, None if it's a friend message""" + sender: MessageMember + """The sender info""" + message: list[BaseMessageComponent] + """Sorted list of message components after parsing""" + message_str: str + """The parsed message text after parsing, without any formatting or special components""" raw_message: object - timestamp: int # 消息时间戳 + """The raw message object, the specific type depends on the platform""" + timestamp: int + """The timestamp when the message is received, in seconds""" def __init__(self) -> None: self.timestamp = int(time.time()) @@ -70,16 +81,12 @@ def __str__(self) -> str: @property def group_id(self) -> str: - """向后兼容的 group_id 属性 - 群组id,如果为私聊,则为空 - """ if self.group: return self.group.group_id return "" @group_id.setter def group_id(self, value: str | None) -> None: - """设置 group_id""" if value: if self.group: self.group.group_id = value diff --git a/dashboard/src/components/config/ConfigProfileSidebar.vue b/dashboard/src/components/config/ConfigProfileSidebar.vue new file mode 100644 index 0000000000..4d5c6304d0 --- /dev/null +++ b/dashboard/src/components/config/ConfigProfileSidebar.vue @@ -0,0 +1,213 @@ + + + + + mdi-format-list-bulleted-square + {{ tm('profileSidebar.title') }} + + + + + + + + + + + + mdi-file-outline + {{ config.name }} + + + mdi-routes + + + + + + + + mdi-robot-outline + + + {{ binding.platformId }} + + + + + + {{ tm('profileSidebar.platformId') }}: {{ binding.platformId }} + + + {{ tm('profileSidebar.umop') }}: + + + {{ umop }} + + + + + +{{ bindingsForConfig(config.id).length - maxVisibleBindings }} + + + + {{ tm('profileSidebar.noBindings') }} + + + + + + + + + + + + diff --git a/dashboard/src/components/config/ConfigRouteManagerDialog.vue b/dashboard/src/components/config/ConfigRouteManagerDialog.vue new file mode 100644 index 0000000000..91f7e087bb --- /dev/null +++ b/dashboard/src/components/config/ConfigRouteManagerDialog.vue @@ -0,0 +1,236 @@ + + + + + + {{ props.configName }} {{ tm('routeManager.title') }} + + + + + + + + + + {{ tm('routeManager.hint') }} + + + + {{ tm('routeManager.empty') }} + + + + + + + + + mdi-robot-outline + + {{ group.platformId }} + + {{ group.routes.length }} + + + + + + + {{ isAllSessionsRoute(route.umop) ? tm('routeManager.allSessions') : route.umop }} + + + + + + + + + + + + + + + + + + {{ tm('buttons.cancel') }} + + + {{ tm('actions.save') }} + + + + + + + + + diff --git a/dashboard/src/components/shared/ProviderSelector.vue b/dashboard/src/components/shared/ProviderSelector.vue index 7ffbeb6ea6..0965f53625 100644 --- a/dashboard/src/components/shared/ProviderSelector.vue +++ b/dashboard/src/components/shared/ProviderSelector.vue @@ -372,6 +372,7 @@ function closeProviderDrawer() { white-space: nowrap; max-width: calc(100% - 80px); display: inline-block; + font-size: 13px; } .selected-preview { diff --git a/dashboard/src/i18n/locales/en-US/features/config.json b/dashboard/src/i18n/locales/en-US/features/config.json index 4b726ae3c8..f9efbb13bc 100644 --- a/dashboard/src/i18n/locales/en-US/features/config.json +++ b/dashboard/src/i18n/locales/en-US/features/config.json @@ -69,6 +69,26 @@ "normalConfig": "Basic", "systemConfig": "System" }, + "profileSidebar": { + "title": "Configuration Profiles", + "platformId": "Platform ID", + "umop": "Bound UMOP", + "noBindings": "No platform bindings" + }, + "routeManager": { + "title": "Route Manager", + "targetConfig": "Config: {config}", + "hint": "AstrBot supports multiple config files, and routing decides which session uses which config. This dialog shows all routes handled by the current config: platform on the left and UMOP on the right; click Save after deleting routes.", + "empty": "No routes available to manage.", + "platform": "Platform", + "umop": "UMOP", + "allSessions": "All Sessions", + "delete": "Delete Route", + "loadFailed": "Failed to load routes", + "saveSuccess": "Routes saved", + "saveFailed": "Failed to save routes", + "routeOccupied": "This route is already occupied by another config: {umop}" + }, "search": { "placeholder": "Search config items (key/description/hint)", "noResult": "No matching config items found" diff --git a/dashboard/src/i18n/locales/zh-CN/features/config.json b/dashboard/src/i18n/locales/zh-CN/features/config.json index e7cd90408b..4ee7a453d2 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/config.json +++ b/dashboard/src/i18n/locales/zh-CN/features/config.json @@ -69,6 +69,26 @@ "normalConfig": "普通", "systemConfig": "系统" }, + "profileSidebar": { + "title": "配置文件列表", + "platformId": "平台 ID", + "umop": "绑定 UMOP", + "noBindings": "暂无平台绑定" + }, + "routeManager": { + "title": "路由管理", + "targetConfig": "配置:{config}", + "hint": "AstrBot 支持多配置文件,路由用于决定“哪个会话用哪个配置”。这里展示的是当前配置文件接管的全部路由:左侧是机器人 ID、右侧是匹配的消息会话来源。", + "empty": "暂无可管理的路由。", + "platform": "平台", + "umop": "UMOP", + "allSessions": "全部会话", + "delete": "删除路由", + "loadFailed": "加载路由失败", + "saveSuccess": "路由已保存", + "saveFailed": "保存路由失败", + "routeOccupied": "该路由已被其他配置占用:{umop}" + }, "search": { "placeholder": "搜索配置项(字段名/描述/提示)", "noResult": "未找到匹配的配置项" diff --git a/dashboard/src/views/ConfigPage.vue b/dashboard/src/views/ConfigPage.vue index 7c50fbb583..c027d2e803 100644 --- a/dashboard/src/views/ConfigPage.vue +++ b/dashboard/src/views/ConfigPage.vue @@ -1,81 +1,119 @@ - - - - - - - - + + + + + + + + + + {{ selectedConfigInfo.name || selectedConfigID }} + + + ID: {{ selectedConfigID }} + + + + + + + + + + + - + + + + {{ tm('messages.unsavedChangesNotice') }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - {{ tm('messages.unsavedChangesNotice') }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -158,6 +196,18 @@ + + {{ save_message }} @@ -201,6 +251,8 @@