forked from dyf/dyf-vue-ui
设备分组功能完成
This commit is contained in:
@ -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",
|
||||
|
421
src/api/equipmentManagement/devicegroup/index.ts
Normal file
421
src/api/equipmentManagement/devicegroup/index.ts
Normal 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
|
||||
}
|
BIN
src/assets/images/searchIcon.png
Normal file
BIN
src/assets/images/searchIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
1151
src/views/fys-equipment/group/index.vue
Normal file
1151
src/views/fys-equipment/group/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@ -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 会假设你的应用是被部署在一个域名的根路径上
|
||||
|
Reference in New Issue
Block a user