# 退单接口使用说明 ## 📋 功能概述 退单接口允许代理用户对自己创建的链接进行退单操作。执行退单时,系统会: 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)