Files
game_server/docs/终端用户文档v2.md
zyh 3847250c2b feat: 添加用户端链接状态查询接口及自动刷新逻辑
主要修改:
1. 在LinkController中新增获取用户链接状态的接口,支持通过linkId或codeNo查询。
2. 在LinkStatusService中实现用户链接状态查询逻辑,包含自动刷新和二维码更新功能。
3. 更新LinkTask实体,添加needRefresh、refreshTime、qrCreatedAt和qrExpireAt字段以支持新功能。
4. 在ScriptClient中新增检查空闲设备、选区、刷新、检查上号状态等操作的实现。
5. 更新SecurityConfig,允许用户端获取链接状态接口公开访问。

技术细节:
- 新增UserLinkStatusResponse DTO以支持用户链接状态的返回格式。
- 通过脚本端接口实现链接状态的自动刷新和二维码信息更新。
2025-08-26 18:07:44 +08:00

3.9 KiB
Raw Permalink Blame History

明白了!让我重新整理接口设计:

后端接口设计文档(最终版)

1. 获取链接状态接口

接口: GET /api/link/status?code={code}

业务逻辑:

  1. 解密和验证code参数包含linkId、签发时间、过期时间等
  2. 检查链接是否过期默认24小时
  3. 从数据库查询链接当前状态
  4. 如果状态不是NEW后端自动执行刷新逻辑
    • 调用脚本端刷新:POST http://36.138.184.60:1234/yijianwan_netfile/saveMsg?文件名=判断刷新&编号=刷新
    • 设置need_refresh=true记录refresh_time
    • 等待10秒或配置的刷新等待时间
    • 执行完毕后继续下面的逻辑
  5. 如果状态为USING重新获取二维码
    • 调用:http://36.138.184.60:12345/{编号}/二维码.png?t={timestamp}
    • 更新qr_created_at和qr_expire_at
  6. 返回链接状态和相关信息

前端调用方式:

// 前端只需要调用一次,后端会自动处理刷新逻辑
const statusResponse = await fetch('/api/link/status?code=' + code);
const status = await statusResponse.json();
// 根据返回的状态直接渲染对应页面

数据库操作:

  • 如果状态不是NEW设置need_refresh=true记录refresh_time
  • 如果状态为USING更新qr_created_at和qr_expire_at

2. 刷新接口(保留,供手动刷新使用)

接口: POST /api/link/refresh 请求体: { code: string }

业务逻辑:

  1. 验证code参数
  2. 调用脚本端刷新
  3. 设置need_refresh=true记录refresh_time
  4. 返回等待时间

使用时机:

  • 用户在扫码页面手动点击"刷新"按钮时

3. 选区接口

接口: POST /api/link/select-region 请求体: { code: string, region: "Q" | "V" }

业务逻辑:

  1. 验证code和region参数
  2. 检查链接状态只有NEW状态才能选区
  3. 如果need_refresh=true检查是否已等待10秒否则返回423错误
  4. 调用脚本端分配空闲设备
  5. 调用脚本端选区
  6. 等待脚本端生成二维码
  7. 更新数据库状态为USING
  8. 返回二维码信息

4. 轮询上号接口

接口: GET /api/link/poll-login?code={code}

业务逻辑:

  1. 验证code参数
  2. 检查链接状态只有USING状态才能轮询
  3. 调用脚本端检查上号状态
  4. 如果返回"已上号"更新状态为LOGGED_IN
  5. 返回上号结果和资源信息

5. 核心改动说明

获取状态接口的核心逻辑:

@GetMapping("/status")
public ResponseEntity<LinkStatusResponse> getStatus(@RequestParam String code) {
    // 1. 验证code
    LinkTask linkTask = validateAndGetLinkTask(code);
    
    // 2. 如果状态不是NEW自动执行刷新
    if (!"NEW".equals(linkTask.getStatus())) {
        // 调用脚本端刷新
        scriptClient.refresh(linkTask.getCodeNo());
        
        // 设置刷新标记和时间
        linkTask.setNeedRefresh(true);
        linkTask.setRefreshTime(new Date());
        linkTaskMapper.updateById(linkTask);
        
        // 等待10秒
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    // 3. 如果状态为USING重新获取二维码
    if ("USING".equals(linkTask.getStatus())) {
        long timestamp = System.currentTimeMillis();
        String qrUrl = String.format("http://36.138.184.60:12345/%s/二维码.png?t=%d", 
                                    linkTask.getCodeNo(), timestamp);
        
        linkTask.setQrCreatedAt(new Date());
        linkTask.setQrExpireAt(new Date(System.currentTimeMillis() + 60000));
        linkTaskMapper.updateById(linkTask);
    }
    
    // 4. 返回状态信息
    return ResponseEntity.ok(buildStatusResponse(linkTask));
}

这样的设计是否符合你的需求?前端只需要调用一次获取状态接口,后端会自动处理所有刷新逻辑。