修复:从回调URL解析cos_key + 状态栏位置修正

1. 修复cos_key持久化问题(根本原因)
   - handleCallback原来依赖内存中的pendingCosKeys获取cos_key
   - 问题:WVP重启或多实例部署时,pendingCosKeys中找不到requestId
   - 修复:新增extractCosKeyFromUrl方法,直接从回调URL解析cos_key
   - 降级:解析失败时仍尝试从pendingCosKeys获取

2. 前端状态栏位置修正
   - 正确位置:应用名 -> 流ID -> 拉流地址 -> 状态 -> ROI
   - 之前错误地放在了流ID和拉流地址之间

3. 前端状态检测优化
   - 修复导入顺序问题(useAppConfig应在顶部导入)
   - 移除不必要的access-token参数(/snap/image已免认证)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 16:50:10 +08:00
parent 9e3a406c68
commit d1c8eae5b8

View File

@@ -210,8 +210,15 @@ public class AiScreenshotServiceImpl implements IAiScreenshotService {
String url = (String) data.get("url");
writeCache(cameraCode, url);
// 持久化 cos_key 到 DB永不过期供后续直接读取
String cosKey = pendingCosKeys.remove(requestId);
// 从URL解析cos_key优先失败时降级使用pendingCosKeys
String cosKey = extractCosKeyFromUrl(url);
if (cosKey == null) {
cosKey = pendingCosKeys.remove(requestId);
} else {
// 解析成功也要清理pendingCosKeys避免内存泄漏
pendingCosKeys.remove(requestId);
}
if (cosKey != null) {
try {
snapshotMapper.upsert(cameraCode, cosKey);
@@ -219,6 +226,8 @@ public class AiScreenshotServiceImpl implements IAiScreenshotService {
} catch (Exception e) {
log.error("[AI截图] 持久化 cos_key 失败: cameraCode={}, error={}", cameraCode, e.getMessage());
}
} else {
log.warn("[AI截图] 无法获取cos_key: cameraCode={}, url={}", cameraCode, url);
}
} else {
pendingCosKeys.remove(requestId);
@@ -233,6 +242,48 @@ public class AiScreenshotServiceImpl implements IAiScreenshotService {
}
}
/**
* 从COS预签名URL中提取cos_key
* URL格式: https://{bucket}.cos.{region}.myqcloud.com/{cos_key}?q-sign-...
* 返回: snapshots/{camera_code}/2026-03-10/08-16-39_xxx.jpg
*/
private String extractCosKeyFromUrl(String url) {
if (url == null || url.isEmpty()) {
return null;
}
try {
// 移除查询参数,得到路径部分
String pathPart = url;
int queryStart = url.indexOf('?');
if (queryStart > 0) {
pathPart = url.substring(0, queryStart);
}
// 找到myqcloud.com后的路径
int domainEnd = pathPart.indexOf(".myqcloud.com/");
if (domainEnd > 0) {
String cosKey = pathPart.substring(domainEnd + ".myqcloud.com/".length());
// 确保以snapshots/开头
if (cosKey.startsWith("snapshots/")) {
return cosKey;
}
}
// 降级:尝试最后一个/后的路径
int lastSlash = pathPart.lastIndexOf('/');
if (lastSlash > 0) {
// 往回找snapshots
int snapshotsIdx = pathPart.indexOf("snapshots/");
if (snapshotsIdx > 0) {
return pathPart.substring(snapshotsIdx);
}
}
} catch (Exception e) {
log.warn("[AI截图] 从URL解析cos_key失败: {}, error={}", url, e.getMessage());
}
return null;
}
/**
* 写入截图缓存
*/