Files
game_server/docs/退单接口使用说明.md
zyh 02c64b3a38 feat: 新增退单操作接口及相关逻辑
主要修改:
1. 在LinkController中新增退单操作接口,支持用户对指定链接进行退单。
2. 在LinkStatusService中实现退单逻辑,确保用户只能退单自己的链接,并更新链接状态。
3. 在ScriptClient中新增调用退单接口的方法,处理与外部系统的交互。

技术细节:
- 通过新增的退单功能,提升了用户对链接的管理能力,确保操作的安全性和有效性。
2025-08-27 19:07:37 +08:00

294 lines
8.3 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.

# 退单接口使用说明
## 📋 功能概述
退单接口允许代理用户对自己创建的链接进行退单操作。执行退单时,系统会:
1. 调用外部脚本退单接口:`http://36.138.184.60:1234/yijianwan_netfile/saveMsg?文件名=判断退单&cc2={machineId}`
2. 将链接状态更新为 `REFUNDED`
3. 记录退单时间
## 🔧 接口详情
### 基本信息
- **请求方式**: `POST`
- **请求路径**: `/api/link/{codeNo}/refund`
- **认证方式**: JWT Bearer Token
- **返回类型**: `application/json`
### 请求参数
#### 路径参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| codeNo | String | 是 | 链接编号 |
#### 请求头
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| Authorization | String | 是 | JWT认证令牌格式`Bearer {token}` |
### 响应格式
#### 成功响应 (HTTP 200)
```json
{
"data": true,
"success": true,
"message": "操作成功"
}
```
#### 错误响应
```json
{
"success": false,
"message": "错误详情",
"code": "错误代码"
}
```
## 📝 使用示例
### 1. 基本退单操作
```bash
curl -X POST 'http://localhost:8080/api/link/ABC12345/refund' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...' \
-H 'Content-Type: application/json'
```
**成功响应:**
```json
{
"data": true,
"success": true,
"message": "退单操作成功"
}
```
### 2. JavaScript 示例
```javascript
async function refundOrder(codeNo, jwt_token) {
try {
const response = await fetch(`http://localhost:8080/api/link/${codeNo}/refund`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${jwt_token}`,
'Content-Type': 'application/json'
}
});
const result = await response.json();
if (result.success) {
console.log('退单成功');
return true;
} else {
console.error('退单失败:', result.message);
return false;
}
} catch (error) {
console.error('退单请求失败:', error);
return false;
}
}
// 使用示例
refundOrder('ABC12345', 'your_jwt_token');
```
### 3. Python 示例
```python
import requests
def refund_order(code_no, jwt_token):
"""执行退单操作"""
url = f'http://localhost:8080/api/link/{code_no}/refund'
headers = {
'Authorization': f'Bearer {jwt_token}',
'Content-Type': 'application/json'
}
try:
response = requests.post(url, headers=headers)
response.raise_for_status()
result = response.json()
if result.get('success'):
print('退单成功')
return True
else:
print(f'退单失败: {result.get("message")}')
return False
except requests.exceptions.RequestException as e:
print(f'退单请求失败: {e}')
return False
# 使用示例
refund_order('ABC12345', 'your_jwt_token')
```
## 🚫 错误处理
### 常见错误类型
| 错误码 | HTTP状态 | 错误信息 | 说明 |
|-------|---------|---------|------|
| AUTH_001 | 401 | 用户未认证 | JWT令牌无效或过期 |
| LINK_001 | 400 | 链接不存在 | 指定的链接编号不存在 |
| LINK_002 | 400 | 权限不足 | 用户无权操作此链接 |
| LINK_003 | 400 | 链接已经退过单 | 不能重复退单 |
| LINK_004 | 400 | 过期链接不允许退单 | 链接已过期 |
| LINK_005 | 400 | 已完成链接不允许退单 | 游戏已完成的链接 |
### 错误处理示例
```javascript
async function handleRefund(codeNo, token) {
try {
const response = await fetch(`/api/link/${codeNo}/refund`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
const result = await response.json();
if (!result.success) {
switch (result.code) {
case 'LINK_003':
alert('此链接已经退过单了');
break;
case 'LINK_004':
alert('过期链接无法退单');
break;
case 'LINK_005':
alert('已完成的游戏无法退单');
break;
default:
alert('退单失败: ' + result.message);
}
return false;
}
alert('退单成功');
return true;
} catch (error) {
console.error('退单请求失败:', error);
alert('网络错误,请稍后重试');
return false;
}
}
```
## 🔄 状态流转
### 允许退单的状态
- `NEW` (新建)
- `USING` (使用中)
- `LOGGED_IN` (已登录)
### 不允许退单的状态
- `REFUNDED` (已退款) - 已经退过单
- `EXPIRED` (已过期) - 链接已过期
- `COMPLETED` (已完成) - 游戏已完成
### 状态流转图
```
NEW/USING/LOGGED_IN → [退单操作] → REFUNDED (最终状态)
```
## 📊 业务逻辑
### 退单流程
1. **身份验证**
- 验证JWT令牌有效性
- 确认用户有权限操作该链接
2. **状态检查**
- 检查链接是否存在
- 检查链接当前状态是否允许退单
3. **外部接口调用**
- 如果链接有关联设备,调用脚本端退单接口
- URL格式`http://36.138.184.60:1234/yijianwan_netfile/saveMsg?文件名=判断退单&cc2={真实设备ID}`
- 即使外部接口调用失败,仍会更新数据库状态
4. **数据库更新**
- 更新链接状态为 `REFUNDED`
- 记录退单时间 `refund_at`
- 更新修改时间 `updated_at`
### 注意事项
1. **权限控制**: 用户只能退单自己创建的链接
2. **状态限制**: 只有特定状态的链接才能退单
3. **重复操作**: 已退单的链接不能再次退单
4. **外部接口**: 即使外部接口调用失败,也会更新本地状态,避免用户重复操作
5. **事务性**: 整个退单操作在事务中执行,确保数据一致性
## 🧪 测试示例
### 完整测试流程
```bash
# 1. 登录获取JWT令牌
curl -X POST 'http://localhost:8080/api/auth/login' \
-H 'Content-Type: application/json' \
-d '{"username":"test_user","password":"password"}'
# 2. 生成测试链接
curl -X POST 'http://localhost:8080/api/link/generate' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"times":1,"linkCount":1}'
# 3. 查看链接状态 (退单前)
curl -X GET 'http://localhost:8080/api/link/YOUR_CODE_NO/status'
# 4. 执行退单操作
curl -X POST 'http://localhost:8080/api/link/YOUR_CODE_NO/refund' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'
# 5. 查看链接状态 (退单后应该是REFUNDED状态)
curl -X GET 'http://localhost:8080/api/link/YOUR_CODE_NO/status'
```
## 🔍 日志示例
### 成功退单日志
```
2024-01-15 14:30:00.123 INFO LinkStatusService - === 开始处理退单操作 ===
2024-01-15 14:30:00.124 INFO LinkStatusService - 链接编号: ABC12345, 代理ID: 1001
2024-01-15 14:30:00.125 INFO LinkStatusService - 链接关联设备: f1, 调用脚本端退单接口
2024-01-15 14:30:00.234 INFO ScriptClient - 调用退单接口: 设备=f1, url=http://36.138.184.60:1234/yijianwan_netfile/saveMsg?文件名=判断退单&cc2=f1
2024-01-15 14:30:00.567 INFO ScriptClient - 退单接口调用成功: 设备=f1, 结果=SUCCESS
2024-01-15 14:30:00.580 INFO LinkStatusService - 退单操作成功: codeNo=ABC12345, 设备=f1, 状态更新为REFUNDED
2024-01-15 14:30:00.581 INFO LinkStatusService - === 退单操作完成 ===
```
### 失败退单日志
```
2024-01-15 14:30:00.123 INFO LinkStatusService - === 开始处理退单操作 ===
2024-01-15 14:30:00.124 INFO LinkStatusService - 链接编号: ABC12345, 代理ID: 1001
2024-01-15 14:30:00.125 WARN LinkStatusService - 链接已经退过单: codeNo=ABC12345, status=REFUNDED
2024-01-15 14:30:00.126 ERROR LinkStatusService - === 退单操作失败 ===
2024-01-15 14:30:00.127 ERROR LinkStatusService - codeNo=ABC12345, agentId=1001, 错误详情: 链接已经退过单
```
## 🔗 相关接口
- [链接生成接口](./API文档.md#链接生成)
- [链接状态查询接口](./链接状态接口测试.md)
- [链接列表接口](./链接列表接口测试.md)
- [JWT认证说明](./JWT认证使用说明.md)