# 预约命令
**本文引用的文件**
- [src/command/index.ts](file://src/command/index.ts)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.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/history.ts](file://src/command/handlers/history.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)
- [package.json](file://package.json)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向“预约命令”的实现与使用,围绕以下命令展开:
- 预约创建:/book_{event_id}_{slot_id}
- 预约取消:/cancel_{booking_id}
- 活动浏览:/events、/event_{id}
- 历史查询:/history
- 登录/登出:/login、/logout、/start
文档将深入解释命令解析、用户认证、活动与时间槽选择、优惠券应用、取消确认流程、状态管理与并发控制策略,并提供错误处理与数据一致性保障方案,以及扩展开发指导。
## 项目结构
该机器人采用模块化命令分发与客户端封装:
- 命令入口与路由:在命令入口中注册所有命令与回调查询,绑定环境变量(KV 存储)。
- 命令处理器:每个命令对应一个处理器文件,负责解析输入、调用客户端 API、构建交互式键盘与消息。
- 客户端封装:统一的 CosmoeClient 封装 API 请求、认证状态与数据模型。
```mermaid
graph TB
subgraph "命令层"
CMD_INDEX["命令入口
src/command/index.ts"]
H_BOOK["预约处理器
src/command/handlers/bookEvent.ts"]
H_CANCEL["取消处理器
src/command/handlers/cancel.ts"]
H_EVENTS["活动列表处理器
src/command/handlers/events.ts"]
H_EVENTD["活动详情处理器
src/command/handlers/eventDetails.ts"]
H_HISTORY["历史处理器
src/command/handlers/history.ts"]
H_LOGIN["登录处理器
src/command/handlers/login.ts"]
H_LOGOUT["登出处理器
src/command/handlers/logout.ts"]
H_START["开始处理器
src/command/handlers/start.ts"]
end
subgraph "客户端层"
C_CLIENT["CosmoeClient
src/client/cosmoe.ts"]
end
CMD_INDEX --> H_BOOK
CMD_INDEX --> H_CANCEL
CMD_INDEX --> H_EVENTS
CMD_INDEX --> H_EVENTD
CMD_INDEX --> H_HISTORY
CMD_INDEX --> H_LOGIN
CMD_INDEX --> H_LOGOUT
CMD_INDEX --> H_START
H_BOOK --> C_CLIENT
H_CANCEL --> C_CLIENT
H_EVENTS --> C_CLIENT
H_EVENTD --> C_CLIENT
H_HISTORY --> C_CLIENT
H_LOGIN --> C_CLIENT
H_LOGOUT --> C_CLIENT
H_START --> C_CLIENT
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [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/history.ts](file://src/command/handlers/history.ts#L1-L107)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L1-L75)
- [src/command/handlers/logout.ts](file://src/command/handlers/logout.ts#L1-L34)
- [src/command/handlers/start.ts](file://src/command/handlers/start.ts#L1-L6)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
## 核心组件
- 命令入口与路由:集中注册命令与回调查询,绑定 KV 存储用于会话与凭证持久化。
- 预约处理器:解析 /book_{event_id}_{slot_id},校验用户登录状态,拉取活动详情与时间槽,支持优惠券选择与自动下单。
- 取消处理器:解析 /cancel_{booking_id},展示确认键盘,二次确认后调用取消接口。
- 客户端封装:统一的 CosmoeClient 提供认证、事件查询、预约、取消等能力,并维护认证状态。
- 会话与存储:通过 KV 适配器为会话与对话状态提供持久化。
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L118)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L11-L84)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
## 架构总览
命令到 API 的整体调用链如下:
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "命令入口
src/command/index.ts"
participant HB as "预约处理器
src/command/handlers/bookEvent.ts"
participant HC as "取消处理器
src/command/handlers/cancel.ts"
participant CC as "CosmoeClient
src/client/cosmoe.ts"
participant KV as "KV 存储"
U->>B : 发送命令 /book_{event_id}_{slot_id}
B->>HB : 路由到预约处理器
HB->>KV : 读取用户凭证
KV-->>HB : 返回凭证
HB->>CC : 获取活动详情与时间槽
CC-->>HB : 返回活动数据
HB->>U : 展示优惠券选择键盘如适用
U->>B : 回调选择优惠券
B->>HB : 调用优惠券选择处理器
HB->>CC : 下单含可选优惠券
CC-->>HB : 返回下单结果
HB-->>U : 成功/失败消息
U->>B : 发送命令 /cancel_{booking_id}
B->>HC : 路由到取消处理器
HC->>CC : 查询我的预约
CC-->>HC : 返回预约列表
HC->>U : 展示取消确认键盘
U->>B : 回调确认取消
B->>HC : 调用取消确认处理器
HC->>CC : 执行取消
CC-->>HC : 返回取消结果
HC-->>U : 成功/失败消息
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L77-L105)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L11-L118)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L11-L84)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L270)
## 详细组件分析
### 预约命令 /book_{event_id}_{slot_id}
- 命令解析:使用正则匹配 /book_{event_id}_{slot_index},提取活动 ID 与时间槽索引。
- 认证检查:从 KV 中读取用户凭证,若无则提示先登录。
- 活动与时间槽:调用客户端获取活动详情,按 range 排序,校验索引有效性与剩余容量。
- 优惠券应用:
- 若存在多个可用优惠券,生成内联键盘让用户选择;支持“不使用优惠券”选项。
- 若仅有一个优惠券,自动应用;若无优惠券,则直接下单。
- 下单流程:构造下单请求(event_id、time_slot、可选 coupon_code),调用客户端下单接口,返回最终价格、预约编号等信息并反馈给用户。
```mermaid
flowchart TD
Start(["进入 /book_{event_id}_{slot_id}"]) --> Parse["解析命令参数
提取 event_id, slot_index"]
Parse --> CheckAuth["从 KV 读取用户凭证"]
CheckAuth --> HasAuth{"有凭证?"}
HasAuth --> |否| PromptLogin["提示先登录"] --> End
HasAuth --> |是| FetchEvent["获取活动详情与时间槽"]
FetchEvent --> ValidateIndex{"索引有效且有余量?"}
ValidateIndex --> |否| ShowError["提示错误并结束"] --> End
ValidateIndex --> |是| CheckCoupons{"是否有可用优惠券?"}
CheckCoupons --> |多张| ShowKeyboard["展示优惠券选择键盘"] --> End
CheckCoupons --> |一张| AutoApply["自动应用唯一优惠券"]
CheckCoupons --> |无| NoCoupon["不使用优惠券"]
AutoApply --> PlaceOrder["调用下单接口"]
NoCoupon --> PlaceOrder
PlaceOrder --> OrderOK{"下单成功?"}
OrderOK --> |是| ReplySuccess["回复成功消息含最终价格/编号/优惠码"] --> End
OrderOK --> |否| ReplyFail["回复失败消息"] --> End
```
图表来源
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L17-L117)
- [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/client/cosmoe.ts](file://src/client/cosmoe.ts#L191-L270)
### 取消命令 /cancel_{booking_id}
- 命令解析:使用正则匹配 /cancel_{booking_id},提取预约 ID。
- 认证检查:从 KV 读取凭证,确保已登录。
- 预约确认:调用客户端获取我的预约,查找目标预约,不存在则提示。
- 确认流程:生成“确认/取消”内联键盘,展示预约详情与风险提示。
- 取消执行:用户确认后调用取消接口,返回结果并更新消息。
```mermaid
sequenceDiagram
participant U as "用户"
participant B as "命令入口"
participant HC as "取消处理器"
participant CC as "CosmoeClient"
participant KV as "KV 存储"
U->>B : 发送 /cancel_{booking_id}
B->>HC : 路由到取消处理器
HC->>KV : 读取用户凭证
KV-->>HC : 返回凭证
HC->>CC : 获取我的预约
CC-->>HC : 返回预约列表
HC->>U : 展示确认键盘
U->>B : 回调 confirm_cancel 或 cancel_action
alt 确认取消
B->>HC : 调用取消确认处理器
HC->>CC : 执行取消
CC-->>HC : 返回取消结果
HC-->>U : 更新为成功/失败消息
else 取消
HC-->>U : 更新为已取消
end
```
图表来源
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L17-L84)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L87-L132)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L226-L239)
- [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#L226-L239)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L405-L422)
### 活动与时间槽展示
- /events:列出最近的摄影活动,每个活动附带跳转到详情页的命令链接。
- /event_{id}:获取活动详情,排序时间槽并显示剩余/容量;对可预约且当天或之前的时间槽,提供对应的 /book_{event_id}_{slot_index} 链接。
章节来源
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L4-L26)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L10-L60)
### 历史与登录/登出
- /history:获取用户预约历史,按时间倒序取最新若干条,对可取消的预约显示 /cancel_{booking_id} 链接。
- /login:交互式登录,向 Cosmoe API 获取 token 并存入 KV。
- /logout:删除 KV 中的用户凭证。
- /start:欢迎信息与可用命令提示。
章节来源
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L4-L106)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L13-L74)
- [src/command/handlers/logout.ts](file://src/command/handlers/logout.ts#L10-L33)
- [src/command/handlers/start.ts](file://src/command/handlers/start.ts#L4-L5)
## 依赖关系分析
- 命令入口依赖各处理器与 KV 存储,负责命令与回调查询的路由。
- 处理器依赖 CosmoeClient 进行 API 调用,并依赖 KV 存储进行凭证与会话持久化。
- 客户端封装统一的 API 行为,包括认证状态检查与错误处理。
```mermaid
graph LR
CMD_INDEX["src/command/index.ts"] --> H_BOOK["src/command/handlers/bookEvent.ts"]
CMD_INDEX --> H_CANCEL["src/command/handlers/cancel.ts"]
CMD_INDEX --> H_EVENTS["src/command/handlers/events.ts"]
CMD_INDEX --> H_EVENTD["src/command/handlers/eventDetails.ts"]
CMD_INDEX --> H_HISTORY["src/command/handlers/history.ts"]
CMD_INDEX --> H_LOGIN["src/command/handlers/login.ts"]
CMD_INDEX --> H_LOGOUT["src/command/handlers/logout.ts"]
CMD_INDEX --> H_START["src/command/handlers/start.ts"]
H_BOOK --> C_CLIENT["src/client/cosmoe.ts"]
H_CANCEL --> C_CLIENT
H_EVENTS --> C_CLIENT
H_EVENTD --> C_CLIENT
H_HISTORY --> C_CLIENT
H_LOGIN --> C_CLIENT
H_LOGOUT --> C_CLIENT
H_START --> C_CLIENT
```
图表来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L1-L226)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L1-L132)
- [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/history.ts](file://src/command/handlers/history.ts#L1-L107)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L1-L75)
- [src/command/handlers/logout.ts](file://src/command/handlers/logout.ts#L1-L34)
- [src/command/handlers/start.ts](file://src/command/handlers/start.ts#L1-L6)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
## 性能考虑
- API 调用频率:活动列表、详情、预约历史、下单与取消均涉及网络请求,建议在处理器中避免重复请求,必要时缓存短期结果。
- 消息长度限制:历史消息可能较长,已做截断处理,避免超出 Telegram API 限制。
- KV 存储:凭证与会话存储在 KV 中,注意键空间命名与过期策略,避免无限增长。
- 时间计算:活动日与当前时间比较使用北京时间偏移,确保本地化正确性。
章节来源
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L94-L97)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L23-L35)
## 故障排查指南
- 命令未响应
- 检查命令是否被正确注册与路由(命令入口)。
- 确认回调查询正则匹配是否正确。
- 无法登录
- 确认 /login 是否成功写入 KV,检查凭证格式与有效期。
- 预约失败
- 检查时间槽剩余容量与索引合法性。
- 确认优惠券是否仍有效且适用于该活动。
- 取消失败
- 确认预约是否存在且状态允许取消。
- 检查回调数据格式与解析逻辑。
- 错误处理策略
- 所有处理器均包含 try/catch,出现异常时回复通用错误消息并记录日志。
- 客户端方法在未认证时抛出错误,需在调用前确保已设置凭证。
章节来源
- [src/command/index.ts](file://src/command/index.ts#L77-L105)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L114-L117)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L80-L83)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L207-L209)
## 结论
该预约系统通过清晰的命令分发与处理器职责划分,结合 KV 存储与客户端封装,实现了从活动浏览、时间槽选择、优惠券应用到预约与取消的完整闭环。系统具备良好的可扩展性与错误处理能力,适合在此基础上进一步增强并发控制、状态机与审计日志。
## 附录
### 命令一览与行为
- /start:欢迎信息与可用命令提示。
- /events:列出最近活动,附带 /event_{id} 链接。
- /event_{id}:展示活动详情与时间槽,提供 /book_{event_id}_{slot_index} 链接。
- /book_{event_id}_{slot_index}:预约创建,支持优惠券选择与自动下单。
- /history:展示预约历史,对可取消项提供 /cancel_{booking_id} 链接。
- /cancel_{booking_id}:取消预约,二次确认后执行。
- /login:交互式登录,保存凭证至 KV。
- /logout:删除 KV 中的用户凭证。
章节来源
- [src/command/handlers/start.ts](file://src/command/handlers/start.ts#L4-L5)
- [src/command/handlers/events.ts](file://src/command/handlers/events.ts#L4-L26)
- [src/command/handlers/eventDetails.ts](file://src/command/handlers/eventDetails.ts#L10-L60)
- [src/command/handlers/bookEvent.ts](file://src/command/handlers/bookEvent.ts#L17-L117)
- [src/command/handlers/history.ts](file://src/command/handlers/history.ts#L4-L106)
- [src/command/handlers/cancel.ts](file://src/command/handlers/cancel.ts#L17-L84)
- [src/command/handlers/login.ts](file://src/command/handlers/login.ts#L13-L74)
- [src/command/handlers/logout.ts](file://src/command/handlers/logout.ts#L10-L33)
### 数据模型与 API 关键点
- CosmoeClient 提供认证、事件、预约、取消等方法,内部维护 userId 与 token。
- 预约请求包含 event_id、time_slot、可选 coupon_code。
- 预约响应包含最终价格、预约编号等字段,便于回执展示。
章节来源
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
### 并发控制与状态管理
- 当前实现未显式引入分布式锁或队列,建议在关键路径(如下单)增加幂等键与重试策略,避免重复提交。
- 使用 KV 存储会话与凭证,注意键冲突与并发读写的一致性问题。
- 对于高并发场景,可在客户端层引入重试与退避策略,并在处理器中对同一用户的连续请求进行限流。
章节来源
- [src/command/index.ts](file://src/command/index.ts#L21-L52)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L247-L269)
### 扩展开发指导
- 新增命令:在命令入口注册新命令与回调查询,编写处理器文件并在入口中导入。
- 新增 API:在 CosmoeClient 中新增方法,遵循现有认证与错误处理模式。
- 优化体验:引入会话状态机管理多步流程,减少 KV 读写次数;对长消息进行分片发送。
- 安全加固:对命令输入进行更严格的校验与白名单过滤;对敏感操作增加二次确认与审计日志。
章节来源
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
- [package.json](file://package.json#L18-L22)