245 lines
5.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="detail-container">
<el-form ref="formRef" :model="form" label-position="right" label-width="auto"
style="max-height: 60vh; overflow-y: auto; padding-right: 50px" :rules="rules">
<el-form-item label="" prop="schedules">
<div class="tree-transfer-container">
<!-- 左侧树形结构 -->
<div class="tree-panel">
<el-tree :data="treeOrgs" :props="{
children: 'children',
label: 'orgName'
}" node-key="orgId" :expand-on-click-node="false" :default-expand-all="false" highlight-current
style="height: 400px; overflow-y: auto;"
@node-click="handleNodeClick">
<template #default="{ node, data }">
<span class="custom-tree-node">
<span>{{ node.label }}</span>
</span>
</template>
</el-tree>
</div>
<!-- 中间空白区域 -->
<div class="middle-panel">
<!-- 暂留空后续使用 -->
</div>
<!-- 右侧空白区域 -->
<div class="right-panel">
<!-- 暂留空后续使用 -->
</div>
</div>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from "vue";
import { request } from "@/utils/request";
import { ElMessage } from 'element-plus';
const formRef = ref(null);
defineExpose({ formRef });
const props = defineProps({
form: {
type: Object,
default: () => ({}),
},
});
const rules = computed(() => {
return {
};
});
// 用户组织列表
const userOrgs = ref([]);
// 树形结构数据
const treeOrgs = ref([]);
// 查询用户组织
const getUserOrgs = async () => {
try {
const res = await request({
url: '/snow-ops-platform/user/userOrgs',
method: 'GET',
})
if (res.code === '00000') {
userOrgs.value = res.data.data
// 构造树形结构
treeOrgs.value = buildOrgTree(userOrgs.value)
} else {
throw new Error(res.message)
}
} catch (error) {
ElMessage.error('获取组织失败');
console.error('获取组织失败:', error);
}
}
/**
* 构建组织树形结构
* @param {Array} orgList 组织列表
* @returns {Array} 树形结构数据
*/
const buildOrgTree = (orgList) => {
if (!orgList || !orgList.length) return [];
// 创建映射表,便于查找
const orgMap = {};
orgList.forEach(org => {
orgMap[org.orgId] = {
...org,
children: []
};
});
const tree = [];
orgList.forEach(org => {
const currentOrg = orgMap[org.orgId];
// 根节点判断orgParentId为-1或orgPids为"[-1],"
if (org.orgParentId === -1 || org.orgPids === "[-1],") {
tree.push(currentOrg);
} else {
// 找到父节点
// 从orgPids中提取父级orgId这里简化处理实际可能需要更复杂的解析
let parentId = null;
// 方法1尝试从orgPids中解析父级ID
if (org.orgPids) {
const pidMatches = org.orgPids.match(/\d+/g);
if (pidMatches && pidMatches.length > 0) {
// 取最后一个ID作为直接父级排除-1
const parentIds = pidMatches.filter(id => id !== '-1');
if (parentIds.length > 0) {
parentId = parseInt(parentIds[parentIds.length - 1]);
}
}
}
// 方法2如果无法从orgPids解析使用orgParentId
if (parentId === null && org.orgParentId && org.orgParentId !== -1) {
parentId = org.orgParentId;
}
// 添加到父节点的children中
if (parentId && orgMap[parentId]) {
orgMap[parentId].children.push(currentOrg);
} else {
// 如果没有找到父节点,也作为根节点
tree.push(currentOrg);
}
}
});
// 按orgSort排序
const sortTree = (tree) => {
tree.sort((a, b) => (a.orgSort || 0) - (b.orgSort || 0));
tree.forEach(node => {
if (node.children && node.children.length) {
sortTree(node.children);
}
});
return tree;
};
return sortTree(tree);
}
// 树节点点击事件
const handleNodeClick = (data, node) => {
// 判断是否为叶子节点(没有子节点)
if (!node.childNodes || node.childNodes.length === 0) {
// 叶子节点,调用获取用户列表方法
getUsersByOrgId(data.orgId);
}
}
// 根据组织ID查询用户列表
const getUsersByOrgId = async (orgId) => {
try {
const res = await request({
url: '/snow-ops-platform/user/orgUsers',
method: 'GET',
params: {
orgId
}
})
if (res.code === '00000') {
console.log('@@@@@@用户列表',res.data);
} else {
throw new Error(res.message)
}
} catch (error) {
ElMessage.error('获取用户失败');
console.error('获取用户失败:', error);
}
}
onMounted(() => {
getUserOrgs();
})
</script>
<style scoped>
.form-part {
padding: 20px;
}
.text-center {
text-align: center;
}
.tree-transfer-container {
display: flex;
gap: 20px;
width: 100%;
}
.tree-panel {
flex: 1;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px;
background-color: #fff;
}
.empty-panel {
}
.middle-panel {
flex: 2;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px;
background-color: #fff;
}
.right-panel {
flex: 2;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px;
background-color: #fff;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
font-size: 14px;
padding-right: 8px;
}
</style>