1
0
forked from dyf/dyf-vue-ui

设备分组功能完成

This commit is contained in:
liub
2025-09-01 17:27:11 +08:00
parent 3782f73215
commit 7f85623cb2
5 changed files with 1576 additions and 4 deletions

View File

@ -76,7 +76,7 @@
"unplugin-icons": "22.1.0",
"unplugin-vue-components": "28.5.0",
"unplugin-vue-setup-extend-plus": "1.0.1",
"vite": "6.3.2",
"vite": "^7.1.3",
"vite-plugin-compression": "0.5.1",
"vite-plugin-svg-icons-ng": "^1.4.0",
"vite-plugin-vue-devtools": "7.7.5",

View File

@ -0,0 +1,421 @@
import { func } from 'vue-types';
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
//左侧节点的数据源
function getTreeData(para : any) {
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) => {
Promise.allSettled([ promise2]).then(res => {
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") {
let updateTree=function(){
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; // 未找到匹配的节点
}
let requestUpdate=function(){
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; // 未找到匹配的节点
}
let requestDel=function(){
let promise2 = new Promise((resolve, reject) => {
request({
url: '/api/device/group/'+targetValue,
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',
params:{
"deviceStatus": 1,
"pageNum": para.pageIndex,
"pageSize": para.pageSize,
"groupId": para.nodeCode,
}
}).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);
}
});
});
}
//从分组中删除设备
function groupDelDevice(groupid,deviceIds){
return new Promise((resolve,reject)=>{
request({
url: '/api/device/group/groupUnbind/'+deviceIds,
method: 'get',
}).then((res) => {
resolve(res);
}).catch((ex) => {
reject(ex);
});
});
}
//将设备移动至分组
function deviceMoveGroup(groupid,deviceIds){
return new Promise((resolve,reject)=>{
request({
url: '/api/device/group/groupId/'+groupid+'/'+deviceIds,
method: 'get',
}).then((res) => {
resolve(res);
}).catch((ex) => {
reject(ex);
});
});
}
export default {
getTreeData: getTreeData,
treeNodeSearch: treeNodeSearch,
updateTreeName: updateTreeName,
addTreeNode: addTreeNode,
delTreeNode: delTreeNode,
getNodeDevice: getNodeDevice,
groupDelDevice:groupDelDevice,
deviceMoveGroup:deviceMoveGroup
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because it is too large Load Diff

View File

@ -5,17 +5,17 @@ import path from 'path';
export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, process.cwd());
// 参考eladmin-web的部署方式使用相对路径
let basePath = '/';
if (mode === 'production') {
if (mode === 'development') {
// 生产环境:如果设置了上下文路径则使用,否则使用相对路径
basePath = env.VITE_APP_CONTEXT_PATH || './';
} else {
// 开发环境:使用上下文路径或默认根路径
basePath = env.VITE_APP_CONTEXT_PATH || '/';
}
return {
// 部署生产环境和开发环境下的URL。
// 默认情况下vite 会假设你的应用是被部署在一个域名的根路径上