Files
doucan/API.md
wtz 97e03acbe2 fix: 修复牌型识别、获胜显示、出牌区布局、移动端重连
1. 牌型识别: 新增三带一对、飞机、飞机带单/带对、四带二、四带两对
2. 获胜显示: 先显示最后出牌1秒后再弹出获胜对话框
3. 出牌区布局: 横向排列并换行
4. 移动端重连: 切回前台时自动重连WebSocket
5. 更新文档: README.md和API.md补充新增牌型
2026-02-22 10:00:13 +08:00

448 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 斗地主残局版 API 文档
## 基础信息
- 基础URL: `http://<host>/api`
- 响应格式: JSON
## 响应格式
所有API响应遵循统一格式:
```json
{
"status": 200,
"code": 0,
"message": "success",
"data": { ... }
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| status | int | HTTP状态码 |
| code | int | 业务状态码 (0=成功, 1=失败) |
| message | string | 提示信息 |
| data | object | 实际业务数据 |
---
## 认证相关 API
### 获取验证码
**GET** `/api/auth/captcha`
响应:
```json
{
"status": 200,
"code": 0,
"message": "success",
"data": {
"captchaId": "abc123",
"image": "data:image/png;base64,..."
}
}
```
### 用户注册
**POST** `/api/auth/register`
请求体:
```json
{
"username": "testuser",
"password": "123456",
"nickname": "测试玩家",
"captcha": "ABCD",
"captchaId": "abc123"
}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| username | string | 是 | 用户名3-20字符 |
| password | string | 是 | 密码至少6位 |
| nickname | string | 是 | 昵称 |
| captcha | string | 是 | 验证码 |
| captchaId | string | 是 | 验证码ID |
响应:
```json
{
"status": 200,
"code": 0,
"message": "success",
"data": {
"token": "xxx",
"userId": "xxx",
"username": "testuser",
"nickname": "测试玩家"
}
}
```
### 用户登录
**POST** `/api/auth/login`
请求体:
```json
{
"username": "testuser",
"password": "123456",
"captcha": "ABCD",
"captchaId": "abc123"
}
```
响应: 同注册
### 验证Token
**GET** `/api/auth/validate`
请求头: `Authorization: Bearer {token}`
响应:
```json
{
"status": 200,
"code": 0,
"message": "success",
"data": {
"userId": "xxx",
"username": "testuser",
"nickname": "测试玩家"
}
}
```
### 退出登录
**POST** `/api/auth/logout`
请求头: `Authorization: Bearer {token}`
---
## 房间相关 API
> 注意: 所有房间相关 API 需要在请求头中携带 `Authorization: Bearer {token}`
### 创建房间
**POST** `/api/rooms`
请求体:
```json
{
"playerName": "玩家昵称",
"maxPlayers": 4
}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| playerName | string | 是 | 玩家昵称 |
| maxPlayers | int | 否 | 最大玩家数默认4范围2-10 |
响应:
```json
{
"status": 200,
"code": 0,
"message": "success",
"data": {
"roomId": "a1b2c3d4e5f6g7h8",
"playerId": "i9j0k1l2m3n4o5p6"
}
}
```
### 加入房间
**POST** `/api/rooms/{roomId}/join`
请求体:
```json
{
"playerName": "玩家昵称"
}
```
响应:
```json
{
"status": 200,
"code": 0,
"message": "success",
"data": {
"roomId": "a1b2c3d4e5f6g7h8",
"playerId": "q7r8s9t0u1v2w3x4"
}
}
```
### 离开房间
**POST** `/api/rooms/leave`
请求头: `Authorization: Bearer {token}`
响应:
```json
{
"status": 200,
"code": 0,
"message": "success",
"data": null
}
```
### 获取当前房间
**GET** `/api/rooms/current`
请求头: `Authorization: Bearer {token}`
用于检查用户当前是否在房间中。如果用户之前创建了房间但未离开,可以获取房间信息并自动重新连接。
响应(在房间中):
```json
{
"status": 200,
"code": 0,
"message": "success",
"data": {
"roomId": "a1b2c3d4",
"playerId": "i9j0k1l2"
}
}
```
响应(不在房间中):
```json
{
"status": 200,
"code": 0,
"message": "success",
"data": null
}
```
### 错误响应示例
```json
{
"status": 400,
"code": 1,
"message": "room not found",
"data": null
}
```
---
## WebSocket API
**连接地址**: `ws://<host>/api/ws?roomId={roomId}&playerId={playerId}`
### 消息格式
所有消息为JSON格式:
```json
{
"type": "消息类型",
"playerId": "玩家ID",
"roomId": "房间ID",
"data": { ... },
"timestamp": 1708123456
}
```
### 消息类型
| 类型 | 方向 | 说明 |
|------|------|------|
| ready | 客户端→服务器 | 准备/取消准备 |
| play | 客户端→服务器 | 出牌 |
| pass | 客户端→服务器 | 不出 |
| chat | 双向 | 聊天消息 |
| state | 服务器→客户端 | 游戏状态更新 |
| gameOver | 服务器→客户端 | 游戏结束 |
| leave | 服务器→客户端 | 玩家离开房间 |
| error | 服务器→客户端 | 错误消息 |
### 准备
```json
{
"type": "ready",
"playerId": "xxx",
"roomId": "xxx",
"data": { "ready": true }
}
```
当所有玩家都准备后,游戏自动开始。
### 出牌
```json
{
"type": "play",
"playerId": "xxx",
"roomId": "xxx",
"data": {
"cards": [
{ "suit": 0, "value": 14 },
{ "suit": 1, "value": 14 }
]
}
}
```
### 不出
```json
{
"type": "pass",
"playerId": "xxx",
"roomId": "xxx"
}
```
注意: 只能在上家出牌后才能"不出",自己最后出牌时不能"不出"。
### 聊天
客户端发送:
```json
{
"type": "chat",
"playerId": "xxx",
"roomId": "xxx",
"data": "消息内容"
}
```
服务器推送:
```json
{
"type": "chat",
"data": {
"playerId": "xxx",
"playerName": "玩家昵称",
"message": "消息内容"
},
"timestamp": 1708123456
}
```
### 游戏状态 (服务器推送)
```json
{
"type": "state",
"data": {
"id": "a1b2c3d4e5f6g7h8",
"players": [
{
"id": "xxx",
"name": "玩家1",
"cards": [...],
"cardCount": 5,
"isReady": true,
"isOnline": true
}
],
"currentTurn": 0,
"state": 1,
"lastPlay": {
"playerId": "xxx",
"cards": [...],
"cardType": 2
},
"roundCount": 1,
"maxPlayers": 4
},
"timestamp": 1708123456
}
```
注意: 只有当前玩家能看到自己的手牌(cards),其他玩家只能看到牌数(cardCount)。
### 游戏结束 (服务器推送)
```json
{
"type": "gameOver",
"data": {
"winnerId": "xxx"
},
"timestamp": 1708123456
}
```
---
## 数据类型
### Card (牌)
| 字段 | 类型 | 说明 |
|------|------|------|
| suit | int | 花色 |
| value | int | 点数 |
花色值:
- 0: 红桃 ♥
- 1: 方块 ♦
- 2: 梅花 ♣
- 3: 黑桃 ♠
- 4: 王 (Joker)
- 5: 超人强 (Super)
点数值:
- 3-10: 对应点数
- 11: J
- 12: Q
- 13: K
- 14: A
- 15: 2
- 16: 小王
- 17: 大王
- 18: 超人强
### CardType (牌型)
| 值 | 说明 |
|----|------|
| 0 | 无效 |
| 1 | 单牌 |
| 2 | 对子 |
| 3 | 三张 (未使用) |
| 4 | 三带一 |
| 5 | 三带一对 |
| 6 | 顺子 |
| 7 | 连对 |
| 8 | 炸弹 |
| 9 | 火箭 |
| 10 | 飞机 |
| 11 | 飞机带单 |
| 12 | 飞机带对 |
| 13 | 四带二 |
| 14 | 四带两对 |
### RoomState (房间状态)
| 值 | 说明 |
|----|------|
| 0 | 等待中 |
| 1 | 游戏中 |
| 2 | 已结束 |