# 预约与取消命令
**本文档引用的文件**
- [src/command/index.ts](file://src/command/index.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/events.ts](file://src/command/handlers/events.ts)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts)
- [src/command/handlers/logout.ts](file://src/command/handlers/logout.ts)
- [src/command/handlers/start.ts](file://src/command/handlers/start.ts)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts)
- [src/scheduler/index.ts](file://src/scheduler/index.ts)
- [wrangler.jsonc](file://wrangler.jsonc)
- [package.json](file://package.json)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向“预约与取消命令”的完整业务流程,深入解析以下命令:
- 预约流程:/bookEvent(活动选择、时间槽确认、优惠券应用、用户确认和最终预订)
- 历史查询:/history(预约记录获取、状态筛选、分页展示和详情查看)
- 取消流程:/cancel(预约确认、取消原因选择、退款处理和状态更新)
同时解释回调查询处理、按钮交互和实时状态更新机制,并提供预约冲突检测、容量管理与通知推送的扩展实现建议。
## 项目结构
该机器人基于 GrammY 框架构建,采用模块化命令处理器与 Cloudflare Workers 运行环境。核心目录与职责如下:
- src/command/index.ts:注册命令与回调查询,配置对话式会话存储(KV)
- src/command/handlers/*:各命令处理器(事件列表、活动详情、预约、历史、取消、登录、登出等)
- src/client/cosmoe.ts:封装对 Cosmoe API 的调用(认证、事件、预约、取消等)
- src/scheduler/index.ts:定时任务(新活动通知推送)
- wrangler.jsonc:Cloudflare Workers 配置(KV 绑定、计划任务)
- package.json:依赖与脚本
```mermaid
graph TB
subgraph "Telegram 机器人"
CMD["命令入口
src/command/index.ts"]
HANDLERS["命令处理器
src/command/handlers/*"]
SCHED["定时任务
src/scheduler/index.ts"]
end
subgraph "客户端"
CLIENT["Cosmoe 客户端
src/client/cosmoe.ts"]
end
subgraph "Cloudflare Workers"
KV["KV 存储
COSMOE_CREDENTIALS/COSMOE_STORAGE"]
TRIG["计划任务触发器
*/1 * * * *"]
end
CMD --> HANDLERS
HANDLERS --> CLIENT
SCHED --> CLIENT
HANDLERS --> KV
SCHED --> KV
TRIG --> SCHED
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
- [wrangler.jsonc](file://wrangler.jsonc#L21-L30)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L1-L110)
- [wrangler.jsonc](file://wrangler.jsonc#L1-L31)
## 核心组件
- 命令注册与会话存储:通过 KV 适配器实现对话状态持久化,支持登录对话、回调查询处理与命令路由。
- Cosmoe 客户端:统一封装认证、事件查询、预约、取消、历史查询等 API 调用。
- 定时任务:周期性检查新活动并推送通知给已登录用户。
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
## 架构总览
下图展示了从用户输入到 API 调用与 KV 存储的整体流程。
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "Telegram Bot"
participant C as "命令处理器"
participant K as "KV 存储"
participant API as "Cosmoe API"
U->>B : 发送命令/回调
B->>C : 路由到对应处理器
C->>K : 读取/写入用户凭证与会话
C->>API : 调用事件/预约/取消接口
API-->>C : 返回结果
C-->>U : 发送消息/内联键盘
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
## 详细组件分析
### 预约流程:/bookEvent
- 输入格式:/book_{event_id}_{slot_index}
- 关键步骤:
1) 解析命令参数,提取活动 ID 与时间槽索引
2) 从 KV 获取用户凭证并校验登录状态
3) 调用 Cosmoe API 获取活动详情与时间槽
4) 校验时间槽剩余容量
5) 查询可用优惠券,若多于一个则弹出内联键盘供用户选择
6) 用户确认后发起预约请求,返回最终价格、预约编号等信息
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "Bot"
participant H as "bookEvent 处理器"
participant K as "KV 存储"
participant API as "Cosmoe API"
U->>B : /book_{event_id}_{slot_index}
B->>H : 路由到处理函数
H->>K : 读取用户凭证
H->>API : 获取活动详情与时间槽
API-->>H : 返回活动数据
H->>H : 校验剩余容量
H->>API : 查询可用优惠券
API-->>H : 返回优惠券列表
alt 多个优惠券
H-->>U : 弹出内联键盘选择优惠券
U->>B : 回调选择优惠券
B->>H : 处理回调
else 单个或无优惠券
H->>H : 自动选择/不使用优惠券
end
H->>API : 提交预约请求
API-->>H : 返回预约结果
H-->>U : 成功/失败消息
```
图表来源
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L118)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L160-L226)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L270)
章节来源
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L118)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L160-L226)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L270)
### 历史查询:/history
- 功能要点:
- 获取用户登录态,调用历史接口
- 对预约按时间倒序排序,限制展示数量
- 为可取消且未来时间的预约生成取消链接
- 支持 Markdown 格式输出,避免超长消息截断
```mermaid
flowchart TD
Start(["进入 /history"]) --> GetUser["获取 Telegram 用户ID"]
GetUser --> CheckCreds{"KV 中存在凭证?"}
CheckCreds --> |否| PromptLogin["提示先登录"]
CheckCreds --> |是| InitClient["初始化 Cosmoe 客户端"]
InitClient --> FetchBookings["获取我的预约历史"]
FetchBookings --> HasData{"有数据?"}
HasData --> |否| EmptyMsg["提示历史为空"]
HasData --> |是| SortLimit["按时间倒序并限制数量"]
SortLimit --> BuildMsg["构建 Markdown 消息"]
BuildMsg --> CancelLink{"满足可取消条件?"}
CancelLink --> |是| AddLink["添加取消链接"]
CancelLink --> |否| SkipLink["跳过"]
AddLink --> SendMsg["发送消息"]
SkipLink --> SendMsg
PromptLogin --> End(["结束"])
EmptyMsg --> End
SendMsg --> End
```
图表来源
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L4-L107)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L226-L239)
章节来源
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L4-L107)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L226-L239)
### 取消流程:/cancel
- 输入格式:/cancel_{booking_id}
- 关键步骤:
1) 解析命令参数,获取预约 ID
2) 校验登录态并获取用户历史
3) 在历史中定位目标预约,构造确认内联键盘
4) 用户点击确认后,调用取消接口并更新消息
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "Bot"
participant H as "cancel 处理器"
participant API as "Cosmoe API"
U->>B : /cancel_{booking_id}
B->>H : 路由到处理函数
H->>API : 获取我的预约历史
API-->>H : 返回历史列表
H->>H : 定位目标预约
H-->>U : 弹出确认内联键盘
U->>B : 点击“确认”或“取消”
B->>H : 处理回调
alt 确认取消
H->>API : 调用取消接口
API-->>H : 返回结果
H-->>U : 更新为成功/失败消息
else 取消操作
H-->>U : 提示操作已取消
end
```
图表来源
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L11-L84)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L87-L132)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L405-L422)
章节来源
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L11-L84)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L87-L132)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L405-L422)
### 回调查询与按钮交互
- 回调类型:
- 取消确认:confirm_cancel_{booking_id} 或 cancel_action
- 优惠券选择:select_coupon_{event_id}_{slot_index}_{coupon_code|none}
- 处理逻辑:
- 解析回调数据,校验用户登录态
- 读取活动详情与时间槽,更新消息内容
- 执行预约或取消操作并反馈结果
章节来源
- [src/command/index.ts](file://src/command/index.ts#L92-L105)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L160-L226)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L87-L132)
### 实时状态更新机制
- 当前实现:
- 历史查询中根据当前北京时间判断是否可取消,但未实现自动刷新
- 定时任务用于推送新活动通知,未包含预约状态变更通知
- 建议扩展:
- 在历史查询中增加“刷新”按钮,调用相同接口并重新渲染
- 在定时任务中加入“预约状态变更通知”,向用户推送取消/完成状态变化
章节来源
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L68-L92)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L24-L84)
## 依赖关系分析
- 命令入口依赖各处理器模块,处理器依赖 Cosmoe 客户端与 KV 存储
- 定时任务依赖 Cosmoe 客户端与 KV 存储,通过计划任务触发器运行
- Cloudflare Workers 配置定义 KV 绑定与计划任务
```mermaid
graph LR
IDX["命令入口
src/command/index.ts"] --> H_BOOK["预约处理器
src/command/handlers/bookEvent.ts"]
IDX --> H_CANCEL["取消处理器
src/command/handlers/cancel.ts"]
IDX --> H_HISTORY["历史处理器
src/command/handlers/history.ts"]
H_BOOK --> CLIENT["Cosmoe 客户端
src/client/cosmoe.ts"]
H_CANCEL --> CLIENT
H_HISTORY --> CLIENT
SCHED["定时任务
src/scheduler/index.ts"] --> CLIENT
SCHED --> KV["KV 存储"]
IDX --> KV
WRANGLER["Workers 配置
wrangler.jsonc"] --> KV
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
- [wrangler.jsonc](file://wrangler.jsonc#L21-L30)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
- [wrangler.jsonc](file://wrangler.jsonc#L21-L30)
## 性能考虑
- KV 读写:会话与凭证均通过 KV 存储,注意控制读写频率与错误重试
- API 调用:事件与历史接口可能返回大量数据,需在前端做分页与截断
- Markdown 渲染:消息长度超过限制时应截断,避免 Telegram API 报错
- 定时任务:每分钟触发一次,需确保任务执行时间短、异常处理完备
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L94-L102)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
## 故障排除指南
- 认证失败
- 症状:提示需要登录或凭证无效
- 排查:确认 /login 是否成功写入 KV;检查凭证有效期
- 预约失败
- 症状:提示预约失败或无空位
- 排查:检查时间槽剩余容量;确认优惠券是否可用
- 取消失败
- 症状:取消请求返回失败
- 排查:确认预约状态是否允许取消;检查网络与 API 返回
- 消息超长
- 症状:历史消息被截断
- 排查:减少展示条数或分页展示
章节来源
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L49-L69)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L60-L63)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L120-L124)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L94-L102)
## 结论
本系统以清晰的模块化设计实现了完整的预约与取消流程,结合 KV 会话存储与回调交互,提供了良好的用户体验。建议后续增强实时状态更新与通知推送能力,进一步提升用户参与度与满意度。
## 附录
### 命令与回调一览
- 命令
- /start:欢迎与帮助
- /login:交互式登录
- /logout:登出并清除凭证
- /events:查看最新活动
- /event_{id}:查看活动详情与预约入口
- /book_{event_id}_{slot_index}:发起预约
- /history:查看预约历史
- /cancel_{booking_id}:发起取消
- 回调
- confirm_cancel_{booking_id}:确认取消
- cancel_action:取消取消
- select_coupon_{event_id}_{slot_index}_{coupon_code|none}:选择优惠券
章节来源
- [src/command/index.ts](file://src/command/index.ts#L59-L109)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L160-L226)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L87-L132)
### 扩展实现建议
- 预约冲突检测
- 在提交预约前,查询用户当前未完成的预约,避免重复占用同一时间槽
- 容量管理
- 在活动详情页显示更直观的剩余/容量比例,必要时提供“占位”或“候补”机制
- 通知推送
- 新增“预约状态变更通知”:完成、取消、过期等状态变化时主动推送
- 新活动通知:现有定时任务已实现,可扩展为按用户偏好定制推送
章节来源
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L24-L84)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L247-L270)