fix(aiot): ROI 显示修复 + 前端截图策略优化

- aiRoi.js: getSnapUrl 改为直接返回 /snap/image 代理 URL,
  非 force 模式不再触发 Edge 截图(从 DB 读持久化截图)
- roiConfig.vue: fetchSnap 适配新 API(直接使用返回的 URL)
- RoiCanvas.vue:
  · 添加 ResizeObserver 确保容器尺寸变化时重新初始化 canvas
  · onImageError 兜底初始化 canvas(截图失败仍可绘制/查看 ROI)
  · snapUrl watcher 触发 canvas 重初始化

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-03 20:09:55 +08:00
parent 650894b4e4
commit 80f0275216
3 changed files with 35 additions and 20 deletions

View File

@@ -150,20 +150,8 @@ export default {
fetchSnap(force = false) {
if (!this.cameraId) return
this.snapLoading = true
getSnapUrl(this.cameraId, force).then(res => {
const data = res.data || res
if (data.status === 'ok' && data.url) {
// 添加时间戳防止浏览器缓存旧截图
const url = data.url
this.snapUrl = url + (url.includes('?') ? '&' : '?') + '_t=' + Date.now()
if (data.stale) {
this.$message.warning('截图为缓存数据,边缘设备可能离线')
}
} else if (data.status === 'timeout') {
this.$message.warning(data.message || '边缘设备响应超时')
} else {
this.$message.error(data.message || '截图失败')
}
getSnapUrl(this.cameraId, force).then(url => {
this.snapUrl = url
}).catch(() => {
this.$message.error('截图请求失败,请检查网络')
}).finally(() => {

View File

@@ -43,7 +43,8 @@ export default {
currentPoint: null,
polygonPoints: [],
loading: true,
errorMsg: ''
errorMsg: '',
resizeObserver: null
}
},
watch: {
@@ -57,16 +58,30 @@ export default {
snapUrl() {
this.loading = true
this.errorMsg = ''
this.$nextTick(() => this.initCanvas())
}
},
mounted() {
this.$nextTick(() => {
this.initCanvas()
// ResizeObserver 确保容器尺寸变化时重新初始化 canvas
if (this.$refs.wrapper && typeof ResizeObserver !== 'undefined') {
this.resizeObserver = new ResizeObserver(() => {
if (this.$refs.wrapper && this.$refs.wrapper.clientWidth > 0) {
this.initCanvas()
}
})
this.resizeObserver.observe(this.$refs.wrapper)
}
window.addEventListener('resize', this.handleResize)
})
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize)
if (this.resizeObserver) {
this.resizeObserver.disconnect()
this.resizeObserver = null
}
},
methods: {
onImageLoad() {
@@ -78,6 +93,8 @@ export default {
onImageError() {
this.loading = false
this.errorMsg = '截图加载失败,请确认摄像头正在拉流'
// 关键:截图失败也初始化 canvas使 ROI 区域可见可操作
this.$nextTick(() => this.initCanvas())
},
initCanvas() {
const canvas = this.$refs.canvas