253 lines
5.5 KiB
Markdown
253 lines
5.5 KiB
Markdown
# 链接状态接口兼容性说明
|
||
|
||
## 概述
|
||
|
||
为了解决链接复制粘贴时参数丢失的问题,同时保证向后兼容,系统现在支持两种访问格式:
|
||
1. **路径参数格式**(推荐):`/api/link/{code}/status`
|
||
2. **查询参数格式**(兼容旧版):`/api/link/status?code={code}`
|
||
|
||
## 支持的访问方式
|
||
|
||
### 方式一:路径参数(推荐 ⭐)
|
||
|
||
**接口:** `GET /api/link/{code}/status`
|
||
|
||
**示例:**
|
||
```bash
|
||
curl http://localhost:8080/api/link/ABC12345/status
|
||
```
|
||
|
||
```javascript
|
||
// JavaScript
|
||
fetch('/api/link/ABC12345/status')
|
||
```
|
||
|
||
**优势:**
|
||
- ✅ 复制粘贴时不会丢失参数
|
||
- ✅ 符合 RESTful 设计规范
|
||
- ✅ URL 结构更清晰
|
||
- ✅ 浏览器地址栏直接可见完整路径
|
||
|
||
---
|
||
|
||
### 方式二:查询参数(兼容旧版)
|
||
|
||
**接口:** `GET /api/link/status`
|
||
|
||
**支持的参数:**
|
||
- `code` - 链接编号(推荐)
|
||
- `codeNo` - 链接编号(别名)
|
||
- `linkId` - 链接数据库ID
|
||
|
||
**示例:**
|
||
|
||
```bash
|
||
# 使用 code 参数
|
||
curl "http://localhost:8080/api/link/status?code=ABC12345"
|
||
|
||
# 使用 codeNo 参数
|
||
curl "http://localhost:8080/api/link/status?codeNo=ABC12345"
|
||
|
||
# 使用 linkId 参数
|
||
curl "http://localhost:8080/api/link/status?linkId=123"
|
||
```
|
||
|
||
```javascript
|
||
// JavaScript
|
||
fetch('/api/link/status?code=ABC12345')
|
||
fetch('/api/link/status?codeNo=ABC12345')
|
||
fetch('/api/link/status?linkId=123')
|
||
```
|
||
|
||
**说明:**
|
||
- `linkId` 和 `code/codeNo` 至少提供一个即可
|
||
- 如果同时提供,优先使用 `codeNo`,其次是 `code`
|
||
|
||
---
|
||
|
||
## 响应格式
|
||
|
||
两种方式返回完全相同的数据结构:
|
||
|
||
```json
|
||
{
|
||
"status": "NEW",
|
||
"machineId": null
|
||
}
|
||
```
|
||
|
||
**status 可能的值:**
|
||
- `NEW` - 新建
|
||
- `USING` - 使用中(前端会显示为 NEW)
|
||
- `LOGGED_IN` - 已登录
|
||
- `COMPLETED` - 已完成
|
||
- `REFUNDED` - 已退款
|
||
- `EXPIRED` - 已过期
|
||
|
||
---
|
||
|
||
## 测试用例
|
||
|
||
### 测试 1:路径参数方式
|
||
|
||
```bash
|
||
# 假设有一个 codeNo 为 ABC12345 的链接
|
||
curl http://localhost:8080/api/link/ABC12345/status
|
||
```
|
||
|
||
**期望结果:** 返回链接状态信息
|
||
|
||
---
|
||
|
||
### 测试 2:查询参数方式(code)
|
||
|
||
```bash
|
||
curl "http://localhost:8080/api/link/status?code=ABC12345"
|
||
```
|
||
|
||
**期望结果:** 返回与测试1相同的结果
|
||
|
||
---
|
||
|
||
### 测试 3:查询参数方式(codeNo)
|
||
|
||
```bash
|
||
curl "http://localhost:8080/api/link/status?codeNo=ABC12345"
|
||
```
|
||
|
||
**期望结果:** 返回与测试1相同的结果
|
||
|
||
---
|
||
|
||
### 测试 4:查询参数方式(linkId)
|
||
|
||
```bash
|
||
# 假设链接的数据库 ID 为 123
|
||
curl "http://localhost:8080/api/link/status?linkId=123"
|
||
```
|
||
|
||
**期望结果:** 返回链接状态信息
|
||
|
||
---
|
||
|
||
### 测试 5:错误处理
|
||
|
||
```bash
|
||
# 不存在的链接
|
||
curl http://localhost:8080/api/link/INVALID/status
|
||
|
||
# 空参数
|
||
curl "http://localhost:8080/api/link/status?code="
|
||
|
||
# 缺少参数
|
||
curl "http://localhost:8080/api/link/status"
|
||
```
|
||
|
||
**期望结果:** 返回错误信息
|
||
|
||
---
|
||
|
||
## 迁移建议
|
||
|
||
### 对于新开发的前端
|
||
|
||
**推荐使用路径参数格式:**
|
||
```javascript
|
||
const codeNo = 'ABC12345';
|
||
const response = await fetch(`/api/link/${codeNo}/status`);
|
||
```
|
||
|
||
### 对于现有系统
|
||
|
||
**无需修改,查询参数格式继续有效:**
|
||
```javascript
|
||
// 继续使用旧格式
|
||
const response = await fetch(`/api/link/status?code=${codeNo}`);
|
||
```
|
||
|
||
### 渐进式迁移
|
||
|
||
可以逐步将旧代码迁移到新格式:
|
||
|
||
```javascript
|
||
// 旧代码
|
||
async function getLinkStatus_Old(codeNo) {
|
||
return fetch(`/api/link/status?code=${codeNo}`);
|
||
}
|
||
|
||
// 新代码(推荐)
|
||
async function getLinkStatus_New(codeNo) {
|
||
return fetch(`/api/link/${codeNo}/status`);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 后端实现说明
|
||
|
||
### Controller 方法
|
||
|
||
系统提供了两个独立的 Controller 方法:
|
||
|
||
1. **getUserLinkStatusByPath** - 处理路径参数请求
|
||
- 路由:`GET /api/link/{code}/status`
|
||
- 参数:`@PathVariable String code`
|
||
|
||
2. **getUserLinkStatusByQuery** - 处理查询参数请求
|
||
- 路由:`GET /api/link/status`
|
||
- 参数:`@RequestParam Long linkId`, `@RequestParam String codeNo`, `@RequestParam String code`
|
||
|
||
### 日志区分
|
||
|
||
两个方法使用不同的日志标识,便于问题排查:
|
||
- 路径参数:`=== 用户端获取链接状态(路径参数) ===`
|
||
- 查询参数:`=== 用户端获取链接状态(查询参数,兼容模式) ===`
|
||
|
||
---
|
||
|
||
## 兼容性保证
|
||
|
||
- ✅ 两种格式返回完全相同的数据结构
|
||
- ✅ 旧链接继续有效,无需修改
|
||
- ✅ 新生成的链接推荐使用路径参数格式
|
||
- ✅ 系统会长期维护两种格式的支持
|
||
- ✅ 不会影响现有功能和性能
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### Q1: 为什么推荐使用路径参数格式?
|
||
|
||
**A:** 路径参数格式的优势:
|
||
1. 复制粘贴 URL 时不会丢失参数(查询参数容易在 `?` 后被截断)
|
||
2. 符合 RESTful API 设计规范
|
||
3. URL 更清晰,更容易阅读和理解
|
||
4. 浏览器地址栏显示更完整
|
||
|
||
### Q2: 旧链接会失效吗?
|
||
|
||
**A:** 不会。查询参数格式会长期保持支持,确保兼容性。
|
||
|
||
### Q3: 能否混合使用两种格式?
|
||
|
||
**A:** 可以。同一个应用中可以同时使用两种格式,系统都会正确处理。
|
||
|
||
### Q4: 性能上有区别吗?
|
||
|
||
**A:** 没有。两种格式调用相同的底层服务方法,性能完全一致。
|
||
|
||
### Q5: 如何在 Swagger/OpenAPI 中查看?
|
||
|
||
**A:** Swagger UI 会显示两个独立的接口:
|
||
- `GET /api/link/{code}/status` - 推荐格式
|
||
- `GET /api/link/status` - 兼容格式
|
||
|
||
---
|
||
|
||
## 更新日志
|
||
|
||
- **2025-10-21**:添加路径参数格式支持,同时保留查询参数格式兼容性
|
||
- 旧的查询参数格式标记为"兼容模式",推荐新项目使用路径参数格式
|
||
|