主要修改: 1. 在LinkController中新增获取用户链接状态的接口,支持通过linkId或codeNo查询。 2. 在LinkStatusService中实现用户链接状态查询逻辑,包含自动刷新和二维码更新功能。 3. 更新LinkTask实体,添加needRefresh、refreshTime、qrCreatedAt和qrExpireAt字段以支持新功能。 4. 在ScriptClient中新增检查空闲设备、选区、刷新、检查上号状态等操作的实现。 5. 更新SecurityConfig,允许用户端获取链接状态接口公开访问。 技术细节: - 新增UserLinkStatusResponse DTO以支持用户链接状态的返回格式。 - 通过脚本端接口实现链接状态的自动刷新和二维码信息更新。
3.9 KiB
3.9 KiB
明白了!让我重新整理接口设计:
后端接口设计文档(最终版)
1. 获取链接状态接口
接口: GET /api/link/status?code={code}
业务逻辑:
- 解密和验证code参数(包含linkId、签发时间、过期时间等)
- 检查链接是否过期(默认24小时)
- 从数据库查询链接当前状态
- 如果状态不是NEW,后端自动执行刷新逻辑:
- 调用脚本端刷新:
POST http://36.138.184.60:1234/yijianwan_netfile/saveMsg?文件名=判断刷新&编号=刷新 - 设置need_refresh=true,记录refresh_time
- 等待10秒(或配置的刷新等待时间)
- 执行完毕后继续下面的逻辑
- 调用脚本端刷新:
- 如果状态为USING,重新获取二维码:
- 调用:
http://36.138.184.60:12345/{编号}/二维码.png?t={timestamp} - 更新qr_created_at和qr_expire_at
- 调用:
- 返回链接状态和相关信息
前端调用方式:
// 前端只需要调用一次,后端会自动处理刷新逻辑
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 }
业务逻辑:
- 验证code参数
- 调用脚本端刷新
- 设置need_refresh=true,记录refresh_time
- 返回等待时间
使用时机:
- 用户在扫码页面手动点击"刷新"按钮时
3. 选区接口
接口: POST /api/link/select-region
请求体: { code: string, region: "Q" | "V" }
业务逻辑:
- 验证code和region参数
- 检查链接状态,只有NEW状态才能选区
- 如果need_refresh=true,检查是否已等待10秒,否则返回423错误
- 调用脚本端分配空闲设备
- 调用脚本端选区
- 等待脚本端生成二维码
- 更新数据库状态为USING
- 返回二维码信息
4. 轮询上号接口
接口: GET /api/link/poll-login?code={code}
业务逻辑:
- 验证code参数
- 检查链接状态,只有USING状态才能轮询
- 调用脚本端检查上号状态
- 如果返回"已上号",更新状态为LOGGED_IN
- 返回上号结果和资源信息
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));
}
这样的设计是否符合你的需求?前端只需要调用一次获取状态接口,后端会自动处理所有刷新逻辑。