# 活动管理命令
**本文引用的文件**
- [src/index.ts](file://src/index.ts)
- [src/command/index.ts](file://src/command/index.ts)
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能与缓存策略](#性能与缓存策略)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录:扩展开发指南](#附录扩展开发指南)
## 简介
本文件聚焦于活动管理相关命令的实现与扩展,重点解析以下命令:
- /events:活动列表获取、分页显示、筛选排序与交互式导航(当前实现为“最近活动”列表)
- /event_{id}:活动详情查询、图片展示、时间安排与报名状态显示
- /book_{event_id}_{slot_index}:基于活动详情的预约流程(含优惠券选择)
- /history:用户预约历史展示
- /cancel_{booking_id}:预约取消确认与执行
- /login:基于会话的交互式登录,凭据持久化至 KV
同时,文档阐述活动数据的缓存策略、API 调用优化与错误处理机制,并提供活动搜索、过滤与个性化推荐的扩展开发建议。
## 项目结构
项目采用按功能模块划分的目录组织方式,命令入口集中于命令索引文件,各命令处理器位于独立文件中,客户端封装统一的 API 客户端。
```mermaid
graph TB
subgraph "入口与配置"
IDX["src/index.ts
Bot 初始化与命令注册"]
CMDIDX["src/command/index.ts
命令注册与会话配置"]
end
subgraph "命令处理器"
EVT["src/command/handlers/events.ts
/events 列表"]
DET["src/command/handlers/eventDetails.ts
/event_{id} 详情"]
BOOK["src/command/handlers/bookEvent.ts
/book_* 预约与优惠券"]
HIST["src/command/handlers/history.ts
/history 历史"]
CANCEL["src/command/handlers/cancel.ts
/cancel_* 取消"]
LOGIN["src/command/handlers/login.ts
/login 交互式登录"]
end
subgraph "客户端"
CLIENT["src/client/cosmoe.ts
CosmoeClient 封装"]
end
IDX --> CMDIDX
CMDIDX --> EVT
CMDIDX --> DET
CMDIDX --> BOOK
CMDIDX --> HIST
CMDIDX --> CANCEL
CMDIDX --> LOGIN
EVT --> CLIENT
DET --> CLIENT
BOOK --> CLIENT
HIST --> CLIENT
CANCEL --> CLIENT
LOGIN --> CLIENT
```
图表来源
- [src/index.ts](file://src/index.ts#L13-L46)
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L1-L27)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L1-L61)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L1-L107)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L1-L75)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
章节来源
- [src/index.ts](file://src/index.ts#L13-L46)
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
## 核心组件
- 命令注册与会话配置:在命令索引中完成命令绑定、会话插件安装与 KV 存储适配。
- 事件命令处理器:负责获取活动列表并以 Markdown 格式输出,支持最多 10 条最近活动。
- 事件详情处理器:解析 /event_{id},调用详情接口,格式化时间安排、剩余容量与预约链接。
- 预约处理器:解析 /book_{event_id}_{slot_index},读取用户凭据,校验时段可用性,支持优惠券选择与自动下单。
- 历史与取消:历史命令展示用户最近预约记录;取消命令提供二次确认与回调处理。
- 登录处理器:通过交互式会话获取用户名与密码,调用认证接口并将凭据写入 KV。
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L1-L27)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L1-L61)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L1-L107)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L1-L75)
## 架构总览
下图展示了从用户输入到 API 调用与响应处理的整体流程,以及关键组件之间的依赖关系。
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "Bot(grammy)"
participant C as "命令处理器"
participant K as "KV 存储"
participant API as "CosmoeClient(API)"
U->>B : "/events"
B->>C : "handleEventsCommand"
C->>API : "getEvents()"
API-->>C : "返回活动列表"
C-->>U : "Markdown 格式的活动列表"
U->>B : "/event_{id}"
B->>C : "handleEventDetails"
C->>API : "getEventDetail(id)"
API-->>C : "返回活动详情"
C-->>U : "Markdown 格式的详情(含图片、时间安排、预约链接)"
U->>B : "/book_{event_id}_{slot_index}"
B->>C : "handleBookEvent"
C->>K : "读取用户凭据"
K-->>C : "返回凭据(JSON)"
C->>API : "getEventDetail(id)"
API-->>C : "返回活动详情"
C->>API : "bookEvent(含可选优惠券)"
API-->>C : "返回预约结果"
C-->>U : "预约成功/失败消息"
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L68-L80)
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L4-L26)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L4-L60)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L117)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L177-L199)
## 详细组件分析
### /events 命令:活动列表获取与展示
- 功能要点
- 调用 CosmoeClient 的活动列表接口,取回最新活动。
- 限制输出数量为前 10 条,避免消息过长。
- 使用 Markdown 格式输出,包含每个活动的跳转链接(/event_{id})。
- 错误处理
- 当 API 返回非 200 或无数据时,提示“当前没有摄影活动”。
- 异常捕获后回复“获取摄影活动时出错,请稍后再试”。
```mermaid
flowchart TD
Start(["进入 /events"]) --> CallAPI["调用 getEvents()"]
CallAPI --> RespOK{"返回 code==200 且有数据?"}
RespOK -- 否 --> NoEvents["回复: 当前没有摄影活动"]
RespOK -- 是 --> SliceTop10["取前 10 条活动"]
SliceTop10 --> BuildMsg["构建 Markdown 消息"]
BuildMsg --> Reply["发送消息"]
NoEvents --> End(["结束"])
Reply --> End
```
图表来源
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L4-L26)
章节来源
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L1-L27)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L177-L184)
### /eventDetails 命令:活动详情、图片与时间安排
- 功能要点
- 解析 /event_{id},调用 CosmoeClient 的详情接口。
- 格式化标题、日期、时间段与剩余容量,生成 Markdown 消息。
- 对于当天或之前的活动,显示“预约 -> /book_{event_id}_{slot_index}”链接。
- 展示封面图链接。
- 时间与状态判断
- 使用北京时间(UTC+8)比较活动日期与当前日期,决定是否允许预约。
- 时间段按 range 排序,保证展示顺序一致。
- 错误处理
- API 非 200 或异常时,回复错误消息并记录日志。
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "Bot"
participant H as "eventDetails 处理器"
participant API as "CosmoeClient"
U->>B : "/event_{id}"
B->>H : "handleEventDetails"
H->>API : "getEventDetail(id)"
API-->>H : "返回活动详情"
H->>H : "计算是否可预约(按北京时间比较)"
H->>H : "按 range 排序时间段"
H-->>U : "Markdown 格式详情(含图片与预约链接)"
```
图表来源
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L4-L60)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L199)
章节来源
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L1-L61)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L36-L50)
### /bookEvent 命令:预约流程与优惠券选择
- 功能要点
- 解析 /book_{event_id}_{slot_index},读取 KV 中的用户凭据。
- 获取活动详情,按 range 排序时间段,校验所选索引与剩余容量。
- 若存在多个可用优惠券,弹出内联键盘供用户选择;否则自动使用唯一优惠券或不使用。
- 调用预约接口,返回最终价格、预约编号等信息。
- 回调处理
- 通过回调选择优惠券后,更新消息并继续执行预约。
- 错误处理
- 凭据缺失、无效索引、已满等情况均给出明确提示。
- 异常捕获后回复“处理预约请求时出错,请稍后再试”。
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "Bot"
participant HB as "handleBookEvent"
participant HK as "handleCouponSelection"
participant API as "CosmoeClient"
participant KV as "KV 存储"
U->>B : "/book_{event_id}_{slot_index}"
B->>HB : "处理预约请求"
HB->>KV : "读取用户凭据"
KV-->>HB : "返回凭据(JSON)"
HB->>API : "getEventDetail(event_id)"
API-->>HB : "返回活动详情"
HB->>HB : "校验索引与剩余容量"
alt 多个优惠券
HB-->>U : "内联键盘选择优惠券"
U->>B : "回调 : 选择优惠券"
B->>HK : "handleCouponSelection"
HK->>API : "getEventDetail(event_id)"
API-->>HK : "返回活动详情"
HK->>API : "bookEvent(含优惠券)"
API-->>HK : "返回预约结果"
HK-->>U : "更新消息并回复结果"
else 单个/无优惠券
HB->>API : "bookEvent(可选优惠券)"
API-->>HB : "返回预约结果"
HB-->>U : "回复预约结果"
end
```
图表来源
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L117)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L159-L226)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L247-L270)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L329-L343)
章节来源
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L247-L270)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L329-L343)
### /history 命令:预约历史展示
- 功能要点
- 读取 KV 中用户凭据,初始化 CosmoeClient 并设置认证信息。
- 获取用户预约历史,按预约日期降序取前 8 条,拼接 Markdown 消息。
- 对未来且未完成的预约,附加取消链接(/cancel_{booking_id})。
- 时间处理
- 统一转换为北京时间进行比较,确保逻辑一致性。
- 错误处理
- 凭据缺失、认证失败、API 失败等情况均有明确提示。
章节来源
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L1-L107)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L226-L239)
### /cancel 命令:预约取消与确认
- 功能要点
- 解析 /cancel_{booking_id},读取用户凭据,获取历史确认待取消的预约。
- 弹出内联键盘“确认/取消”,点击后执行取消或取消操作。
- 取消成功/失败均反馈消息。
- 错误处理
- 未登录、无效 ID、认证失败、API 失败等情况均有提示。
章节来源
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L405-L422)
### /login 命令:交互式登录与凭据存储
- 功能要点
- 通过会话交互获取用户名与密码,调用 CosmoeClient.getToken 获取 user_id 与 token。
- 将凭据以 JSON 形式写入 KV,键为 Telegram 用户 ID,便于后续命令使用。
- 错误处理
- 输入缺失、认证失败、KV 写入异常等情况均有提示。
章节来源
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L1-L75)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L124-L140)
## 依赖关系分析
- 命令层依赖
- 所有命令处理器依赖 CosmoeClient 进行 API 调用。
- /bookEvent、/history、/cancel、/login 依赖 KV 存储读写用户凭据。
- /login 依赖会话插件实现交互式对话。
- 客户端依赖
- CosmoeClient 封装了基础 URL、认证状态管理与多类 API 方法。
- 入口依赖
- Bot 初始化与命令注册集中在入口文件,命令索引文件负责会话与回调注册。
```mermaid
graph LR
EVT["events.ts"] --> CLI["cosmoe.ts:getEvents"]
DET["eventDetails.ts"] --> CLI
BOOK["bookEvent.ts"] --> CLI
HIST["history.ts"] --> CLI
CANCEL["cancel.ts"] --> CLI
LOGIN["login.ts"] --> CLI
BOOK --> KV["KV 存储(COSMOE_CREDENTIALS)"]
HIST --> KV
CANCEL --> KV
LOGIN --> KV
CMDIDX["command/index.ts"] --> EVT
CMDIDX --> DET
CMDIDX --> BOOK
CMDIDX --> HIST
CMDIDX --> CANCEL
CMDIDX --> LOGIN
```
图表来源
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L1-L27)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L1-L61)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L1-L107)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L1-L75)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
## 性能与缓存策略
- 当前实现
- /events 仅取最新 10 条,减少消息长度与渲染压力。
- /eventDetails 对时间段按 range 排序,提升一致性与可读性。
- /history 仅取最近 8 条,避免超长消息。
- 缓存建议
- 活动列表与详情可引入短期缓存(如 TTL 5-10 分钟),结合 KV 或内存缓存,降低重复请求。
- 对热门活动的图片与描述可考虑本地镜像或 CDN 缓存,减少网络抖动影响。
- API 优化
- 在客户端层增加重试与退避策略,针对瞬时网络错误提升成功率。
- 对批量请求(如历史)可合并为单次调用,减少往返次数。
- 错误处理
- 所有命令均包含 try/catch 与条件分支,确保异常不影响整体服务稳定性。
- KV 读写失败时记录错误并优雅降级,避免阻塞主流程。
[本节为通用性能建议,不直接分析具体文件,故无章节来源]
## 故障排查指南
- 常见问题定位
- /events 无结果:检查 API 返回码与数据结构,确认网络连通性与服务端状态。
- /eventDetails 报错:确认传入的 id 是否正确,检查 API 返回字段映射。
- /bookEvent 提示未登录:确认 KV 中是否存在对应 Telegram 用户的凭据。
- /history 为空:确认用户已登录且存在预约记录。
- /cancel 失败:确认预约状态与时间窗口(需为未来且未完成)。
- 日志与调试
- 所有处理器均包含错误日志打印,便于定位问题。
- 建议在生产环境开启更详细的日志级别与错误追踪。
章节来源
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L23-L26)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L57-L60)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L30-L33)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L14-L18)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L28-L32)
## 结论
本项目围绕活动管理构建了完整的命令体系,覆盖活动浏览、详情查看、预约、历史与取消等核心流程。当前实现简洁可靠,具备良好的错误处理与用户体验。为进一步增强系统能力,可在现有基础上引入缓存、搜索过滤与个性化推荐等扩展功能。
[本节为总结性内容,不直接分析具体文件,故无章节来源]
## 附录:扩展开发指南
### 活动搜索与过滤
- 搜索建议
- 在 CosmoeClient 中新增搜索接口,支持关键词、日期范围、状态等参数。
- 在命令层新增 /search 命令,解析参数并调用搜索接口,返回匹配结果列表。
- 过滤建议
- 支持按“可预约”、“已结束”、“本周/本月”等维度过滤。
- 在 UI 层提供内联按钮快速切换过滤条件。
章节来源
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L177-L184)
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L4-L26)
### 分页显示与交互式导航
- 分页建议
- 在活动列表接口中支持 page/size 参数,命令层维护当前页码与翻页按钮。
- 使用内联键盘提供“上一页/下一页”与“直达页码”按钮。
- 导航建议
- 在详情页提供“返回列表”与“下一活动”的快捷跳转。
- 对热门活动提供“收藏/取消收藏”功能(结合 KV 存储用户偏好)。
章节来源
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L9-L10)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L40-L45)
### 个性化推荐
- 推荐策略
- 基于用户历史预约与偏好(如时间段、摄影师)生成候选集。
- 在 /events 列表中优先展示推荐项,并标注“为你推荐”。
- 数据来源
- 通过 /history 与 /bookEvent 的数据统计,结合 KV 存储用户标签。
章节来源
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L49-L52)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L128-L135)
### 缓存与性能优化
- 缓存策略
- 活动列表与详情设置 TTL,命中缓存时减少 API 调用。
- 对图片与静态资源使用 CDN 缓存,缩短加载时间。
- 重试与退避
- 对瞬时网络错误实施指数退避重试,提升成功率。
- 错误隔离
- 将 KV 读写与 API 调用置于独立模块,便于监控与限流。
章节来源
- [src/command/index.ts](file://src/command/index.ts#L22-L49)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L124-L140)