feat(aiot): Edge截图方案替代ZLM截图,支持COS URL返回
- 新增 IAiScreenshotService 接口和实现:通过 Redis Stream 请求 Edge 截图,轮询等待结果,支持 5 分钟缓存和 force 刷新 - AiRoiController.getSnap() 从 ZLM 二进制截图改为返回 JSON(含 COS URL) - 前端 aiRoi.js 新增 getSnapUrl 方法 - roiConfig.vue 改为异步加载截图,增加 loading 状态和错误提示 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -62,3 +62,11 @@ export function updateAlgoParams(data) {
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function getSnapUrl(cameraCode, force = false) {
|
||||
return request({
|
||||
method: 'get',
|
||||
url: '/api/ai/roi/snap',
|
||||
params: { cameraCode, force }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="header-right">
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="startDraw('rectangle')">画矩形</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="startDraw('polygon')">画多边形</el-button>
|
||||
<el-button size="small" icon="el-icon-refresh" @click="refreshSnap">刷新截图</el-button>
|
||||
<el-button size="small" icon="el-icon-refresh" :loading="snapLoading" @click="refreshSnap">刷新截图</el-button>
|
||||
<el-button size="small" type="info" @click="handlePush">推送到边缘端</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -87,7 +87,7 @@
|
||||
<script>
|
||||
import RoiCanvas from '@/views/roiConfig/components/RoiCanvas.vue'
|
||||
import RoiAlgorithmBind from '@/views/roiConfig/components/RoiAlgorithmBind.vue'
|
||||
import { queryRoiByCameraId, saveRoi, deleteRoi, queryRoiDetail } from '@/api/aiRoi'
|
||||
import { queryRoiByCameraId, saveRoi, deleteRoi, queryRoiDetail, getSnapUrl } from '@/api/aiRoi'
|
||||
import { pushConfig } from '@/api/aiConfig'
|
||||
|
||||
export default {
|
||||
@@ -103,7 +103,8 @@ export default {
|
||||
roiList: [],
|
||||
selectedRoiId: null,
|
||||
selectedRoiBindings: [],
|
||||
snapUrl: ''
|
||||
snapUrl: '',
|
||||
snapLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -117,7 +118,7 @@ export default {
|
||||
this.srcUrl = this.$route.query.srcUrl || ''
|
||||
this.app = this.$route.query.app || ''
|
||||
this.stream = this.$route.query.stream || ''
|
||||
this.buildSnapUrl()
|
||||
this.fetchSnap()
|
||||
this.loadRois()
|
||||
},
|
||||
methods: {
|
||||
@@ -146,14 +147,29 @@ export default {
|
||||
startDraw(mode) {
|
||||
this.drawMode = mode
|
||||
},
|
||||
buildSnapUrl() {
|
||||
if (this.app && this.stream) {
|
||||
const base = process.env.NODE_ENV === 'development' ? process.env.VUE_APP_BASE_API : ''
|
||||
this.snapUrl = `${base}/api/ai/roi/snap?app=${encodeURIComponent(this.app)}&stream=${encodeURIComponent(this.stream)}&t=${Date.now()}`
|
||||
}
|
||||
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) {
|
||||
this.snapUrl = data.url
|
||||
if (data.stale) {
|
||||
this.$message.warning('截图为缓存数据,边缘设备可能离线')
|
||||
}
|
||||
} else if (data.status === 'timeout') {
|
||||
this.$message.warning(data.message || '边缘设备响应超时')
|
||||
} else {
|
||||
this.$message.error(data.message || '截图失败')
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.error('截图请求失败,请检查网络')
|
||||
}).finally(() => {
|
||||
this.snapLoading = false
|
||||
})
|
||||
},
|
||||
refreshSnap() {
|
||||
this.buildSnapUrl()
|
||||
this.fetchSnap(true)
|
||||
},
|
||||
onRoiDrawn(data) {
|
||||
this.drawMode = null
|
||||
|
||||
Reference in New Issue
Block a user