Files
admin-govern/src/views/govern/device/planData/components/schemeTree.vue
2024-12-25 10:53:07 +08:00

400 lines
13 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>
<div :style="{ width: menuCollapse ? '40px' : '280px' }" style=" overflow: hidden; height: 100%">
<Icon v-show="menuCollapse" @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 mt20 menu-collapse"
style="cursor: pointer" />
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1, display: menuCollapse ? 'none' : '' }">
<div style="display: flex; align-items: center" class="mb10">
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
<template #prefix>
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>
</el-input>
<el-tooltip placement="bottom" :hide-after="0">
<template #content>
<span>新增方案</span>
</template>
<Icon name="el-icon-Plus" size="18" class="fold ml10 menu-collapse" style="cursor: pointer"
@click="onAdd" />
</el-tooltip>
<Icon @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 menu-collapse"
style="cursor: pointer" />
</div>
<el-tree style="flex: 1; overflow: auto" :props="defaultProps" highlight-current
:filter-node-method="filterNode" node-key="id" v-bind="$attrs" default-expand-all :data="tree"
ref="treRef" @node-click="clickNode" :expand-on-click-node="false">
<template #default="{ node, data }">
<span class="custom-tree-node">
<div class="left">
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
v-if="data.icon" />
<span>{{ node.label }}</span>
</div>
<div class="right">
<a :style="{ marginRight: '0.5rem' }" v-if="data?.children">
<el-icon :style="{ color: '#0000FF' }">
<el-tooltip placement="bottom" :hide-after="0">
<template #content>
<span>新增测试项</span>
</template>
<Plus @click.stop="add(node, data)" />
</el-tooltip>
</el-icon>
</a>
<a :style="{ marginRight: '0.5rem' }" v-else>
<el-icon :style="{ color: '#0000FF' }">
<el-tooltip placement="bottom" :hide-after="0">
<template #content>
<span>数据绑定</span>
</template>
<SetUp @click.stop="bind(node, data)" />
</el-tooltip>
</el-icon>
</a>
<a :style="{ marginRight: '0.5rem' }">
<el-icon :style="{ color: '#0000FF' }">
<el-tooltip placement="bottom" :hide-after="0">
<template #content>
<span> {{ data.pid ? '修改测试项' : ' 修改测试方案' }}</span>
</template>
<Edit @click.stop="edit(node, data)" />
</el-tooltip>
</el-icon>
</a>
<a :style="{ marginRight: '0.5rem' }">
<el-icon :style="{ color: '#DA3434' }">
<Delete @click.stop="del(node, data)" />
</el-icon>
</a>
</div>
</span>
</template>
</el-tree>
</div>
</div>
<popup ref="dialogRef" @onSubmit="getTreeList"></popup>
</div>
</template>
<script lang="ts" setup>
import { ref, nextTick, watch, defineProps, defineEmits } from 'vue'
import { getSchemeTree, getTestRecordInfo } from '@/api/cs-device-boot/planData'
import { useConfig } from '@/stores/config'
import useCurrentInstance from '@/utils/useCurrentInstance'
import { ElTree } from 'element-plus'
import { Plus, Edit, Delete, SetUp } from '@element-plus/icons-vue'
import { delRecord } from '@/api/cs-device-boot/planData'
import popup from './popup.vue'
import { getDeviceList } from '@/api/cs-device-boot/planData'
import { ElMessage, ElMessageBox } from 'element-plus'
defineOptions({
name: 'govern/schemeTree'
})
interface Props {
width?: string
canExpand?: boolean
}
const visible1 = ref(false)
const visible2 = ref(false)
const visible3 = ref(false)
const visible4 = ref(false)
const { proxy } = useCurrentInstance()
const menuCollapse = ref(false)
const filterText = ref('')
const treeRef = ref<InstanceType<typeof ElTree>>()
watch(filterText, val => {
treRef.value!.filter(val)
})
const onMenuCollapse = () => {
menuCollapse.value = !menuCollapse.value
proxy.eventBus.emit('cnTreeCollapse', menuCollapse)
}
const filterNode = (value: string, data: any, node: any) => {
if (!value) return true
// return data.name.includes(value)
if (data.name) {
return chooseNode(value, data, node)
}
}
const chooseNode = (value: string, data: any, node: any) => {
if (data.name.indexOf(value) !== -1) {
return true
}
const level = node.level
// 如果传入的节点本身就是一级节点就不用校验了
if (level === 1) {
return false
}
// 先取当前节点的父节点
let parentData = node.parent
// 遍历当前节点的父节点
let index = 0
while (index < level - 1) {
// 如果匹配到直接返回此处name值是中文字符enName是英文字符。判断匹配中英文过滤
if (parentData.data.name.indexOf(value) !== -1) {
return true
}
// 否则的话再往上一层做匹配
parentData = parentData.parent
index++
}
// 没匹配到返回false
return false
}
// 新增方案
const onAdd = () => {
emit('onAdd')
}
// 绑定数据
const bind = (node: any, data: any) => {
emit('bind', data)
}
/** 树形结构数据 */
const defaultProps = {
children: 'children',
label: 'name',
value: 'id'
}
const props = withDefaults(
defineProps<{
showCheckbox?: boolean
defaultCheckedKeys?: any
}>(),
{
showCheckbox: false,
defaultCheckedKeys: []
}
)
const emit = defineEmits(['init', 'checkChange', 'nodeChange', 'editNode', 'getChart', 'onAdd', 'bind'])
const config = useConfig()
const tree = ref()
const treRef = ref()
const id: any = ref(null)
const treeData = ref({})
//获取方案树形数据
const getTreeList = () => {
getSchemeTree().then(res => {
let arr: any[] = []
res.data.forEach((item: any) => {
item.icon = 'el-icon-Menu'
item.color = config.getColorVal('elementUiPrimary')
item?.children.forEach((item2: any) => {
item2.icon = 'el-icon-Document'
item2.color = config.getColorVal('elementUiPrimary')
arr.push(item2)
})
})
tree.value = res.data
nextTick(() => {
if (arr.length) {
treRef.value.setCurrentKey(id.value || arr[0].id)
let list = id.value ? arr.find((item: any) => item.id == id.value) : arr[0]
// 注册父组件事件
emit('init', {
level: 2,
...list
})
} else {
emit('init')
}
})
})
}
getTreeList()
const dialogRef = ref()
const handleOpen = (val: any, id: any) => {
dialogRef.value.open(val, id)
}
//方案id
const planId: any = ref('')
//测试项id
const monitorId: any = ref('')
const planData: any = ref({})
const getPlanData = (row: any) => {
planData.value = {}
planData.value = JSON.parse(JSON.stringify(row))
}
/** 添加树节点 */
// 0 新增方案 1 修改方案 2 新增测试项 3 修改测试项 4 设备信息
const add = (node: any, data: any) => {
planId.value = data.id
//添加测试项
if (data?.children) {
dialogRef.value.detailsType('tree')
handleOpen(2, planId.value)
}
}
/** 编辑树节点 */
const edit = async (node: Node, data: any) => {
planId.value = data.id
await getTestRecordInfo(planId.value)
.then(res => {
//修改方案
if (data?.children) {
dialogRef.value.detailsType('')
dialogRef.value.details(res.data)
handleOpen(1, planId.value)
}
//修改测试项
else {
monitorId.value = data.id
dialogRef.value.detailsType('tree')
dialogRef.value.details(res.data.records[0])
handleOpen(3, planId.value)
}
})
.catch(e => { })
}
/** 删除树节点 */
const del = async (node: Node, data: any) => {
let titleList = ''
planId.value = data.id
await getDeviceList({
id: data.id,
isTrueFlag: 1
}).then(res => {
if (res.data.length > 0) {
titleList = '已绑定数据_'
}
})
//删除方案/测试项
ElMessageBox.confirm(titleList + '是否确认删除?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
delRecord({ id: data.id }).then((res: any) => {
if (res.code == 'A0000') {
ElMessage.success('删除成功')
id.value = null
getTreeList()
}
})
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消'
})
})
}
//取消删除
const cancelDel = () => { }
const clickNode = (e: anyObj) => {
e?.children ? (planId.value = e.id) : (planId.value = e.pid)
id.value = e.id
emit('nodeChange', e)
}
const setCheckedNode = (e: anyObj) => {
// console.log('🚀 ~ setCheckedNode ~ e:', e)
id.value = e
treRef.value.setCurrentKey(e)
}
watch(
() => planData.value,
(val, oldVal) => {
if (val && dialogRef.value) {
const obj = JSON.parse(JSON.stringify(val))
obj.records = [
val.records.find(item => {
return item.id == monitorId.value
})
]
dialogRef.value.details(obj)
}
},
{
immediate: true,
deep: true
}
)
defineExpose({ treeRef, getPlanData, getTreeList, setCheckedNode })
</script>
<style lang="scss" scoped>
.cn-tree {
flex-shrink: 0;
display: flex;
flex-direction: column;
box-sizing: border-box;
padding: 10px;
height: 100%;
width: 100%;
:deep(.el-tree) {
border: 1px solid var(--el-border-color);
}
:deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {
background-color: var(--el-color-primary-light-7);
}
.menu-collapse {
color: var(--el-color-primary);
}
}
.ml10 {
margin-bottom: 0 !important;
}
.add_plan {
width: 100%;
height: 40px;
display: flex;
justify-content: flex-end;
align-items: center;
}
.custom-tree-node {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.left,
.right {
display: flex;
align-items: center;
}
.left {
span {
margin-left: 2px;
}
}
.right {
a {
margin-left: 2px;
}
}
}
</style>