数据修复工具:完善设备检索
This commit is contained in:
parent
4599221606
commit
4cc487c00f
@ -159,7 +159,7 @@ public class DeviceController extends BaseController {
|
||||
/**
|
||||
* 查询树形设备列表(用于报表生成等场景,网关设备可展开显示子设备)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasAnyPermi('iot:device:list,iot:report:generate')")
|
||||
@PreAuthorize("@ss.hasAnyPermi('iot:device:list,iot:report:generate,dataCenter:repair:list')")
|
||||
@GetMapping("/treeList")
|
||||
@ApiOperation("查询树形设备列表(网关可展开子设备)")
|
||||
public AjaxResult treeList(Device device) {
|
||||
|
||||
@ -47,16 +47,34 @@
|
||||
<el-form-item label="设备">
|
||||
<el-select
|
||||
v-model="queryParams.deviceId"
|
||||
placeholder="请选择设备"
|
||||
placeholder="请选择设备(可输入名称/编号检索)"
|
||||
filterable
|
||||
clearable
|
||||
@change="handleDeviceChange"
|
||||
style="width: 220px"
|
||||
style="width: 280px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in deviceList"
|
||||
:key="item.deviceId"
|
||||
:label="`${item.deviceName} (${item.serialNumber})`"
|
||||
:label="item.label"
|
||||
:value="item.deviceId"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 选中网关且其下挂有子设备时动态出现;不选则修复网关本体的物模型 -->
|
||||
<el-form-item v-if="gatewayChildren.length > 0" label="子设备">
|
||||
<el-select
|
||||
v-model="queryParams.subDeviceId"
|
||||
placeholder="不选则修复网关本体"
|
||||
filterable
|
||||
clearable
|
||||
@change="handleSubDeviceChange"
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in gatewayChildren"
|
||||
:key="item.deviceId"
|
||||
:label="item.label"
|
||||
:value="item.deviceId"
|
||||
></el-option>
|
||||
</el-select>
|
||||
@ -124,7 +142,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 自动校准配置弹窗 -->
|
||||
<el-dialog title="自动校准配置" :visible.sync="calibrationConfigVisible" width="600px" append-to-body v-dialogDrag>
|
||||
<el-dialog title="自动校准配置" :visible.sync="calibrationConfigVisible" width="720px" append-to-body v-dialogDrag>
|
||||
<el-alert
|
||||
type="info"
|
||||
:closable="false"
|
||||
@ -170,7 +188,24 @@
|
||||
<el-option
|
||||
v-for="item in deviceList"
|
||||
:key="item.deviceId"
|
||||
:label="`${item.deviceName} (${item.serialNumber})`"
|
||||
:label="item.label"
|
||||
:value="item.deviceId"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="configGatewayChildren.length > 0" label="子设备">
|
||||
<el-select
|
||||
v-model="newConfig.subDeviceId"
|
||||
placeholder="不选则配置网关本体"
|
||||
filterable
|
||||
clearable
|
||||
@change="handleConfigSubDeviceChange"
|
||||
style="width: 200px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in configGatewayChildren"
|
||||
:key="item.deviceId"
|
||||
:label="item.label"
|
||||
:value="item.deviceId"
|
||||
></el-option>
|
||||
</el-select>
|
||||
@ -337,7 +372,7 @@
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import { listDeviceShort, listThingsModel } from '@/api/iot/device.js';
|
||||
import { listDeviceTree, listThingsModel } from '@/api/iot/device.js';
|
||||
import {
|
||||
getRepairDataList,
|
||||
addDeviceLog,
|
||||
@ -367,13 +402,16 @@ export default {
|
||||
calibrationConfigList: [],
|
||||
newConfig: {
|
||||
deviceId: null,
|
||||
subDeviceId: null,
|
||||
identifier: null
|
||||
},
|
||||
configGatewayChildren: [],
|
||||
configIdentifierList: [],
|
||||
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
deviceId: null,
|
||||
subDeviceId: null,
|
||||
identifier: null,
|
||||
dateRange: [
|
||||
moment().subtract(24, 'hours').format('YYYY-MM-DD HH:mm:ss'),
|
||||
@ -384,7 +422,10 @@ export default {
|
||||
},
|
||||
|
||||
// 数据
|
||||
// 设备栏只放顶层设备(网关 + 直连设备);网关的子设备走按需出现的「子设备」栏
|
||||
deviceList: [],
|
||||
deviceMap: {},
|
||||
gatewayChildren: [],
|
||||
identifierList: [],
|
||||
tableData: [],
|
||||
total: 0,
|
||||
@ -450,17 +491,22 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 主设备(网关或直连设备)
|
||||
mainDevice() {
|
||||
return this.deviceMap[this.queryParams.deviceId];
|
||||
},
|
||||
// 有效设备:选了子设备就是子设备,否则是主设备(网关本体)
|
||||
currentDevice() {
|
||||
return this.deviceMap[this.queryParams.subDeviceId] || this.mainDevice;
|
||||
},
|
||||
currentDeviceName() {
|
||||
const device = this.deviceList.find(d => d.deviceId === this.queryParams.deviceId);
|
||||
const device = this.currentDevice;
|
||||
return device ? `${device.deviceName} (${device.serialNumber})` : '';
|
||||
},
|
||||
currentModelName() {
|
||||
const model = this.identifierList.find(m => m.identifier === this.queryParams.identifier);
|
||||
return model ? model.modelName : '';
|
||||
},
|
||||
currentDevice() {
|
||||
return this.deviceList.find(d => d.deviceId === this.queryParams.deviceId);
|
||||
},
|
||||
currentModel() {
|
||||
return this.identifierList.find(m => m.identifier === this.queryParams.identifier);
|
||||
}
|
||||
@ -506,19 +552,27 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 配置设备变化
|
||||
// 配置:主设备变化 → 重置子设备与物模型,并按需挂出该网关的子设备
|
||||
async handleConfigDeviceChange(deviceId) {
|
||||
this.newConfig.subDeviceId = null;
|
||||
this.newConfig.identifier = null;
|
||||
this.configGatewayChildren = [];
|
||||
this.configIdentifierList = [];
|
||||
if (!deviceId) return;
|
||||
try {
|
||||
const res = await listThingsModel({ deviceId, pageNum: 1, pageSize: 9999 });
|
||||
if (res.code === 200) {
|
||||
this.configIdentifierList = res.rows || [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('加载物模型失败', e);
|
||||
const device = this.deviceMap[deviceId];
|
||||
if (device && device.children.length) {
|
||||
this.configGatewayChildren = device.children;
|
||||
}
|
||||
this.configIdentifierList = await this.fetchIdentifierList(device);
|
||||
},
|
||||
|
||||
// 配置:子设备变化(清空则回到网关本体)
|
||||
async handleConfigSubDeviceChange(subDeviceId) {
|
||||
this.newConfig.identifier = null;
|
||||
this.configIdentifierList = [];
|
||||
const deviceId = subDeviceId || this.newConfig.deviceId;
|
||||
if (!deviceId) return;
|
||||
this.configIdentifierList = await this.fetchIdentifierList(this.deviceMap[deviceId]);
|
||||
},
|
||||
|
||||
// 添加自动校准配置
|
||||
@ -526,7 +580,7 @@ export default {
|
||||
if (!this.newConfig.deviceId || !this.newConfig.identifier) {
|
||||
return this.$message.warning('请选择设备和物模型');
|
||||
}
|
||||
const device = this.deviceList.find(d => d.deviceId === this.newConfig.deviceId);
|
||||
const device = this.deviceMap[this.newConfig.subDeviceId || this.newConfig.deviceId];
|
||||
const model = this.configIdentifierList.find(m => m.identifier === this.newConfig.identifier);
|
||||
if (!device || !model) {
|
||||
return this.$message.error('设备或物模型不存在');
|
||||
@ -581,35 +635,81 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 加载设备列表
|
||||
// 加载设备树:主栏只取顶层设备(网关 + 直连设备),子设备递归挂在所属网关的 children 上
|
||||
async loadDeviceList() {
|
||||
try {
|
||||
const res = await listDeviceShort({ showChild: true, pageNum: 1, pageSize: 9999 });
|
||||
if (res.code === 200) {
|
||||
this.deviceList = res.rows || [];
|
||||
}
|
||||
const res = await listDeviceTree({ showChild: true });
|
||||
if (res.code !== 200) return;
|
||||
const deviceMap = {};
|
||||
// 节点 → 下拉项;label 带编号(filterable 可按名称或编号检索),并同步写进 deviceId 索引
|
||||
const convert = (node) => {
|
||||
const option = {
|
||||
deviceId: node.deviceId,
|
||||
deviceName: node.deviceName,
|
||||
serialNumber: node.serialNumber,
|
||||
productId: node.productId,
|
||||
productName: node.productName,
|
||||
deviceType: node.deviceType,
|
||||
children: [],
|
||||
label: `${node.deviceType === 2 ? '🌐 ' : ''}${node.deviceName || node.serialNumber} (${node.serialNumber})`
|
||||
};
|
||||
deviceMap[node.deviceId] = option;
|
||||
option.children = (node.children || []).map(convert);
|
||||
return option;
|
||||
};
|
||||
const roots = (res.data || []).map(convert);
|
||||
// 整体替换而非逐键写入,保证 deviceMap 的响应式失效
|
||||
this.deviceMap = deviceMap;
|
||||
this.deviceList = roots;
|
||||
} catch (e) {
|
||||
console.error('加载设备列表失败', e);
|
||||
console.error('加载设备树失败', e);
|
||||
}
|
||||
},
|
||||
|
||||
// 设备变化
|
||||
// 设备变化:清空子设备栏与物模型;是网关则挂出子设备,并默认按网关本体加载物模型
|
||||
async handleDeviceChange(deviceId) {
|
||||
this.queryParams.subDeviceId = null;
|
||||
this.queryParams.identifier = null;
|
||||
this.gatewayChildren = [];
|
||||
this.identifierList = [];
|
||||
this.tableData = [];
|
||||
this.total = 0;
|
||||
|
||||
if (!deviceId) return;
|
||||
|
||||
const device = this.deviceMap[deviceId];
|
||||
if (device && device.children.length) {
|
||||
this.gatewayChildren = device.children;
|
||||
}
|
||||
|
||||
// 网关本体没有物模型时,物模型栏就空着,由用户去「子设备」里选
|
||||
this.identifierList = await this.fetchIdentifierList(device);
|
||||
},
|
||||
|
||||
// 子设备变化:选中则修复该子设备,清空则回到网关本体
|
||||
async handleSubDeviceChange(subDeviceId) {
|
||||
this.queryParams.identifier = null;
|
||||
this.identifierList = [];
|
||||
this.tableData = [];
|
||||
this.total = 0;
|
||||
|
||||
const deviceId = subDeviceId || this.queryParams.deviceId;
|
||||
if (!deviceId) return;
|
||||
this.identifierList = await this.fetchIdentifierList(this.deviceMap[deviceId]);
|
||||
},
|
||||
|
||||
// 查设备「自己」的物模型(属性type=1、功能type=2、事件type=3)
|
||||
// ⚠️ /iot/device/listThingsModel 会把网关下所有子设备的物模型也合并返回(带 parentSerialNumber),
|
||||
// 修复页只认选中设备自身的物模型,否则子设备的标识符会被当成网关的物模型去查询/新增
|
||||
async fetchIdentifierList(device) {
|
||||
if (!device) return [];
|
||||
try {
|
||||
const res = await listThingsModel({ deviceId, pageNum: 1, pageSize: 9999 });
|
||||
if (res.code === 200) {
|
||||
// 显示所有物模型(属性type=1、功能type=2、事件type=3)
|
||||
this.identifierList = res.rows || [];
|
||||
}
|
||||
const res = await listThingsModel({ deviceId: device.deviceId, pageNum: 1, pageSize: 9999 });
|
||||
const rows = res.code === 200 ? (res.rows || []) : [];
|
||||
return rows.filter(model => model.serialNumber === device.serialNumber);
|
||||
} catch (e) {
|
||||
console.error('加载物模型失败', e);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
@ -632,6 +732,7 @@ export default {
|
||||
handleReset() {
|
||||
this.queryParams = {
|
||||
deviceId: null,
|
||||
subDeviceId: null,
|
||||
identifier: null,
|
||||
dateRange: [
|
||||
moment().subtract(24, 'hours').format('YYYY-MM-DD HH:mm:ss'),
|
||||
@ -640,6 +741,7 @@ export default {
|
||||
pageNum: 1,
|
||||
pageSize: 50
|
||||
};
|
||||
this.gatewayChildren = [];
|
||||
this.identifierList = [];
|
||||
this.tableData = [];
|
||||
this.total = 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user