|
@@ -1,255 +1,205 @@
|
|
|
/**
|
|
/**
|
|
|
- * 模拟API接口
|
|
|
|
|
- * 所有接口使用setTimeout模拟网络请求
|
|
|
|
|
|
|
+ * API 接口层
|
|
|
|
|
+ * 基础路径: /laboratory/labScreen (lab), /auth (auth)
|
|
|
*/
|
|
*/
|
|
|
|
|
+import request from '@/utils/request'
|
|
|
|
|
|
|
|
-// 模拟延迟
|
|
|
|
|
-function mockDelay(data, delay = 500) {
|
|
|
|
|
- return new Promise(resolve => {
|
|
|
|
|
- setTimeout(() => resolve({ code: 200, data, msg: 'success' }), delay)
|
|
|
|
|
- })
|
|
|
|
|
|
|
+function wrapResult(data) {
|
|
|
|
|
+ return { code: 200, data, msg: 'success' }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const PIE_COLORS = ['#48d7ff', '#3a7bff', '#36d399', '#ffb020', '#ff8c00', '#ff4d4f', '#a78bfa', '#e91e63', '#00e5ff', '#9c27b0']
|
|
|
|
|
+
|
|
|
|
|
+// ======================== 1. 实验室基本情况统计 ========================
|
|
|
|
|
+let _labBasicCache = null
|
|
|
|
|
+
|
|
|
|
|
+async function fetchLabBasic() {
|
|
|
|
|
+ if (_labBasicCache) return _labBasicCache
|
|
|
|
|
+ const res = await request.get('/laboratory/labScreen/labBasicStatistics')
|
|
|
|
|
+ if (res.code === 200 && res.data) { _labBasicCache = res.data; return res.data }
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 登录接口
|
|
|
|
|
-export function loginApi(params) {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- token: 'mock-token-' + Date.now(),
|
|
|
|
|
- userInfo: {
|
|
|
|
|
- name: '管理员',
|
|
|
|
|
- role: 'admin'
|
|
|
|
|
- }
|
|
|
|
|
- }, 800)
|
|
|
|
|
|
|
+function clearLabBasicCache() {
|
|
|
|
|
+ setTimeout(() => { _labBasicCache = null }, 5000)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 实验室基本情况统计
|
|
|
|
|
-export function getLabBasicStats() {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- totalLabs: 58,
|
|
|
|
|
|
|
+export async function getLabBasicStats() {
|
|
|
|
|
+ const raw = await fetchLabBasic()
|
|
|
|
|
+ clearLabBasicCache()
|
|
|
|
|
+ return wrapResult({
|
|
|
|
|
+ totalLabs: raw.labTotal,
|
|
|
levels: [
|
|
levels: [
|
|
|
- { name: 'I级(红)', value: 12, color: '#f44336' },
|
|
|
|
|
- { name: 'II级(橙)', value: 18, color: '#ff9800' },
|
|
|
|
|
- { name: 'III级(黄)', value: 16, color: '#ffc107' },
|
|
|
|
|
- { name: 'IV级(蓝)', value: 12, color: '#2196f3' }
|
|
|
|
|
|
|
+ { name: 'I级(红)', value: raw.levelOneCount, color: '#f44336' },
|
|
|
|
|
+ { name: 'II级(橙)', value: raw.levelTwoCount, color: '#ff9800' },
|
|
|
|
|
+ { name: 'III级(黄)', value: raw.levelThreeCount, color: '#ffc107' },
|
|
|
|
|
+ { name: 'IV级(蓝)', value: raw.levelFourCount, color: '#2196f3' }
|
|
|
],
|
|
],
|
|
|
- usage: {
|
|
|
|
|
- using: 20,
|
|
|
|
|
- abnormal: 3,
|
|
|
|
|
- idle: 35
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ usage: { using: raw.useTotal, abnormal: raw.exceptionalTotal, idle: raw.availableTotal }
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 实验室安全分级统计
|
|
|
|
|
-export function getSafetyLevelStats() {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- departments: [
|
|
|
|
|
- { name: '安全技术\n研究所', total: 11, level1: 3, level2: 3, level3: 3, level4: 2 },
|
|
|
|
|
- { name: '职业安全\n研究所', total: 9, level1: 2, level2: 3, level3: 2, level4: 2 },
|
|
|
|
|
- { name: '化学品安全\n研究所', total: 12, level1: 3, level2: 4, level3: 3, level4: 2 },
|
|
|
|
|
- { name: '矿山安全\n研究所', total: 10, level1: 2, level2: 3, level3: 3, level4: 2 },
|
|
|
|
|
- { name: '应急科学\n研究中心', total: 14, level1: 4, level2: 4, level3: 3, level4: 3 },
|
|
|
|
|
- { name: '信息技术\n研究所', total: 8, level1: 2, level2: 2, level3: 2, level4: 2 },
|
|
|
|
|
- { name: '检测检验\n中心', total: 6, level1: 1, level2: 2, level3: 2, level4: 1 },
|
|
|
|
|
- { name: '标准化\n研究所', total: 4, level1: 1, level2: 1, level3: 1, level4: 1 }
|
|
|
|
|
- ]
|
|
|
|
|
- })
|
|
|
|
|
|
|
+// ======================== 2. 实验室安全分级统计(复用 labBasicStatistics 数据)========================
|
|
|
|
|
+export async function getSafetyLevelStats() {
|
|
|
|
|
+ const raw = await fetchLabBasic()
|
|
|
|
|
+ clearLabBasicCache()
|
|
|
|
|
+ const departments = (raw.labLevelVOList || []).map(d => ({
|
|
|
|
|
+ name: d.deptName,
|
|
|
|
|
+ total: (d.levelOneCount || 0) + (d.levelTwoCount || 0) + (d.levelThreeCount || 0) + (d.levelFourCount || 0),
|
|
|
|
|
+ level1: d.levelOneCount || 0,
|
|
|
|
|
+ level2: d.levelTwoCount || 0,
|
|
|
|
|
+ level3: d.levelThreeCount || 0,
|
|
|
|
|
+ level4: d.levelFourCount || 0
|
|
|
|
|
+ }))
|
|
|
|
|
+ return wrapResult({ departments })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 实验室进入人数统计及走势
|
|
|
|
|
-export function getPersonStats() {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- todayTotal: [0, 1, 2, 8, 6],
|
|
|
|
|
- currentLab: [0, 0, 4, 7],
|
|
|
|
|
- hourlyData: [
|
|
|
|
|
- { hour: '0:00', enter: 5, lab: 2 },
|
|
|
|
|
- { hour: '3:00', enter: 3, lab: 1 },
|
|
|
|
|
- { hour: '6:00', enter: 20, lab: 8 },
|
|
|
|
|
- { hour: '9:00', enter: 135, lab: 85 },
|
|
|
|
|
- { hour: '12:00', enter: 98, lab: 60 },
|
|
|
|
|
- { hour: '15:00', enter: 110, lab: 72 },
|
|
|
|
|
- { hour: '18:00', enter: 45, lab: 25 },
|
|
|
|
|
- { hour: '21:00', enter: 15, lab: 5 },
|
|
|
|
|
- { hour: '24:00', enter: 3, lab: 1 }
|
|
|
|
|
- ]
|
|
|
|
|
- })
|
|
|
|
|
|
|
+// ======================== 3. 实验室进入人数统计及走势 ========================
|
|
|
|
|
+export async function getPersonStats() {
|
|
|
|
|
+ const res = await request.get('/laboratory/labScreen/passOutTrend')
|
|
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
|
|
+ const d = res.data
|
|
|
|
|
+ const toDigits = n => String(n).split('').map(Number)
|
|
|
|
|
+ const hourMap = {}
|
|
|
|
|
+ ;(d.entryTrend || []).forEach(t => { hourMap[t.hour] = { enter: t.count, lab: 0 } })
|
|
|
|
|
+ ;(d.labUserTrend || []).forEach(t => {
|
|
|
|
|
+ if (!hourMap[t.hour]) hourMap[t.hour] = { enter: 0, lab: 0 }
|
|
|
|
|
+ hourMap[t.hour].lab = t.count
|
|
|
|
|
+ })
|
|
|
|
|
+ const hourlyData = Object.keys(hourMap).sort((a, b) => a - b).map(h => ({
|
|
|
|
|
+ hour: h + ':00', enter: hourMap[h].enter, lab: hourMap[h].lab
|
|
|
|
|
+ }))
|
|
|
|
|
+ return wrapResult({ todayTotal: toDigits(d.todayEntryCount || 0), currentLab: toDigits(d.currentLabUserCount || 0), hourlyData })
|
|
|
|
|
+ }
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 实验室环境安全智能感知
|
|
|
|
|
-export function getEnvSensingList() {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- list: [
|
|
|
|
|
- { id: 1, lab: '有机化学实验室A103(A103)', dept: '化学品安全研究所', temp: 23.4, humidity: 37, tvoc: 0.83, co2: { value: 1071, warn: true }, o2: { value: 20.4, warn: false } },
|
|
|
|
|
- { id: 2, lab: '无损检测实验室B205(B205)', dept: '安全技术研究所', temp: 25.9, humidity: 44, tvoc: 0.96, co2: { value: 452, warn: false }, o2: { value: 20.1, warn: false } },
|
|
|
|
|
- { id: 3, lab: '化学实验室A101(A101)', dept: '化学品安全研究所', temp: 23.4, humidity: 43, tvoc: 0.72, co2: { value: 923, warn: true }, o2: { value: 19.9, warn: true } },
|
|
|
|
|
- { id: 4, lab: '材料力学实验室B203(B203)', dept: '安全技术研究所', temp: 25.8, humidity: 77, tvoc: 0.69, co2: { value: 862, warn: false }, o2: { value: 18.5, warn: true } },
|
|
|
|
|
- { id: 5, lab: '气体分析实验室A305(A305)', dept: '职业安全研究所', temp: 18.2, humidity: 73, tvoc: 0.11, co2: { value: 396, warn: false }, o2: { value: 21.2, warn: false } },
|
|
|
|
|
- { id: 6, lab: '高温高压实验室C102(C102)', dept: '矿山安全研究所', temp: 26.3, humidity: 31, tvoc: 1.74, co2: { value: 947, warn: false }, o2: { value: 20.6, warn: false } },
|
|
|
|
|
- { id: 7, lab: '生物安全实验室A202(A202)', dept: '职业安全研究所', temp: 21.3, humidity: 32, tvoc: 1.69, co2: { value: 444, warn: false }, o2: { value: 20.7, warn: false } },
|
|
|
|
|
- { id: 8, lab: '粉尘检测实验室B101(B101)', dept: '矿山安全研究所', temp: 28.8, humidity: 78, tvoc: 0.79, co2: { value: 871, warn: false }, o2: { value: 20.7, warn: false } },
|
|
|
|
|
- { id: 9, lab: '电气安全实验室C201(C201)', dept: '安全技术研究所', temp: 22.6, humidity: 41, tvoc: 0.55, co2: { value: 523, warn: false }, o2: { value: 20.9, warn: false } },
|
|
|
|
|
- { id: 10, lab: '防爆测试实验室C301(C301)', dept: '矿山安全研究所', temp: 24.1, humidity: 39, tvoc: 0.88, co2: { value: 612, warn: false }, o2: { value: 20.5, warn: false } },
|
|
|
|
|
- { id: 11, lab: '热分析实验室A401(A401)', dept: '化学品安全研究所', temp: 27.2, humidity: 45, tvoc: 1.12, co2: { value: 789, warn: false }, o2: { value: 20.3, warn: false } }
|
|
|
|
|
- ]
|
|
|
|
|
- })
|
|
|
|
|
|
|
+// ======================== 4. 实验环境安全智能感知 ========================
|
|
|
|
|
+export async function getEnvSensingList() {
|
|
|
|
|
+ const res = await request.get('/laboratory/labScreen/envMonitor', { params: { page: 1, pageSize: 50 } })
|
|
|
|
|
+ if (res.code === 200 && res.data && res.data.records) {
|
|
|
|
|
+ const list = res.data.records.map((r, i) => {
|
|
|
|
|
+ const sensors = r.sensorList || []
|
|
|
|
|
+ const find = code => sensors.find(s => s.code === code)
|
|
|
|
|
+ const tempS = find('temperature'), humS = find('humidity'), tvocS = find('tvoc'), co2S = find('co2'), o2S = find('o2')
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: r.subId || i + 1,
|
|
|
|
|
+ lab: r.subName + (r.roomNum ? `(${r.roomNum})` : ''),
|
|
|
|
|
+ dept: '',
|
|
|
|
|
+ temp: tempS ? tempS.deviceValue : '-',
|
|
|
|
|
+ humidity: humS ? humS.deviceValue : '-',
|
|
|
|
|
+ tvoc: tvocS ? tvocS.deviceValue : '-',
|
|
|
|
|
+ co2: { value: co2S ? co2S.deviceValue : '-', warn: co2S ? !co2S.operatingState : false },
|
|
|
|
|
+ o2: { value: o2S ? o2S.deviceValue : '-', warn: o2S ? !o2S.operatingState : false }
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ return wrapResult({ list })
|
|
|
|
|
+ }
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 实验室实时风险预警
|
|
|
|
|
-export function getRiskWarningList() {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- totalMonth: 12,
|
|
|
|
|
- list: [
|
|
|
|
|
- { id: 1, lab: '高温高压实验室C102(C102)', dept: '矿山安全研究所', type: '温度', value: '35.6°C', time: '2026-03-04 14:28:05', state: 'pending' },
|
|
|
|
|
- { id: 2, lab: '气体分析实验室A305(A305)', dept: '职业安全研究所', type: 'CO₂', value: '1050ppm', time: '2026-03-04 13:55:42', state: 'processing' },
|
|
|
|
|
- { id: 3, lab: '气体分析实验室A304(A304)', dept: '职业安全研究所', type: 'CO₂', value: '1051ppm', time: '2026-03-04 13:55:41', state: 'pending' },
|
|
|
|
|
- { id: 4, lab: '粉尘检测实验室B101(B101)', dept: '矿山安全研究所', type: 'O₂', value: '18.2%', time: '2026-03-04 13:20:10', state: 'processing' },
|
|
|
|
|
- { id: 5, lab: '有机化学实验室A103(A103)', dept: '化学品安全研究所', type: 'TVOC', value: '2.1mg/m³', time: '2026-03-04 12:45:30', state: 'resolved' },
|
|
|
|
|
- { id: 6, lab: '电气安全实验室C201(C201)', dept: '安全技术研究所', type: '湿度', value: '85%', time: '2026-03-04 11:30:15', state: 'resolved' }
|
|
|
|
|
- ]
|
|
|
|
|
- })
|
|
|
|
|
|
|
+// ======================== 5. 实验室实时风险预警 ========================
|
|
|
|
|
+export async function getRiskWarningList() {
|
|
|
|
|
+ const res = await request.get('/laboratory/labScreen/riskWarning')
|
|
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
|
|
+ const d = res.data
|
|
|
|
|
+ return wrapResult({
|
|
|
|
|
+ totalMonth: d.monthAlarmCount,
|
|
|
|
|
+ list: (d.eventList || []).map(e => ({
|
|
|
|
|
+ id: e.id, lab: e.subName, dept: '', type: e.eventName, value: '',
|
|
|
|
|
+ time: e.eventStartTime ? e.eventStartTime.replace('T', ' ') : ''
|
|
|
|
|
+ }))
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 智能环境感知应用设备统计
|
|
|
|
|
-export function getDeviceStats() {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- online: 186,
|
|
|
|
|
- offline: 14,
|
|
|
|
|
- onlineRate: 93,
|
|
|
|
|
- devices: [
|
|
|
|
|
- { name: '电子信息铭牌', count: 58 },
|
|
|
|
|
- { name: '化学品智能终端', count: 32 },
|
|
|
|
|
- { name: '传感器', count: 76 },
|
|
|
|
|
- { name: '智能设备', count: 34 }
|
|
|
|
|
- ]
|
|
|
|
|
- })
|
|
|
|
|
|
|
+// ======================== 6. 智能环境感知应用设备统计 ========================
|
|
|
|
|
+export async function getDeviceStats() {
|
|
|
|
|
+ const res = await request.get('/laboratory/labScreen/iotDeviceStatistics')
|
|
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
|
|
+ const d = res.data
|
|
|
|
|
+ return wrapResult({
|
|
|
|
|
+ online: d.onlineCount, offline: d.offlineCount, onlineRate: d.onlineRate,
|
|
|
|
|
+ devices: [
|
|
|
|
|
+ { name: '电子信息铭牌', count: d.tagCount || 0 },
|
|
|
|
|
+ { name: '化学品智能终端', count: d.terminalCount || 0 },
|
|
|
|
|
+ { name: '传感器', count: d.sensorCount || 0 },
|
|
|
|
|
+ { name: '摄像头', count: d.cameraCount || 0 },
|
|
|
|
|
+ { name: '智能设备', count: d.iotCount || 0 }
|
|
|
|
|
+ ].filter(i => i.count > 0)
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 实验室设备分类及使用统计
|
|
|
|
|
-export function getEquipmentStats() {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- categories: [
|
|
|
|
|
- { name: '分析仪器', value: 120, color: '#48d7ff' },
|
|
|
|
|
- { name: '安全防护', value: 95, color: '#3a7bff' },
|
|
|
|
|
- { name: '化学试剂设备', value: 80, color: '#36d399' },
|
|
|
|
|
- { name: '电气设备', value: 75, color: '#ffb020' },
|
|
|
|
|
- { name: '力学测试', value: 86, color: '#ff8c00' },
|
|
|
|
|
- { name: '环境监测', value: 72, color: '#ff4d4f' },
|
|
|
|
|
- { name: '通用设备', value: 58, color: '#a78bfa' }
|
|
|
|
|
- ],
|
|
|
|
|
- summary: {
|
|
|
|
|
- totalDevices: 586,
|
|
|
|
|
- totalHours: '12,480',
|
|
|
|
|
- usageRate: '78.6'
|
|
|
|
|
- },
|
|
|
|
|
- status: {
|
|
|
|
|
- using: 128,
|
|
|
|
|
- idle: 312,
|
|
|
|
|
- normal: 108,
|
|
|
|
|
- repair: 38
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+// ======================== 7. 实验室设备分类及使用统计 ========================
|
|
|
|
|
+export async function getEquipmentStats() {
|
|
|
|
|
+ const res = await request.get('/laboratory/labScreen/deviceCategoryStat')
|
|
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
|
|
+ const d = res.data
|
|
|
|
|
+ return wrapResult({
|
|
|
|
|
+ categories: (d.categoryList || []).map((c, i) => ({
|
|
|
|
|
+ name: c.categoryOneName, value: c.totalCount, color: PIE_COLORS[i % PIE_COLORS.length]
|
|
|
|
|
+ })),
|
|
|
|
|
+ summary: {
|
|
|
|
|
+ totalDevices: d.totalCount,
|
|
|
|
|
+ totalHours: d.totalUsageHours ? d.totalUsageHours.toLocaleString() : '0',
|
|
|
|
|
+ usageRate: String(d.usageRate || 0)
|
|
|
|
|
+ },
|
|
|
|
|
+ status: { using: d.inUseCount, idle: d.idleCount, normal: d.normalCount, repair: d.repairCount }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 天气接口(后续对接真实后台)
|
|
|
|
|
-export function getWeather() {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- city: '北京',
|
|
|
|
|
- weather: '晴',
|
|
|
|
|
- temp: 18
|
|
|
|
|
- })
|
|
|
|
|
|
|
+// ======================== 天气接口 ========================
|
|
|
|
|
+export async function getWeather() {
|
|
|
|
|
+ const res = await request.get('/laboratory/labScreen/weather')
|
|
|
|
|
+ if (res.code === 200 && res.data) return wrapResult(res.data)
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 建筑结构导航(视频监控页)
|
|
|
|
|
-export function getBuildingTree() {
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- tree: [
|
|
|
|
|
- {
|
|
|
|
|
- id: 1,
|
|
|
|
|
- label: '安科院院区',
|
|
|
|
|
- children: [
|
|
|
|
|
- {
|
|
|
|
|
- id: 11,
|
|
|
|
|
- label: '科研楼A',
|
|
|
|
|
- children: [
|
|
|
|
|
- { id: 111, label: '1层', children: [
|
|
|
|
|
- { id: 1111, label: 'A101 化学实验室' },
|
|
|
|
|
- { id: 1112, label: 'A102 有机合成实验室' },
|
|
|
|
|
- { id: 1113, label: 'A103 有机化学实验室' }
|
|
|
|
|
- ]},
|
|
|
|
|
- { id: 112, label: '2层', children: [
|
|
|
|
|
- { id: 1121, label: 'A201 材料分析实验室' },
|
|
|
|
|
- { id: 1122, label: 'A202 生物安全实验室' }
|
|
|
|
|
- ]},
|
|
|
|
|
- { id: 113, label: '3层', children: [
|
|
|
|
|
- { id: 1131, label: 'A301 气体分析实验室' },
|
|
|
|
|
- { id: 1132, label: 'A305 气体检测实验室' }
|
|
|
|
|
- ]},
|
|
|
|
|
- { id: 114, label: '4层', children: [
|
|
|
|
|
- { id: 1141, label: 'A401 热分析实验室' }
|
|
|
|
|
- ]}
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: 12,
|
|
|
|
|
- label: '科研楼B',
|
|
|
|
|
- children: [
|
|
|
|
|
- { id: 121, label: '1层', children: [
|
|
|
|
|
- { id: 1211, label: 'B101 粉尘检测实验室' }
|
|
|
|
|
- ]},
|
|
|
|
|
- { id: 122, label: '2层', children: [
|
|
|
|
|
- { id: 1221, label: 'B203 材料力学实验室' },
|
|
|
|
|
- { id: 1222, label: 'B205 无损检测实验室' }
|
|
|
|
|
- ]}
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: 13,
|
|
|
|
|
- label: '科研楼C',
|
|
|
|
|
- children: [
|
|
|
|
|
- { id: 131, label: '1层', children: [
|
|
|
|
|
- { id: 1311, label: 'C102 高温高压实验室' }
|
|
|
|
|
- ]},
|
|
|
|
|
- { id: 132, label: '2层', children: [
|
|
|
|
|
- { id: 1321, label: 'C201 电气安全实验室' }
|
|
|
|
|
- ]},
|
|
|
|
|
- { id: 133, label: '3层', children: [
|
|
|
|
|
- { id: 1331, label: 'C301 防爆测试实验室' }
|
|
|
|
|
- ]}
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- })
|
|
|
|
|
|
|
+// ======================== 8. 建筑结构导航 ========================
|
|
|
|
|
+function transformTree(nodes) {
|
|
|
|
|
+ if (!nodes) return []
|
|
|
|
|
+ return nodes.map(n => ({ id: n.id, label: n.name, children: transformTree(n.buildFloorVoList) }))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 视频列表
|
|
|
|
|
-export function getVideoList(params = {}) {
|
|
|
|
|
- const allVideos = [
|
|
|
|
|
- { id: 1, name: 'A101 化学实验室', ai: false, status: 'online' },
|
|
|
|
|
- { id: 2, name: 'A103 有机化学实验室', ai: true, status: 'online' },
|
|
|
|
|
- { id: 3, name: 'A202 生物安全实验室', ai: false, status: 'online' },
|
|
|
|
|
- { id: 4, name: 'A305 气体检测实验室', ai: false, status: 'online' },
|
|
|
|
|
- { id: 5, name: 'A401 热分析实验室', ai: true, status: 'online' },
|
|
|
|
|
- { id: 6, name: 'B101 粉尘检测实验室', ai: false, status: 'online' },
|
|
|
|
|
- { id: 7, name: 'B203 材料力学实验室', ai: false, status: 'online' },
|
|
|
|
|
- { id: 8, name: 'B205 无损检测实验室', ai: false, status: 'offline' },
|
|
|
|
|
- { id: 9, name: 'C102 高温高压实验室', ai: true, status: 'online' },
|
|
|
|
|
- { id: 10, name: 'C201 电气安全实验室', ai: false, status: 'online' },
|
|
|
|
|
- { id: 11, name: 'C301 防爆测试实验室', ai: false, status: 'online' },
|
|
|
|
|
- { id: 12, name: 'A102 有机合成实验室', ai: false, status: 'online' },
|
|
|
|
|
- { id: 13, name: 'A201 材料分析实验室', ai: false, status: 'offline' },
|
|
|
|
|
- { id: 14, name: 'A301 气体分析实验室', ai: true, status: 'online' },
|
|
|
|
|
- { id: 15, name: '园区东门', ai: false, status: 'online' },
|
|
|
|
|
- { id: 16, name: '园区西门', ai: false, status: 'online' },
|
|
|
|
|
- { id: 17, name: '停车场', ai: false, status: 'online' },
|
|
|
|
|
- { id: 18, name: '走廊通道A3F', ai: false, status: 'online' }
|
|
|
|
|
- ]
|
|
|
|
|
- const page = params.page || 1
|
|
|
|
|
- const start = (page - 1) * 9
|
|
|
|
|
- const list = allVideos.slice(start, start + 9)
|
|
|
|
|
- return mockDelay({
|
|
|
|
|
- total: allVideos.length,
|
|
|
|
|
- page,
|
|
|
|
|
- list
|
|
|
|
|
|
|
+export async function getBuildingTree(params = {}) {
|
|
|
|
|
+ const res = await request.post('/laboratory/labScreen/monitorTree', params)
|
|
|
|
|
+ if (res.code === 200 && res.data) return wrapResult({ tree: transformTree(res.data) })
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ======================== 9. 视频列表 ========================
|
|
|
|
|
+export async function getVideoList(params = {}) {
|
|
|
|
|
+ const res = await request.post('/laboratory/labScreen/cameraStream', {
|
|
|
|
|
+ subIds: params.subIds || [], streamType: 0, protocol: 'ws', source: 3,
|
|
|
|
|
+ page: params.page || 1, pageSize: params.pageSize || 9
|
|
|
})
|
|
})
|
|
|
|
|
+ if (res.code === 200 && res.data && res.data.records) {
|
|
|
|
|
+ return wrapResult({
|
|
|
|
|
+ total: res.data.total, page: res.data.current,
|
|
|
|
|
+ list: res.data.records.map(r => ({
|
|
|
|
|
+ id: r.deviceNo, name: r.subjectName + (r.room ? `(${r.room})` : ''),
|
|
|
|
|
+ ai: false, status: r.streamUrl ? 'online' : 'offline', streamUrl: r.streamUrl
|
|
|
|
|
+ }))
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ======================== 登录接口 ========================
|
|
|
|
|
+export async function loginApi(params) {
|
|
|
|
|
+ const res = await request.post('/auth/bigLogin', params)
|
|
|
|
|
+ if (res.code === 200 && res.data) return wrapResult(res.data)
|
|
|
|
|
+ throw new Error(res.message || res.msg || '登录失败')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ======================== 7. 风险预警-触发预案信息 ========================
|
|
|
|
|
+export async function getTriggerInfo() {
|
|
|
|
|
+ const res = await request.get('/laboratory/large/selectTriggerInfo')
|
|
|
|
|
+ if (res.code === 200 && res.data) return wrapResult(res.data)
|
|
|
|
|
+ throw new Error(res.message || '接口异常')
|
|
|
}
|
|
}
|