|
|
@@ -1,6 +1,6 @@
|
|
|
<template>
|
|
|
<div class="app-container">
|
|
|
- <!-- 系统基础信息卡片 - 添加编辑按钮 -->
|
|
|
+ <!-- 系统基础信息卡片 -->
|
|
|
<el-card class="system-info-card">
|
|
|
<div slot="header" class="card-header">
|
|
|
<span class="title">
|
|
|
@@ -60,7 +60,7 @@
|
|
|
<div class="info-group">
|
|
|
<div class="group-title">设备统计</div>
|
|
|
<div class="info-item">
|
|
|
- <label>设备总数:</label>
|
|
|
+ <label>网关设备:</label>
|
|
|
<span class="stat-number">{{ deviceStats.total }}</span>
|
|
|
</div>
|
|
|
<div class="info-item">
|
|
|
@@ -171,8 +171,8 @@
|
|
|
</div>
|
|
|
</el-tab-pane>
|
|
|
|
|
|
- <!-- 关联设备标签页 -->
|
|
|
- <el-tab-pane label="关联设备" name="devices">
|
|
|
+ <!-- 能耗采集标签页 -->
|
|
|
+ <el-tab-pane label="能耗采集" name="devBaGa">
|
|
|
<div class="tab-content">
|
|
|
<!-- 设备统计 -->
|
|
|
<div class="device-stats">
|
|
|
@@ -315,6 +315,94 @@
|
|
|
</div>
|
|
|
</el-tab-pane>
|
|
|
|
|
|
+ <!-- 楼控设备标签页 - 新增 -->
|
|
|
+ <el-tab-pane label="楼控设备" name="baDevices">
|
|
|
+ <div class="tab-content">
|
|
|
+ <!-- 设备类型选择 -->
|
|
|
+ <div class="ba-device-header">
|
|
|
+ <el-select v-model="selectedBaDeviceModel" placeholder="请选择设备类型" @change="handleBaDeviceTypeChange" style="width: 200px;">
|
|
|
+ <el-option
|
|
|
+ v-for="item in baDeviceModels"
|
|
|
+ :key="item.modelCode"
|
|
|
+ :label="item.modelName"
|
|
|
+ :value="item.modelCode">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ <el-button type="primary" icon="el-icon-refresh" @click="refreshBaDevices" :loading="baDeviceLoading" style="margin-left: 10px;">
|
|
|
+ 刷新
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 设备列表 -->
|
|
|
+ <el-table
|
|
|
+ :data="baDeviceList"
|
|
|
+ border
|
|
|
+ stripe
|
|
|
+ v-loading="baDeviceLoading"
|
|
|
+ style="margin-top: 15px;">
|
|
|
+ <el-table-column type="expand">
|
|
|
+ <template slot-scope="props">
|
|
|
+ <div class="ba-device-detail">
|
|
|
+ <el-tabs v-model="props.row.detailTab">
|
|
|
+ <!-- 基础属性 -->
|
|
|
+ <el-tab-pane label="基础属性" name="base">
|
|
|
+ <el-descriptions :column="2" border size="small" v-if="getBaDeviceAttrs(props.row.deviceCode, 'Base').length > 0">
|
|
|
+ <el-descriptions-item
|
|
|
+ v-for="attr in getBaDeviceAttrs(props.row.deviceCode, 'Base')"
|
|
|
+ :key="attr.attrKey"
|
|
|
+ :label="attr.attrName">
|
|
|
+ {{ attr.attrValue || '-' }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ <el-empty v-else description="暂无基础属性"></el-empty>
|
|
|
+ </el-tab-pane>
|
|
|
+
|
|
|
+ <!-- 状态属性 -->
|
|
|
+ <el-tab-pane label="状态属性" name="state">
|
|
|
+ <el-table
|
|
|
+ :data="getBaDeviceAttrs(props.row.deviceCode, 'State')"
|
|
|
+ border
|
|
|
+ size="small"
|
|
|
+ v-if="getBaDeviceAttrs(props.row.deviceCode, 'State').length > 0">
|
|
|
+ <el-table-column prop="attrName" label="属性名称" width="180"></el-table-column>
|
|
|
+ <el-table-column label="属性值" width="150">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tag v-if="scope.row.attrValueType === 'Enum' && scope.row.attrValueName" size="small">
|
|
|
+ {{ scope.row.attrValueName }}
|
|
|
+ </el-tag>
|
|
|
+ <span v-else>
|
|
|
+ {{ formatBaAttrValue(scope.row) }}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="attrUnit" label="单位" width="100"></el-table-column>
|
|
|
+ <el-table-column prop="updateTime" label="更新时间" width="160"></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <el-empty v-else description="暂无状态数据"></el-empty>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="deviceCode" label="设备代码" width="180"></el-table-column>
|
|
|
+ <el-table-column prop="deviceName" label="设备名称" min-width="200"></el-table-column>
|
|
|
+ <el-table-column prop="location" label="安装位置" min-width="150"></el-table-column>
|
|
|
+ <el-table-column prop="areaCode" label="区域" width="100">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.areaCode && scope.row.areaCode.includes('3001') ? '北区' : '南区' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="设备状态" width="100" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tag :type="scope.row.deviceStatus === 1 ? 'success' : 'info'">
|
|
|
+ {{ scope.row.deviceStatus === 1 ? '在线' : '离线' }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-tab-pane>
|
|
|
+
|
|
|
<!-- 调用日志标签页 -->
|
|
|
<el-tab-pane label="调用日志" name="callLogs">
|
|
|
<div class="tab-content">
|
|
|
@@ -527,7 +615,7 @@
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
|
|
|
- <!-- 能力执行弹窗(支持Slider和Input类型) -->
|
|
|
+ <!-- 能力执行弹窗 -->
|
|
|
<el-dialog :title="abilityDialogTitle" :visible.sync="abilityDialogVisible" width="500px" append-to-body :close-on-click-modal="false">
|
|
|
<el-form ref="abilityForm" :model="abilityForm" label-width="100px">
|
|
|
<el-form-item label="能力名称">
|
|
|
@@ -603,7 +691,7 @@ export default {
|
|
|
data() {
|
|
|
return {
|
|
|
// 系统代码
|
|
|
- systemCode: 'SYS_NHJC',
|
|
|
+ systemCode: 'SYS_BA',
|
|
|
// 系统信息
|
|
|
systemInfo: {},
|
|
|
// 系统状态
|
|
|
@@ -617,7 +705,7 @@ export default {
|
|
|
// 系统能力
|
|
|
systemAbilities: [],
|
|
|
abilityLoading: false,
|
|
|
- // 设备列表
|
|
|
+ // 设备列表(能耗网关)
|
|
|
deviceList: [],
|
|
|
deviceLoading: false,
|
|
|
deviceAttrs: {},
|
|
|
@@ -634,8 +722,17 @@ export default {
|
|
|
// 所有模型代码(系统 + 设备)
|
|
|
allModelCodes: [],
|
|
|
// 子设备相关
|
|
|
- subDeviceAttrs: {}, // 子设备属性缓存
|
|
|
- subDeviceGatewayMap: {}, // 子设备到网关的映射
|
|
|
+ subDeviceAttrs: {},
|
|
|
+ subDeviceGatewayMap: {},
|
|
|
+ // 楼控设备相关 - 新增
|
|
|
+ baDeviceModels: [
|
|
|
+ { modelCode: 'M_Z020_DEV_BA_XF', modelName: 'BA新风设备' },
|
|
|
+ { modelCode: 'M_Z020_DEV_BA_AHU', modelName: 'BA空调设备' }
|
|
|
+ ],
|
|
|
+ selectedBaDeviceModel: 'M_Z020_DEV_BA_XF',
|
|
|
+ baDeviceList: [],
|
|
|
+ baDeviceLoading: false,
|
|
|
+ baDeviceAttrs: {}, // 楼控设备属性缓存
|
|
|
// 调用日志查询
|
|
|
callLogQuery: {
|
|
|
dateRange: [],
|
|
|
@@ -732,7 +829,6 @@ export default {
|
|
|
updateSubsystem(this.editForm).then(response => {
|
|
|
this.$message.success("修改成功")
|
|
|
this.editDialogVisible = false
|
|
|
- // 重新加载系统信息
|
|
|
this.loadSystemInfo()
|
|
|
}).catch(error => {
|
|
|
this.$message.error("修改失败:" + error.message)
|
|
|
@@ -841,7 +937,7 @@ export default {
|
|
|
}
|
|
|
|
|
|
// 如果是抄表能力,刷新设备数据
|
|
|
- if (ability.abilityKey === 'MeterReadingGw') {
|
|
|
+ if (ability.abilityKey === 'MeterReadingGw' || ability.abilityKey === 'MeterReadingTotal') {
|
|
|
this.loadDevices()
|
|
|
}
|
|
|
}).catch(error => {
|
|
|
@@ -1010,12 +1106,13 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
- // 加载设备列表
|
|
|
+ // 加载设备列表(能耗网关) - 修改:添加deviceModel过滤
|
|
|
async loadDevices() {
|
|
|
this.deviceLoading = true
|
|
|
try {
|
|
|
const res = await getByCondition({
|
|
|
- subsystemCode: this.systemCode
|
|
|
+ subsystemCode: this.systemCode,
|
|
|
+ deviceModel: 'M_W4_DEV_BA_GA' // 仅查询能耗网关
|
|
|
})
|
|
|
|
|
|
const deviceData = res.data || res.rows || []
|
|
|
@@ -1054,7 +1151,7 @@ export default {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
- // 批量加载网关设备属性(包含subDev)
|
|
|
+ // 批量加载网关设备属性
|
|
|
for (const modelCode in devicesByModel) {
|
|
|
await this.loadDeviceAttrsBatch(modelCode, devicesByModel[modelCode])
|
|
|
}
|
|
|
@@ -1080,7 +1177,6 @@ export default {
|
|
|
const attrData = batchData[deviceCode]
|
|
|
|
|
|
if (attrData) {
|
|
|
- // 保存基础属性
|
|
|
const baseAttrs = {}
|
|
|
if (attrData.Base) {
|
|
|
attrData.Base.forEach(attr => {
|
|
|
@@ -1097,8 +1193,7 @@ export default {
|
|
|
|
|
|
// 加载所有子设备属性
|
|
|
async loadAllSubDeviceAttrs() {
|
|
|
- // 收集所有子设备信息
|
|
|
- const subDevicesByModel = {} // { modelCode: [deviceCodes] }
|
|
|
+ const subDevicesByModel = {}
|
|
|
|
|
|
this.deviceList.forEach(device => {
|
|
|
const subDevAttr = this.deviceAttrs[device.deviceCode]?.subDev
|
|
|
@@ -1110,8 +1205,6 @@ export default {
|
|
|
subDevicesByModel[subDev.modelCode] = []
|
|
|
}
|
|
|
subDevicesByModel[subDev.modelCode].push(subDev.deviceCode)
|
|
|
-
|
|
|
- // 保存子设备与网关的关联关系
|
|
|
this.subDeviceGatewayMap[subDev.deviceCode] = device.deviceCode
|
|
|
})
|
|
|
} catch (e) {
|
|
|
@@ -1120,7 +1213,6 @@ export default {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
- // 批量查询各个模型的子设备属性
|
|
|
let totalPoints = 0
|
|
|
for (const modelCode in subDevicesByModel) {
|
|
|
const pointsCount = await this.loadSubDeviceAttrsBatch(modelCode)
|
|
|
@@ -1128,8 +1220,6 @@ export default {
|
|
|
}
|
|
|
|
|
|
this.deviceStats.points = totalPoints
|
|
|
-
|
|
|
- // 组织成通道结构供展示
|
|
|
this.organizeChannelsFromSubDevices()
|
|
|
},
|
|
|
|
|
|
@@ -1141,7 +1231,6 @@ export default {
|
|
|
|
|
|
let pointsCount = 0
|
|
|
|
|
|
- // 保存子设备属性
|
|
|
for (const deviceCode in batchData) {
|
|
|
const attrData = batchData[deviceCode]
|
|
|
this.subDeviceAttrs[deviceCode] = attrData
|
|
|
@@ -1168,8 +1257,6 @@ export default {
|
|
|
|
|
|
try {
|
|
|
const subDevices = JSON.parse(subDevAttr)
|
|
|
-
|
|
|
- // 按通道分组
|
|
|
const channelMap = {}
|
|
|
|
|
|
subDevices.forEach(subDev => {
|
|
|
@@ -1178,7 +1265,6 @@ export default {
|
|
|
|
|
|
if (!subDevAttrData) return
|
|
|
|
|
|
- // 获取通道信息
|
|
|
const interfaceAttr = subDevAttrData.Base?.find(attr => attr.attrKey === 'interface')
|
|
|
const channelName = interfaceAttr?.attrValue || '未知通道'
|
|
|
|
|
|
@@ -1190,7 +1276,6 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 构建测点信息
|
|
|
const point = {
|
|
|
key: subDevCode,
|
|
|
name: subDevAttrData.Base?.find(attr => attr.attrKey === 'deviceName')?.attrValue || subDevCode,
|
|
|
@@ -1204,7 +1289,6 @@ export default {
|
|
|
channelMap[channelName].points.push(point)
|
|
|
})
|
|
|
|
|
|
- // 转换为数组并排序
|
|
|
const channels = Object.values(channelMap).sort((a, b) => {
|
|
|
return a.key.localeCompare(b.key)
|
|
|
})
|
|
|
@@ -1220,7 +1304,6 @@ export default {
|
|
|
|
|
|
// 格式化通道名称
|
|
|
formatChannelName(channelKey) {
|
|
|
- // 将类似 "1003D1口" 转换为 "D1口通道"
|
|
|
const match = channelKey.match(/(\d+)(D\d+)口/)
|
|
|
if (match) {
|
|
|
return `${match[2]}口通道`
|
|
|
@@ -1241,7 +1324,6 @@ export default {
|
|
|
// 单个加载设备属性(用于刷新)
|
|
|
async loadDeviceAttrs(deviceCode) {
|
|
|
try {
|
|
|
- // 加载网关属性
|
|
|
const res = await getObjAttr(2, deviceCode)
|
|
|
const attrData = res.data
|
|
|
|
|
|
@@ -1253,7 +1335,6 @@ export default {
|
|
|
}
|
|
|
this.deviceAttrs[deviceCode] = baseAttrs
|
|
|
|
|
|
- // 重新加载该网关的所有子设备
|
|
|
const subDevAttr = baseAttrs.subDev
|
|
|
if (subDevAttr) {
|
|
|
const subDevices = JSON.parse(subDevAttr)
|
|
|
@@ -1266,12 +1347,10 @@ export default {
|
|
|
subDevicesByModel[subDev.modelCode].push(subDev.deviceCode)
|
|
|
})
|
|
|
|
|
|
- // 批量查询子设备属性
|
|
|
for (const modelCode in subDevicesByModel) {
|
|
|
await this.loadSubDeviceAttrsBatch(modelCode)
|
|
|
}
|
|
|
|
|
|
- // 重新组织该网关的通道数据
|
|
|
this.organizeChannelsFromSubDevices()
|
|
|
}
|
|
|
|
|
|
@@ -1314,7 +1393,6 @@ export default {
|
|
|
|
|
|
this.$message.success(`${ability.abilityName}执行成功`)
|
|
|
|
|
|
- // 如果是抄表相关能力,刷新测点数据
|
|
|
if (ability.abilityKey.toLowerCase().includes('meter') ||
|
|
|
ability.abilityKey.toLowerCase().includes('reading')) {
|
|
|
await this.loadDeviceAttrs(device.deviceCode)
|
|
|
@@ -1341,7 +1419,6 @@ export default {
|
|
|
|
|
|
this.$message.success(`${ability.abilityName}执行成功`)
|
|
|
|
|
|
- // 如果是抄表相关能力,刷新测点数据
|
|
|
if (ability.abilityKey.toLowerCase().includes('meter') ||
|
|
|
ability.abilityKey.toLowerCase().includes('reading')) {
|
|
|
await this.loadDeviceAttrs(device.deviceCode)
|
|
|
@@ -1358,15 +1435,110 @@ export default {
|
|
|
this.$refs.deviceTable?.toggleRowExpansion(row)
|
|
|
},
|
|
|
|
|
|
- // 标签页切换
|
|
|
+ // ========== 楼控设备相关方法 - 新增 ==========
|
|
|
+
|
|
|
+ // 处理楼控设备类型切换
|
|
|
+ handleBaDeviceTypeChange() {
|
|
|
+ this.loadBaDevices()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 刷新楼控设备
|
|
|
+ refreshBaDevices() {
|
|
|
+ this.loadBaDevices()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 加载楼控设备列表
|
|
|
+ async loadBaDevices() {
|
|
|
+ if (!this.selectedBaDeviceModel) return
|
|
|
+
|
|
|
+ this.baDeviceLoading = true
|
|
|
+ try {
|
|
|
+ // 查询指定模型的设备
|
|
|
+ const res = await getByCondition({
|
|
|
+ subsystemCode: this.systemCode,
|
|
|
+ deviceModel: this.selectedBaDeviceModel
|
|
|
+ })
|
|
|
+
|
|
|
+ const deviceData = res.data || res.rows || []
|
|
|
+
|
|
|
+ this.baDeviceList = deviceData.map(device => ({
|
|
|
+ ...device,
|
|
|
+ detailTab: 'base'
|
|
|
+ }))
|
|
|
+
|
|
|
+ // 批量加载设备属性
|
|
|
+ if (this.baDeviceList.length > 0) {
|
|
|
+ await this.loadBaDeviceAttrsBatch(this.selectedBaDeviceModel)
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.error('加载楼控设备失败:' + error.message)
|
|
|
+ } finally {
|
|
|
+ this.baDeviceLoading = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 批量加载楼控设备属性
|
|
|
+ async loadBaDeviceAttrsBatch(modelCode) {
|
|
|
+ try {
|
|
|
+ const res = await getObjAttrBatch(2, modelCode)
|
|
|
+ const batchData = res.data || {}
|
|
|
+
|
|
|
+ // 缓存所有设备的属性数据
|
|
|
+ for (const deviceCode in batchData) {
|
|
|
+ this.baDeviceAttrs[deviceCode] = batchData[deviceCode]
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error(`批量加载楼控设备属性失败:`, error)
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取楼控设备的属性(按组)
|
|
|
+ getBaDeviceAttrs(deviceCode, attrGroup) {
|
|
|
+ const attrData = this.baDeviceAttrs[deviceCode]
|
|
|
+ if (!attrData || !attrData[attrGroup]) {
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ return attrData[attrGroup]
|
|
|
+ },
|
|
|
+
|
|
|
+ // 格式化楼控设备属性值
|
|
|
+ formatBaAttrValue(attr) {
|
|
|
+ if (!attr.attrValue && attr.attrValue !== 0) {
|
|
|
+ return '-'
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果有枚举名称,优先显示
|
|
|
+ if (attr.attrValueName) {
|
|
|
+ return attr.attrValueName
|
|
|
+ }
|
|
|
+
|
|
|
+ // 数值类型,保留两位小数
|
|
|
+ if (attr.attrValueType === 'Value') {
|
|
|
+ const numValue = parseFloat(attr.attrValue)
|
|
|
+ if (!isNaN(numValue)) {
|
|
|
+ return numValue.toFixed(2)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return attr.attrValue
|
|
|
+ },
|
|
|
+
|
|
|
+ // ========== 标签页切换 ==========
|
|
|
+
|
|
|
handleTabClick(tab) {
|
|
|
if (tab.name === 'callLogs' && this.callLogList.length === 0) {
|
|
|
this.queryCallLogs()
|
|
|
} else if (tab.name === 'eventLogs' && this.eventLogList.length === 0) {
|
|
|
this.queryEventLogs()
|
|
|
+ } else if (tab.name === 'baDevices' && this.baDeviceList.length === 0) {
|
|
|
+ this.loadBaDevices()
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ // ========== 日志查询相关 ==========
|
|
|
+
|
|
|
// 查询调用日志
|
|
|
async queryCallLogs() {
|
|
|
this.logLoading = true
|
|
|
@@ -1621,6 +1793,18 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 楼控设备样式 - 新增
|
|
|
+ .ba-device-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ba-device-detail {
|
|
|
+ padding: 20px;
|
|
|
+ background: #f5f7fa;
|
|
|
+ }
|
|
|
+
|
|
|
.log-filter {
|
|
|
margin-bottom: 20px;
|
|
|
padding: 15px;
|