2025-09-01 17:27:11 +08:00
|
|
|
|
import { func } from 'vue-types';
|
|
|
|
|
import request from '@/utils/request';
|
|
|
|
|
import { AxiosPromise } from 'axios';
|
|
|
|
|
|
|
|
|
|
//左侧节点的数据源
|
2025-09-02 09:46:45 +08:00
|
|
|
|
function getTreeData(para: any) {
|
2025-09-01 17:27:11 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let promise2 = new Promise((resolve, reject) => {
|
|
|
|
|
request({
|
|
|
|
|
url: '/api/device/group/list',
|
|
|
|
|
method: 'get',
|
|
|
|
|
params: {
|
|
|
|
|
"createDept": null,
|
|
|
|
|
"createBy": null,
|
|
|
|
|
"createTime": "",
|
|
|
|
|
"updateBy": null,
|
|
|
|
|
"updateTime": "",
|
|
|
|
|
"params": {
|
|
|
|
|
"additionalProp1": "",
|
|
|
|
|
"additionalProp2": "",
|
|
|
|
|
"additionalProp3": ""
|
|
|
|
|
},
|
|
|
|
|
"id": null,
|
|
|
|
|
"groupName": para,
|
|
|
|
|
"status": 1,
|
|
|
|
|
"parentId": null,
|
|
|
|
|
"fullPath": "",
|
|
|
|
|
"isDeleted": 0,
|
|
|
|
|
"pageNum": 1,
|
|
|
|
|
"pageSize": 99999
|
|
|
|
|
}
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
resolve(res);
|
|
|
|
|
}).catch((ex) => {
|
|
|
|
|
reject(ex);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
2025-09-02 09:46:45 +08:00
|
|
|
|
Promise.allSettled([promise2]).then(res => {
|
2025-09-01 17:27:11 +08:00
|
|
|
|
debugger;
|
|
|
|
|
if (res[0].status == 'fulfilled') {
|
|
|
|
|
let json = res[0].value;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resolve(json.data);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//节点搜索
|
|
|
|
|
function treeNodeSearch(treeData, search = '', filed = 'groupName', childField = 'children') {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 对文本进行标准化处理(去除空格和转换为小写)
|
|
|
|
|
* @param {string} text - 需要处理的文本
|
|
|
|
|
* @returns {string} 标准化后的文本
|
|
|
|
|
*/
|
|
|
|
|
function normalizeText(text) {
|
|
|
|
|
return text.replace(/\s+/g, '').toLowerCase();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 收集所有末级元素的完整路径
|
|
|
|
|
* @param {Array} nodes - 节点数组
|
|
|
|
|
* @param {Array} currentPath - 当前路径
|
|
|
|
|
* @param {Array} leafPaths - 存储末级元素路径的数组
|
|
|
|
|
*/
|
|
|
|
|
function collectLeafPaths(nodes, currentPath, leafPaths, childField) {
|
|
|
|
|
if (!nodes || !nodes.length) return;
|
|
|
|
|
|
|
|
|
|
for (let node of nodes) {
|
|
|
|
|
// 创建包含当前节点的新路径
|
|
|
|
|
let newPath = [...currentPath, node];
|
|
|
|
|
|
|
|
|
|
// 检查是否为末级元素(没有children或children为空)
|
|
|
|
|
if (!node[childField] || !node[childField].length) {
|
|
|
|
|
leafPaths.push(newPath);
|
|
|
|
|
} else {
|
|
|
|
|
// 递归处理子节点
|
|
|
|
|
collectLeafPaths(node[childField], newPath, leafPaths, childField);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 检查路径上是否有任何节点匹配搜索条件
|
|
|
|
|
* @param {Array} path - 节点路径数组
|
|
|
|
|
* @param {string} searchTerm - 标准化后的搜索词
|
|
|
|
|
* @returns {boolean} 是否匹配
|
|
|
|
|
*/
|
|
|
|
|
function checkPathMatches(path, searchTerm, field) {
|
|
|
|
|
return path.some(node =>
|
|
|
|
|
normalizeText(node[field]).includes(searchTerm)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将路径数组转换为嵌套的层级结构
|
|
|
|
|
* @param {Array} path - 节点路径数组
|
|
|
|
|
* @returns {Object} 嵌套结构的节点
|
|
|
|
|
*/
|
|
|
|
|
function buildHierarchy(path, childField) {
|
|
|
|
|
// 从最后一个节点开始向前构建
|
|
|
|
|
let currentNode = { ...path[path.length - 1] };
|
|
|
|
|
// 移除children属性(末级节点不应有children)
|
|
|
|
|
if (currentNode[childField]) delete currentNode[childField];
|
|
|
|
|
|
|
|
|
|
// 从倒数第二个节点开始向前遍历
|
|
|
|
|
for (let i = path.length - 2; i >= 0; i--) {
|
|
|
|
|
let node = { ...path[i] };
|
|
|
|
|
// 将当前节点作为子节点
|
|
|
|
|
node[childField] = [currentNode];
|
|
|
|
|
currentNode = node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return currentNode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function mergeHierarchies(hierarchies) {
|
|
|
|
|
if (!hierarchies || hierarchies.length === 0) return [];
|
|
|
|
|
|
|
|
|
|
// 使用Map存储相同txt的节点,key为txt
|
|
|
|
|
let nodeMap = new Map();
|
|
|
|
|
|
|
|
|
|
for (let node of hierarchies) {
|
|
|
|
|
let key = node.txt;
|
|
|
|
|
|
|
|
|
|
if (nodeMap.has(key)) {
|
|
|
|
|
// 如果已存在相同txt的节点,合并它们的子节点
|
|
|
|
|
let existingNode = nodeMap.get(key);
|
|
|
|
|
existingNode.child = mergeHierarchies([
|
|
|
|
|
...(existingNode.child || []),
|
|
|
|
|
...(node.child || [])
|
|
|
|
|
]);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不存在,直接添加到Map
|
|
|
|
|
nodeMap.set(key, { ...node });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将Map的值转换为数组并返回
|
|
|
|
|
return Array.from(nodeMap.values());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成路径的唯一标识
|
|
|
|
|
* @param {Object} node - 节点对象
|
|
|
|
|
* @param {string} prefix - 前缀
|
|
|
|
|
* @returns {string} 路径标识
|
|
|
|
|
*/
|
|
|
|
|
function getPathKey(node, prefix = '', field, childField) {
|
|
|
|
|
let currentKey = prefix ? `${prefix}->${node[field]}` : node[field];
|
|
|
|
|
if (node[childField] && node[childField].length) {
|
|
|
|
|
return getPathKey(node[childField][0], currentKey, field, childField);
|
|
|
|
|
}
|
|
|
|
|
return currentKey;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从末级元素开始向上搜索匹配的路径
|
|
|
|
|
* @param {Array} data - 数据源数组
|
|
|
|
|
* @param {string} keyword - 搜索关键词
|
|
|
|
|
* @returns {Array} 匹配的层级结构数组,与原数据结构一致
|
|
|
|
|
*/
|
|
|
|
|
function searchLabels(data, keyword, field, childField) {
|
|
|
|
|
if (!data || !Array.isArray(data)) {
|
|
|
|
|
return [];
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!keyword) {
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 标准化搜索关键词
|
|
|
|
|
let searchTerm = normalizeText(keyword);
|
|
|
|
|
|
|
|
|
|
// 收集所有末级元素的完整路径
|
|
|
|
|
let leafPaths = [];
|
|
|
|
|
collectLeafPaths(data, [], leafPaths, childField);
|
|
|
|
|
|
|
|
|
|
// 筛选出符合条件的路径
|
|
|
|
|
let matchedPaths = leafPaths.filter(path =>
|
|
|
|
|
checkPathMatches(path, searchTerm, field, childField)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 将路径转换为嵌套结构
|
|
|
|
|
let results = matchedPaths.map(path => buildHierarchy(path, childField));
|
|
|
|
|
// 去重并返回结果
|
|
|
|
|
return mergeHierarchies(results);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let searchList = searchLabels(treeData, search, filed, childField);
|
|
|
|
|
|
|
|
|
|
return searchList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新节点名称
|
|
|
|
|
function updateTreeName(nodes, targetValue, newTxt, filed = 'groupName', childField = "children", valueFiled = "id") {
|
2025-09-02 09:46:45 +08:00
|
|
|
|
let updateTree = function () {
|
2025-09-01 17:27:11 +08:00
|
|
|
|
for (let node of nodes) {
|
|
|
|
|
// 检查当前节点是否匹配value
|
|
|
|
|
if (node[valueFiled] === targetValue) {
|
|
|
|
|
node[filed] = newTxt;
|
|
|
|
|
return true; // 找到并更新,返回true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果有子节点,递归查找
|
|
|
|
|
if (node[childField] && node[childField].length > 0) {
|
|
|
|
|
let found = updateTreeName(node[childField], targetValue, newTxt);
|
|
|
|
|
if (found) {
|
|
|
|
|
return true; // 在子节点中找到,返回true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false; // 未找到匹配的节点
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-02 09:46:45 +08:00
|
|
|
|
let requestUpdate = function () {
|
2025-09-01 17:27:11 +08:00
|
|
|
|
let promise2 = new Promise((resolve, reject) => {
|
|
|
|
|
request({
|
|
|
|
|
url: '/api/device/group',
|
|
|
|
|
method: 'put',
|
|
|
|
|
data: targetValue
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
resolve(res);
|
|
|
|
|
}).catch((ex) => {
|
|
|
|
|
reject(ex);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
return promise2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return requestUpdate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//添加新节点
|
|
|
|
|
function addTreeNode(nodes, newNode, targetValue, childField = "children", valueFiled = "id") {
|
|
|
|
|
|
|
|
|
|
let updateTree = function () {
|
|
|
|
|
if (!targetValue) {
|
|
|
|
|
nodes.push(newNode);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
for (let node of nodes) {
|
|
|
|
|
// 检查当前节点是否匹配value
|
|
|
|
|
if (node.value === targetValue) {
|
|
|
|
|
if (!node[childField]) {
|
|
|
|
|
node[childField] = [];
|
|
|
|
|
}
|
|
|
|
|
node[childField].push(newNode);
|
|
|
|
|
return true; // 找到并更新,返回true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果有子节点,递归查找
|
|
|
|
|
if (node[childField] && node[childField].length > 0) {
|
|
|
|
|
let found = addTreeNode(node[childField], newNode, targetValue);
|
|
|
|
|
if (found) {
|
|
|
|
|
return true; // 在子节点中找到,返回true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false; // 未找到匹配的节点
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let requestAddnode = function () {
|
|
|
|
|
let promise2 = new Promise((resolve, reject) => {
|
|
|
|
|
request({
|
|
|
|
|
url: '/api/device/group',
|
|
|
|
|
method: 'post',
|
|
|
|
|
data: newNode
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
resolve(res);
|
|
|
|
|
}).catch((ex) => {
|
|
|
|
|
reject(ex);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
return promise2;
|
|
|
|
|
}
|
|
|
|
|
return requestAddnode();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//删除某个节点
|
|
|
|
|
function delTreeNode(nodes, targetValue, childField = "children", valueFiled = "id") {
|
|
|
|
|
let updateTree = function () {
|
|
|
|
|
if (!targetValue) {
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
for (let node of nodes) {
|
|
|
|
|
// 检查当前节点是否匹配value
|
|
|
|
|
if (node[valueFiled] === targetValue) {
|
|
|
|
|
let index = nodes.indexOf(node);
|
|
|
|
|
if (index > -1) {
|
|
|
|
|
nodes.splice(index, 1);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果有子节点,递归查找
|
|
|
|
|
if (node[childField] && node[childField].length > 0) {
|
|
|
|
|
let found = delTreeNode(node[childField], targetValue);
|
|
|
|
|
if (found) {
|
|
|
|
|
return true; // 在子节点中找到,返回true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false; // 未找到匹配的节点
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-02 09:46:45 +08:00
|
|
|
|
let requestDel = function () {
|
2025-09-01 17:27:11 +08:00
|
|
|
|
let promise2 = new Promise((resolve, reject) => {
|
|
|
|
|
request({
|
2025-09-02 09:46:45 +08:00
|
|
|
|
url: '/api/device/group/' + targetValue,
|
2025-09-01 17:27:11 +08:00
|
|
|
|
method: 'delete',
|
|
|
|
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
resolve(res);
|
|
|
|
|
}).catch((ex) => {
|
|
|
|
|
reject(ex);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
return promise2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return requestDel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取某个节点的设备数据
|
|
|
|
|
function getNodeDevice(para) {
|
|
|
|
|
let promise2 = new Promise((resolve, reject) => {
|
|
|
|
|
request({
|
|
|
|
|
url: '/api/device',
|
|
|
|
|
method: 'get',
|
2025-09-02 09:46:45 +08:00
|
|
|
|
params: {
|
|
|
|
|
"deviceStatus": 1,
|
|
|
|
|
"pageNum": para.pageIndex,
|
|
|
|
|
"pageSize": para.pageSize,
|
|
|
|
|
"groupId": para.nodeCode,
|
|
|
|
|
"communicationMode": para.communicationMode,//通讯方式 0:4G;1:蓝牙
|
|
|
|
|
"deviceType": para.deviceType,//设备类型
|
|
|
|
|
"deviceName": para.deviceName
|
2025-09-01 17:27:11 +08:00
|
|
|
|
|
2025-09-02 09:46:45 +08:00
|
|
|
|
}
|
2025-09-01 17:27:11 +08:00
|
|
|
|
}).then((res) => {
|
|
|
|
|
resolve(res);
|
|
|
|
|
}).catch((ex) => {
|
|
|
|
|
reject(ex);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
Promise.allSettled([promise2]).then(res => {
|
|
|
|
|
|
|
|
|
|
if (res[0].status == 'fulfilled') {
|
|
|
|
|
debugger;
|
|
|
|
|
resolve(res[0].value);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//从分组中删除设备
|
2025-09-02 09:46:45 +08:00
|
|
|
|
function groupDelDevice(groupid, deviceIds) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
2025-09-01 17:27:11 +08:00
|
|
|
|
request({
|
2025-09-02 09:46:45 +08:00
|
|
|
|
url: '/api/device/group/groupUnbind/' + deviceIds,
|
|
|
|
|
method: 'get',
|
|
|
|
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
resolve(res);
|
|
|
|
|
}).catch((ex) => {
|
|
|
|
|
reject(ex);
|
|
|
|
|
});
|
2025-09-01 17:27:11 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//将设备移动至分组
|
2025-09-02 09:46:45 +08:00
|
|
|
|
function deviceMoveGroup(groupid, deviceIds) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
2025-09-01 17:27:11 +08:00
|
|
|
|
request({
|
2025-09-02 09:46:45 +08:00
|
|
|
|
url: '/api/device/group/groupId/' + groupid + '/' + deviceIds,
|
|
|
|
|
method: 'get',
|
|
|
|
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
resolve(res);
|
|
|
|
|
}).catch((ex) => {
|
|
|
|
|
reject(ex);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//获取设备类型
|
|
|
|
|
function getDeviceTypeAll(){
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
request({
|
|
|
|
|
url: '/api/deviceType/all' ,
|
|
|
|
|
method: 'get',
|
|
|
|
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
resolve(res);
|
|
|
|
|
}).catch((ex) => {
|
|
|
|
|
reject(ex);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取通讯方式
|
|
|
|
|
function getNetMode () {
|
|
|
|
|
return request({
|
|
|
|
|
url: '/api/deviceType/communicationMode',
|
|
|
|
|
method: 'get'
|
2025-09-01 17:27:11 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
getTreeData: getTreeData,
|
|
|
|
|
treeNodeSearch: treeNodeSearch,
|
|
|
|
|
updateTreeName: updateTreeName,
|
|
|
|
|
addTreeNode: addTreeNode,
|
|
|
|
|
delTreeNode: delTreeNode,
|
|
|
|
|
getNodeDevice: getNodeDevice,
|
2025-09-02 09:46:45 +08:00
|
|
|
|
groupDelDevice: groupDelDevice,
|
|
|
|
|
deviceMoveGroup: deviceMoveGroup,
|
|
|
|
|
getDeviceTypeAll:getDeviceTypeAll,
|
|
|
|
|
getNetMode:getNetMode
|
|
|
|
|
|
2025-09-01 17:27:11 +08:00
|
|
|
|
}
|