From 7b25f437b85013a30d0cf3e03ad2191c87c5f4e0 Mon Sep 17 00:00:00 2001 From: chenxiangtong Date: Wed, 15 Apr 2026 19:12:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=A2=E9=98=85=E5=88=97?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 26 ++++++++++++++++++++++++++ src/db/repository.py | 25 +++++++++++++++++++++++++ src/services/subscription.py | 25 +++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/main.py b/main.py index 8e38c23..265c947 100644 --- a/main.py +++ b/main.py @@ -314,6 +314,19 @@ class BangumiPlugin(Star): result = await self.subscription_service.unsubscribe(session_key, query) yield event.plain_result(result) + @filter.command("追番列表") + async def list_subscriptions( + self, event: AstrMessageEvent + ) -> AsyncGenerator[object, None]: + """列举当前会话的所有追番订阅。""" + if not self.subscription_service: + yield event.plain_result("❌ 订阅服务未就绪") + return + + session_key = self._resolve_session_key(event) + result = self.subscription_service.list_subscriptions(session_key) + yield event.plain_result(result) + # --- LLM Tool 区 --- @filter.llm_tool(name="bangumi_search") @@ -399,6 +412,19 @@ class BangumiPlugin(Star): async for result in self.search_service.handle_calendar(event): yield result + @filter.llm_tool(name="bangumi_list_subscriptions") + async def llm_list_subscriptions( + self, event: AstrMessageEvent + ) -> AsyncGenerator[object, None]: + """列举当前会话已订阅的所有追番,包含番剧名称、Bangumi ID 和当前更新集数。当用户询问"我订阅了哪些番"、"追番列表"、"我在追什么"时调用。""" + if not self.subscription_service: + yield event.plain_result("❌ 订阅服务未就绪") + return + + session_key = self._resolve_session_key(event) + result = self.subscription_service.list_subscriptions(session_key) + yield event.plain_result(result) + @filter.llm_tool(name="bangumi_subscribe") async def llm_subscribe( self, diff --git a/src/db/repository.py b/src/db/repository.py index 9ad5535..9e86c00 100644 --- a/src/db/repository.py +++ b/src/db/repository.py @@ -181,6 +181,31 @@ class BangumiRepository: finally: session.close() + def get_session_subscribed_subjects(self, session_id: str) -> list[BangumiSubject]: + """ + 获取指定会话(群组或私聊)的所有已订阅番剧详情。 + + Args: + session_id: 会话唯一标识(unified_msg_origin) + + Returns: + BangumiSubject 对象列表,包含名称、集数等信息 + """ + db_session = self.Session() + try: + subjects = ( + db_session.query(BangumiSubject) + .join(Subscription, Subscription.subject_id == BangumiSubject.subject_id) + .filter(Subscription.group_id == str(session_id)) + .all() + ) + return subjects + except Exception as e: + logger.error(f"获取会话订阅列表失败: {e}") + raise DatabaseError(f"获取会话订阅列表失败: {e}") from e + finally: + db_session.close() + def get_monitored_subjects(self) -> list[BangumiSubject]: """ 获取所有已订阅的番剧列表,用于轮询更新 diff --git a/src/services/subscription.py b/src/services/subscription.py index 9949314..562f6e7 100644 --- a/src/services/subscription.py +++ b/src/services/subscription.py @@ -246,6 +246,31 @@ class SubscriptionService: lines.append("(仅显示前 5 项)") return "\n".join(lines), None + def list_subscriptions(self, session_id: str) -> str: + """ + 列举当前会话的所有订阅番剧,格式化为可读文本。 + """ + try: + subjects = self.storage.get_session_subscribed_subjects(session_id) + except DatabaseError as e: + logger.error(f"SubscriptionService.list_subscriptions 失败: {e}") + return f"❌ 查询失败: {e}" + + if not subjects: + return "📭 当前会话暂无追番订阅。\n使用 /追番 <关键词> 添加订阅。" + + lines = [f"📋 当前追番列表(共 {len(subjects)} 部):"] + for idx, subject in enumerate(subjects, start=1): + name = subject.name or "未知番剧" + subject_id = subject.subject_id + current_ep = subject.current_episode or 0 + total_ep = subject.total_episodes or 0 + ep_info = f"已更新至第 {current_ep} 集" if current_ep else "尚未更新" + if total_ep: + ep_info += f"(全 {total_ep} 集)" + lines.append(f"{idx}. 《{name}》(ID: {subject_id}) — {ep_info}") + return "\n".join(lines) + async def check_updates(self) -> None: """ 定时任务核心逻辑:检查所有监控中的番剧是否有更新。