diff --git a/src/views/board/components/listItem.vue b/src/views/board/components/listItem.vue index f30122e..b93b91f 100644 --- a/src/views/board/components/listItem.vue +++ b/src/views/board/components/listItem.vue @@ -1,18 +1,48 @@ @@ -26,12 +56,14 @@ export default { data() { return { height: 0, - width: 0 + width: 0, + top: 0, } }, mounted() { - this.height = this.getVerticalDiff(this.$refs.listItemTitleRef) - this.width = this.getElementWidth(this.$refs.listItemTitleRef) + this.height = this.getVerticalDiff(this.$refs.listItemTitleRef) || 0 + this.width = this.getElementWidth(this.$refs.listItemTitleRef) || 0 + this.top = this.getFirstItemCenterY(this.$refs.listItemTitleRef) || 0 }, methods: { getVerticalDiff(titleEl) { @@ -45,7 +77,7 @@ export default { const titles = []; for (let item of listItems) { - const title = item.querySelector(':scope > .listItemTitle'); + const title = item.querySelector(':scope > .itemDiv'); if (title) titles.push(title); } @@ -61,6 +93,29 @@ export default { return Math.abs(lastCenterY - firstCenterY); }, + getFirstItemCenterY(titleEl) { + if (!titleEl) return null; + + // 找到父容器中 children + const parentEl = titleEl.parentElement.querySelector('.children'); + if (!parentEl) return null; + + // 找到 children 的第一个直接子元素 + const firstItem = parentEl.children[0]; + if (!firstItem) return null; + + // 找到第一个子元素中的 .itemDiv + const firstTitle = firstItem.querySelector(':scope > .itemDiv'); + if (!firstTitle) return null; + + const containerRect = parentEl.getBoundingClientRect(); + const firstRect = firstTitle.getBoundingClientRect(); + + // 计算中心高度,相对于父容器 + const firstCenterY = (firstRect.top + firstRect.height / 2) - containerRect.top; + + return firstCenterY; + }, getElementWidth(el) { if (!el) return null; const rect = el.getBoundingClientRect(); @@ -78,10 +133,58 @@ export default { padding: 20px; position: relative; + + .deviceItem { + padding: 6px 20px; + color: #fff; + border-radius: 6px; + white-space: nowrap; + min-width: 100px; + + .title { + width: 100%; + height: 40px; + line-height: 40px; + text-align: center; + border: 1px solid #fff; + border-bottom: 0; + } + + .content { + width: 100%; + height: auto; + border: 1px solid #fff; + + .name { + width: 100%; + height: 40px; + line-height: 40px; + text-align: center; + border-bottom: 1px solid #fff; + } + + .list { + height: 40px; + line-height: 40px; + white-space: nowrap; + + .value { + display: inline-block; + min-width: 100px; + margin-right: 20px; + text-align: center; + } + + .units { + display: inline-block; + min-width: 50px; + } + } + } + } + .line { position: absolute; - top: 50%; - transform: translateY(-50%); width: 1px; background: #fff; } diff --git a/src/views/board/index1.vue b/src/views/board/index1.vue index 25c9fde..62b0e64 100644 --- a/src/views/board/index1.vue +++ b/src/views/board/index1.vue @@ -26,176 +26,130 @@ export default { return { list1: [ { - name: '根节点1', - children: [ + "name": "root", + "children": [ { - name: '节点1', - children: [ + "name": "child-1", + "children": [ { - name: '节点1-1', - id: '1-1', - device: [ + "name": "child-1-1", + "children": [ { - name: '设备1', - data: [ - { - name: '数据1', - value: '10', - units: "℃" - }, - { - name: '数据2', - value: '20', - units: "℃" - } + "name": "child-1-1-1", + "children": [], + "device": [ + {"name": "device-1-1-1-a", "children": [], "device": []}, + {"name": "device-1-1-1-b", "children": [], "device": []} ] }, { - name: '设备2', - data: [ - { - name: '数据1', - value: '10', - units: "℃" - }, - { - name: '数据2', - value: '20', - units: "℃" - } + "name": "child-1-1-2", + "children": [], + "device": [ + {"name": "device-1-1-2-a", "children": [], "device": []}, + {"name": "device-1-1-2-b", "children": [], "device": []} ] } + ], + "device": [ + {"name": "device-1-1-a", "children": [], "device": []}, + {"name": "device-1-1-b", "children": [], "device": []} ] }, { - name: '节点1-2', - device: [ + "name": "child-1-2", + "children": [ { - name: '设备1', - data: [ - { - name: '数据1', - value: '10', - units: "℃" - }, - { - name: '数据2', - value: '20', - units: "℃" - } + "name": "child-1-2-1", + "children": [], + "device": [ + {"name": "device-1-2-1-a", "children": [], "device": []}, + {"name": "device-1-2-1-b", "children": [], "device": []} ] }, { - name: '设备2', - data: [ - { - name: '数据1', - value: '10', - units: "℃" - }, - { - name: '数据2', - value: '20', - units: "℃" - } + "name": "child-1-2-2", + "children": [], + "device": [ + {"name": "device-1-2-2-a", "children": [], "device": []}, + {"name": "device-1-2-2-b", "children": [], "device": []} ] } + ], + "device": [ + {"name": "device-1-2-a", "children": [], "device": []}, + {"name": "device-1-2-b", "children": [], "device": []} ] } + ], + "device": [ + {"name": "device-1-a", "children": [], "device": []}, + {"name": "device-1-b", "children": [], "device": []} ] }, { - name: '节点2', - children: [ + "name": "child-2", + "children": [ { - name: '节点1-1', - id: '1-1', - device: [ + "name": "child-2-1", + "children": [ { - name: '设备1', - data: [ - { - name: '数据1', - value: '10', - units: "℃" - }, - { - name: '数据2', - value: '20', - units: "℃" - } + "name": "child-2-1-1", + "children": [], + "device": [ + {"name": "device-2-1-1-a", "children": [], "device": []}, + {"name": "device-2-1-1-b", "children": [], "device": []} ] }, { - name: '设备2', - data: [ - { - name: '数据1', - value: '10', - units: "℃" - }, - { - name: '数据2', - value: '20', - units: "℃" - } + "name": "child-2-1-2", + "children": [], + "device": [ + {"name": "device-2-1-2-a", "children": [], "device": []}, + {"name": "device-2-1-2-b", "children": [], "device": []} ] } + ], + "device": [ + {"name": "device-2-1-a", "children": [], "device": []}, + {"name": "device-2-1-b", "children": [], "device": []} ] }, { - name: '节点1-2', - device: [ + "name": "child-2-2", + "children": [ { - name: '设备1', - data: [ - { - name: '数据1', - value: '10', - units: "℃" - }, - { - name: '数据2', - value: '20', - units: "℃" - } + "name": "child-2-2-1", + "children": [], + "device": [ + {"name": "device-2-2-1-a", "children": [], "device": []}, + {"name": "device-2-2-1-b", "children": [], "device": []} ] }, { - name: '设备2', - data: [ - { - name: '数据1', - value: '10', - units: "℃" - }, - { - name: '数据2', - value: '20', - units: "℃" - } + "name": "child-2-2-2", + "children": [], + "device": [ + {"name": "device-2-2-2-a", "children": [], "device": []}, + {"name": "device-2-2-2-b", "children": [], "device": []} ] } + ], + "device": [ + {"name": "device-2-2-a", "children": [], "device": []}, + {"name": "device-2-2-b", "children": [], "device": []} ] } + ], + "device": [ + {"name": "device-2-a", "children": [], "device": []}, + {"name": "device-2-b", "children": [], "device": []} ] } - ] - }, - { - name: '根节点2', - children: [ - { - name: '节点2', - children: [ - { - name: '节点2-1' - }, - { - name: '节点2-2' - } - ] - } + ], + "device": [ + {"name": "device-root-a", "children": [], "device": []}, + {"name": "device-root-b", "children": [], "device": []} ] } ], @@ -209,71 +163,55 @@ export default { zxyg: '', fxyg: '', }; - const fieldFilter = ['vA', 'vB', 'vC', 'iA', 'iB', 'iC', 'glys', 'zxyg', 'fxyg', 'fluxFlow', 'waterFlow', 'steamFlow', 'temperature', 'press', 'density', 'purity']; + const fieldFilter = ['vA', 'vB', 'vC', 'iA', 'iB', 'iC', 'zxyg', 'fxyg']; realTimeData({ monitorType: 2 }).then(res => { console.log(res) - const tree = this.buildTree(res.data, 0, fieldUnits, fieldFilter); + const tree = this.buildTree(res.data, fieldUnits, fieldFilter); this.list = tree console.log(tree) }) }, methods: { - buildTree(list, rootId = 0, fieldUnits = {}, fieldFilter = []) { - const map = new Map(list.map(item => [item.objId, {...item}])); - - function processNode(node) { - // 处理 data 字段 - const isAmmeter = String(node.isAmmeter); - if (isAmmeter !== "0") { - const data = []; - for (const key of fieldFilter) { - if (node.hasOwnProperty(key) && node[key] !== null && node[key] !== undefined) { - data.push({value: node[key], units: fieldUnits[key] || ''}); - delete node[key]; // 删除原字段 - } - } - if (data.length) node.data = data; - } - - // 递归处理子节点 - const children = []; - const devices = []; - for (const child of list) { - if (child.parentId === node.objId) { - const childNode = map.get(child.objId); - processNode(childNode); // 递归 - // 所有子节点根据自身 isAmmeter 决定挂到 children 或 device - if (String(childNode.isAmmeter) === "0") { - children.push(childNode); - } else { - devices.push(childNode); - } - } - } - - if (children.length) node.children = children; - if (devices.length) node.device = devices; - - // 删除空字段 - if (node.children && node.children.length === 0) delete node.children; - if (node.device && node.device.length === 0) delete node.device; - } - + buildTree(data, fieldUnits, fieldFilter) { + const map = {}; const tree = []; - for (const item of list) { - if (item.parentId === rootId) { - const node = map.get(item.objId); - processNode(node); + + // 先创建map,key为objId + data.forEach(item => { + // 深拷贝,防止修改原数组 + map[item.objId] = {...item, children: [], device: []}; + + // 如果isAmmeter为1,生成deviceData + if (item.isAmmeter === "1") { + map[item.objId].deviceData = fieldFilter + .filter(f => f in item) + .map(f => ({ + name: f, + value: item[f], + units: fieldUnits[f] || '' + })); + } + }); + + // 构建树 + data.forEach(item => { + const node = map[item.objId]; + if (item.parentId && map[item.parentId]) { + map[item.parentId].children.push(node); + // 如果需要,把isAmmeter为1的节点也放到device数组里 + // if (item.isAmmeter === "1") { + // map[item.parentId].device.push(node); + // } + } else { tree.push(node); } - } + }); return tree; } - } }