{ "properties" : { }, "id" : "c3d4e5f678901234567890abcdef0123", "script" : null, "groupId" : "f8e3d2c1b0a94e5f8a7b6c5d4e3f2a1", "name" : "市场实时监控", "createTime" : 1781199600000, "updateTime" : null, "lock" : null, "createBy" : "admin", "updateBy" : "admin", "path" : "/market-realtime-monitor", "method" : "GET", "parameters" : [ ], "options" : [ ], "requestBody" : "", "headers" : [ ], "paths" : [ ], "responseBody" : null, "description" : "市场实时监控:视频监控设备列表,数据源 iot_device_video + iot_device_video_data 最新一条(只读)。", "requestBodyDefinition" : null, "responseBodyDefinition" : null } ================================ // 只读查询,不修改任何数据 var sql = """ SELECT v.id, v.name, v.number, v.location, v.address, v.status, v.play_url, v.hd_play_url, v.preview_img_url, v.img, v.channel_number, v."index" AS sort_index, v.last_capture_time, d.stream_url AS latest_stream_url, d.snapshot_url AS latest_snapshot_url, d.online_status AS latest_online_status, d.stream_status AS latest_stream_status, d.fault_code AS latest_fault_code FROM iot_device_video v LEFT JOIN LATERAL ( SELECT stream_url, snapshot_url, online_status, stream_status, fault_code FROM iot_device_video_data WHERE device_id = v.id ORDER BY collect_time DESC NULLS LAST LIMIT 1 ) d ON true WHERE COALESCE(v.del_flag, '0') = '0' AND COALESCE(v.is_show, true) = true ORDER BY v."index" NULLS LAST, v.name """ var rows = db.select(sql) var cameras = [] var pickText = (row, camelKey, snakeKey) => { if (!row) { return '' } if (row[camelKey]) { return row[camelKey] } if (row[snakeKey]) { return row[snakeKey] } return '' } var toUpperText = (text) => { if (!text) { return '' } return ('' + text).toUpperCase() } var mapStatus = (row) => { var deviceStatus = pickText(row, 'status', 'status') var onlineStatus = pickText(row, 'latestOnlineStatus', 'latest_online_status') var faultCode = pickText(row, 'latestFaultCode', 'latest_fault_code') var deviceUpper = toUpperText(deviceStatus) if (deviceUpper === 'OFFLINE') { return 'offline' } if (deviceUpper === 'ERROR' || deviceUpper === 'FAULT') { return 'error' } if (faultCode) { return 'error' } if (onlineStatus) { var onlineUpper = toUpperText(onlineStatus) if (onlineUpper === 'OFFLINE') { return 'offline' } if (onlineUpper === 'ERROR' || onlineUpper === 'FAULT') { return 'error' } } return 'online' } var pickStreamUrl = (row) => { var hd = pickText(row, 'hdPlayUrl', 'hd_play_url') if (hd) { return hd } var play = pickText(row, 'playUrl', 'play_url') if (play) { return play } return pickText(row, 'latestStreamUrl', 'latest_stream_url') } var pickHdStreamUrl = (row) => { return pickText(row, 'hdPlayUrl', 'hd_play_url') } var pickPlayUrl = (row) => { return pickText(row, 'playUrl', 'play_url') } var pickPreviewUrl = (row) => { var preview = pickText(row, 'previewImgUrl', 'preview_img_url') if (preview) { return preview } var img = pickText(row, 'img', 'img') if (img) { return img } return pickText(row, 'latestSnapshotUrl', 'latest_snapshot_url') } if (rows && rows.length > 0) { for (row in rows) { cameras.push({ id: pickText(row, 'id', 'id'), name: pickText(row, 'name', 'name'), number: pickText(row, 'number', 'number'), location: pickText(row, 'location', 'location'), address: pickText(row, 'address', 'address'), channelNumber: row.channelNumber != null ? row.channelNumber : row.channel_number, sortIndex: row.sortIndex != null ? row.sortIndex : row.sort_index, status: mapStatus(row), resolution: '1920x1080', preview: pickPreviewUrl(row), hdStreamUrl: pickHdStreamUrl(row), playUrl: pickPlayUrl(row), streamUrl: pickStreamUrl(row) }) } } return { pageSize: 2, autoPlayInterval: 10000, cameras: cameras }