feat: 支持我参与的接口
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
## Changelog
|
||||
|
||||
- 2026-05-14: 新增 `GET /api/v1/share/participated` 我参与的挑战列表接口,返回挑战名称、已提交参与人数和当前用户名次。
|
||||
- 2026-05-13: 新增 `GET /api/v1/share/{code}` 分享挑战详情接口,返回挑战基本信息和所有已提交用户的排行榜;排行榜项包含用户头像、昵称、答对题数和总耗时。
|
||||
- 2026-05-12: `GET /api/v1/share/created` 响应新增 `firstPlaceUser`,返回每个挑战当前第一名用户的昵称和头像;暂无提交结果时为 `null`。
|
||||
- 2026-05-10: 移除 `POST /api/v1/share/progress` 单关进度上报接口;新增 `POST /api/v1/share/{code}/submit`,客户端一次提交整场挑战的每关答案和耗时,服务端校验答案后返回排名、答对题数、参与人数和完整关卡答案,并持久化提交结果。
|
||||
@@ -31,7 +32,8 @@
|
||||
3. **挑战结果返回**:提交后返回当前用户排名、答对题数、参与人数、总耗时和每关校验结果
|
||||
4. **分享挑战详情**:`GET /api/v1/share/{code}` 接口,用于查询单个挑战的基本信息和完整排行榜
|
||||
5. **我创建的挑战列表**:`GET /api/v1/share/created` 接口,用于查询当前用户创建过的分享挑战、参与人数、本人排名和当前第一名用户信息
|
||||
6. **关卡排序**:关卡全局顺序按 `levels.sort_key` 的应用层字节序计算,接口中的 `sortOrder` 为排序后的 0-based 连续序号
|
||||
6. **我参与的挑战列表**:`GET /api/v1/share/participated` 接口,用于查询当前用户参与过的分享挑战、参与人数和本人排名
|
||||
7. **关卡排序**:关卡全局顺序按 `levels.sort_key` 的应用层字节序计算,接口中的 `sortOrder` 为排序后的 0-based 连续序号
|
||||
|
||||
---
|
||||
|
||||
@@ -393,7 +395,7 @@ Content-Type: application/json
|
||||
**客户端调用场景**:
|
||||
|
||||
- 用户打开单个挑战详情页或结算页时调用。
|
||||
- 需要展示完整排行榜时调用;列表页仍使用 `GET /api/v1/share/created`。
|
||||
- 需要展示完整排行榜时调用;列表页使用 `GET /api/v1/share/created` 或 `GET /api/v1/share/participated`。
|
||||
|
||||
---
|
||||
|
||||
@@ -493,7 +495,78 @@ Authorization: Bearer <token>
|
||||
|
||||
---
|
||||
|
||||
### 6. 提交分享挑战结果
|
||||
### 6. 获取我参与的分享挑战
|
||||
|
||||
获取当前登录用户参与过的分享挑战列表。
|
||||
|
||||
**接口地址**:`GET /api/v1/share/participated`
|
||||
|
||||
**是否需要认证**:是(JWT Bearer Token)
|
||||
|
||||
**请求头**:
|
||||
|
||||
```
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应数据**:
|
||||
|
||||
```typescript
|
||||
{
|
||||
items: [
|
||||
{
|
||||
title: string; // 挑战名称
|
||||
participantCount: number; // 已提交结果的参与人数
|
||||
userRank: number | null; // 当前用户在该挑战中的排名;尚未提交结果时为 null
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**成功响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"items": [
|
||||
{
|
||||
"title": "好友挑战",
|
||||
"participantCount": 5,
|
||||
"userRank": 3
|
||||
},
|
||||
{
|
||||
"title": "速度挑战",
|
||||
"participantCount": 1,
|
||||
"userRank": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"message": null,
|
||||
"timestamp": "2026-05-14T12:00:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
**排名规则**:
|
||||
|
||||
1. 列表只返回当前用户在 `share_participants` 中有参与记录的挑战。
|
||||
2. 只有已经调用 `POST /api/v1/share/{code}/submit` 提交整场挑战结果的用户才会进入排名。
|
||||
3. 排名按答对题数降序计算,答对题数相同时,按总耗时升序、提交时间升序、`participantId` 升序做稳定排序。
|
||||
4. `userRank` 表示当前登录用户在该挑战中的排名。如果当前用户已加入但尚未提交挑战结果,则返回 `null`。
|
||||
|
||||
**参与人数统计规则**:
|
||||
|
||||
- 统计该挑战中已提交完整挑战结果的用户数量。
|
||||
- 创建者本人如果调用提交接口,也会作为参与用户进入统计和排名。
|
||||
|
||||
**客户端调用场景**:
|
||||
|
||||
- 用户进入「我参与的挑战」页面时调用。
|
||||
- 列表只展示挑战名称、参与人数和当前用户名次。
|
||||
|
||||
---
|
||||
|
||||
### 7. 提交分享挑战结果
|
||||
|
||||
用户完成分享挑战后,一次性提交分享中每一关的耗时和答案。服务端校验答案、持久化结果,并返回当前用户的排名和完整关卡答案。
|
||||
|
||||
@@ -966,7 +1039,49 @@ console.log(`当前排名: ${detail.userRank ?? '暂未上榜'}`);
|
||||
console.log(`已提交人数: ${detail.participantCount}`);
|
||||
```
|
||||
|
||||
### 6. 提交挑战结果
|
||||
### 6. 获取我参与的挑战列表
|
||||
|
||||
```typescript
|
||||
interface ParticipatedShareItem {
|
||||
title: string;
|
||||
participantCount: number;
|
||||
userRank: number | null;
|
||||
}
|
||||
|
||||
interface ParticipatedShareListResponse {
|
||||
items: ParticipatedShareItem[];
|
||||
}
|
||||
|
||||
async function getParticipatedShares(): Promise<ParticipatedShareListResponse> {
|
||||
// 确保已登录
|
||||
if (!httpManager.getToken()) {
|
||||
await wxLogin();
|
||||
}
|
||||
|
||||
const response = await httpManager.get<ParticipatedShareListResponse>(
|
||||
'/v1/share/participated',
|
||||
);
|
||||
|
||||
if (response.success && response.data) {
|
||||
console.log('我参与的挑战:', response.data.items);
|
||||
return response.data;
|
||||
} else {
|
||||
throw new Error(response.message || '获取我参与的挑战失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
const participatedShares = await getParticipatedShares();
|
||||
participatedShares.items.forEach((item) => {
|
||||
console.log(
|
||||
`${item.title}: ${item.participantCount} 人参与,当前排名 ${
|
||||
item.userRank ?? '暂未上榜'
|
||||
}`,
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
### 7. 提交挑战结果
|
||||
|
||||
```typescript
|
||||
interface SubmitChallengeLevel {
|
||||
@@ -1033,7 +1148,7 @@ async function onChallengeFinished() {
|
||||
}
|
||||
```
|
||||
|
||||
### 7. 启动流程示例
|
||||
### 8. 启动流程示例
|
||||
|
||||
```typescript
|
||||
// GameEntry.ts - 游戏入口脚本
|
||||
|
||||
Reference in New Issue
Block a user