import { normalizeResponseData, requestJson } from "./request" const JSY_API_BASE = import.meta.env.VITE_JSY_API_BASE || "/jsyApi" const HONGYUAN_TOWN_NAMES = [ "邛溪镇", "刷经寺镇", "安曲镇", "龙日镇", "江茸乡", "查尔玛乡", "瓦切镇", "阿木乡", "麦洼乡", "色地镇", ] function joinBase(path) { if (/^https?:\/\//.test(path)) return path return `${JSY_API_BASE}${path.startsWith("/") ? path : `/${path}`}` } function unwrapResponse(response) { const failed = response?.success === false || (response?.code !== undefined && ![0, 200, "0", "200"].includes(response.code)) if (failed) { const error = new Error(response?.msg || response?.message || "视频监控接口请求失败") error.code = response?.code throw error } return normalizeResponseData(response) } function pickValue(item, keys, fallback = "") { for (const key of keys) { if (item?.[key] !== undefined && item?.[key] !== null && item?.[key] !== "") { return item[key] } } return fallback } function inferTownName(name = "") { const normalizedName = String(name) const town = HONGYUAN_TOWN_NAMES.find((item) => normalizedName.includes(item.replace(/[镇乡]$/, ""))) return town || "红原县" } function inferSceneName(name = "") { const text = String(name) if (text.includes("养殖")) return "养殖基地" if (text.includes("饲草")) return "饲草基地" if (text.includes("种草") || text.includes("牧草")) return "牧草基地" if (text.includes("虫情")) return "虫情监测" if (text.includes("机场")) return "机场周边" return "重点点位" } function getChannel(row, index) { const url = pickValue(row, ["hdPlayUrl", "playUrl", "url"]) const match = String(url).match(/\/(\d+)(?:\.hd)?\.live/i) if (match) return match[1].padStart(2, "0") return String(index + 1).padStart(2, "0") } function getUpdateTime() { return new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit", hour12: false, }) } function normalizeMonitoring(row, index, total, validTotal) { const name = pickValue(row, ["name", "title", "deviceName"], `视频监控${index + 1}`) const hdPlayUrl = pickValue(row, ["hdPlayUrl", "hd_play_url", "url"]) const playUrl = pickValue(row, ["playUrl", "play_url"], hdPlayUrl) const token = pickValue(row, ["token", "accessToken", "access_token"]) const isOnline = Boolean(token && (hdPlayUrl || playUrl)) const onlineRate = total ? Math.round((validTotal / total) * 100) : 0 return { key: pickValue(row, ["id", "number", "deviceSerial"], `${name}-${index}`), title: name, town: inferTownName(name), scene: inferSceneName(name), device: pickValue(row, ["number", "deviceSerial", "serialNumber"], `CAM-${String(index + 1).padStart(3, "0")}`), channel: getChannel(row, index), cameraCount: total, status: isOnline ? "直播中" : "离线", onlineRate, updateTime: getUpdateTime(), operator: isOnline ? "萤石云 · 在线预览" : "监控参数待同步", progress: isOnline ? 100 : 0, image: pickValue(row, ["img", "image", "cover", "snapshot"]), playUrl, hdPlayUrl, token, source: row, } } export async function getHomeMonitorings(params = {}) { const data = await requestJson(joinBase("/api/home/monitorings"), { params, timeout: 18000, }).then(unwrapResponse) const rows = Array.isArray(data) ? data : data?.rows || data?.list || [] const validTotal = rows.filter((row) => pickValue(row, ["token", "accessToken", "access_token"]) && pickValue(row, ["hdPlayUrl", "playUrl", "url"])).length return rows.map((row, index) => normalizeMonitoring(row, index, rows.length, validTotal)) }