<template>
<div class="equipmentList-wrap">
<p-input-search class="leftTree-header mb-2" allowClear placeholder="请输入关键字搜索" @search="onSearch" />
<div class="left_tree_wrapper" id="recipeTree" :style="{ height: TreeDomHeight }">
<p-spin v-if="treeData.length <= 0" class="loading-spin" size="large" />
<p-tree
v-else
show-icon
@select="onSelect"
:auto-expand-parent="autoExpandParent"
:tree-data="treeData"
:replaceFields="replaceFields"
:expanded-keys="expandedKeys"
:loadedKeys="loadedKeys"
@expand="onExpand"
@load="loadData"
>
<template slot="title" slot-scope="dataRef">
<span v-if="dataRef.hasRecipe && dataRef.type == 'equipment'" class="hasRecipeSuccess"></span>
<span v-if="!dataRef.hasRecipe && dataRef.type == 'equipment'" class="hasRecipeWarning"></span>
<span v-if="dataRef.title.indexOf(searchValue) !== -1" :id="dataRef.title">
{{ dataRef.title.substr(0, dataRef.title.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ dataRef.title.substr(dataRef.title.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ dataRef.title }}</span>
</template>
<p-icon type="database" slot="bank" theme="twoTone" />
</p-tree>
</div>
</div>
</template>
<script>
import { getAllTree } from '@/api/tree.js'
const getParentKey = (key, tree) => {
let parentKey
for (let i = 0; i < tree.length; i++) {
const node = tree[i]
if (node.children) {
if (node.children.some((item) => item.key === key)) {
parentKey = node.key
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children)
}
}
}
return parentKey
}
const traverse = (tree)=> {
for (let i = 0; i < tree.length; i++) {
const item = tree[i]
item.key = item.id
item.title = item.eqpId
item.scopedSlots = { title: 'title' }
item.slots = item.type == 'equipment' ? {} : { icon: 'bank' }
if (item.children) {
traverse(item.children);
}
}
}
const setStyleDisplay = (title, nodes) => {
let nums = 0
for (let data of nodes) {
let bl = false
if (data.title.indexOf(title) > -1) {
bl = true
nums += 1
}
if (!!data.children) {
if (data.children.length > 0) {
let count = setStyleDisplay(title, data.children)
nums += count
if (!bl && count == 0) {
bl = false
} else {
bl = true
}
}
}
if (bl) {
delete data['style']
} else {
data['style'] = 'display: none'
}
}
return nums
}
export default {
data() {
return {
dataList: [],
hasRecipe: null,
searchValue: '',
timer: null,
loadedKeys: [],
expandedKeys: [],
autoExpandParent: true,
treeData: [],
TreeDomHeight: '67vh',
replaceFields: {
title: 'title',
key: 'key',
children: 'children'
}
}
},
methods: {
getCompanyList() {
const param = {
company: '',
factory: '',
lineId: ''
}
this.loadedKeys = []
this.expandedKeys = []
getAllTree(param).then((res) => {
let resData = res.data
if (resData.success && resData.data) {
traverse(resData.data)
this.treeData = resData.data
this.generateList(this.treeData)
} else {
this.$message.error('请稍后再试!')
}
})
},
onLoadData(treeNode) {
return new Promise((resolve) => {
if (treeNode.dataRef.children) {
resolve()
return
}
console.log(treeNode.dataRef)
const param = {
company: treeNode.dataRef.company,
factory: treeNode.dataRef.factory,
lineId: treeNode.dataRef.lineId
}
setTimeout(async () => {
const res = await getAllTree(param)
let resData = res.data
if (resData && resData.code == 0) {
let data = resData.data
treeNode.dataRef.children = data.map((item) => {
item.key = item.treeId
item.title = item.eqpId
item.scopedSlots = { title: 'title' }
item.slots = item.type == 'equipment' ? {} : { icon: 'bank' }
item.isLeaf = item.type == 'equipment'
return item
})
}
this.treeData = [...this.treeData]
this.generateList(this.treeData)
resolve()
}, 500)
})
},
loadData(loadedKeys) {
this.loadedKeys = loadedKeys
},
onExpand(expandedKeys) {
this.expandedKeys = expandedKeys
this.autoExpandParent = false
},
onSearch(val) {
const value = val.trim(),
{ dataList } = this
let machArr = []
let expandedKeys = []
if(value && value.length<5) {
this.$message.info('输入关键字较少,会导致页面出现卡机状态,请至少输入5位以上的关键字')
return
}
if(value) {
expandedKeys = dataList
.map((item) => {
if (item.title.indexOf(value) > -1) {
machArr.push(item.title)
return getParentKey(item.key, this.treeData)
}
return ''
})
.filter((item, i, self) => item && self.indexOf(item) === i)
}
setStyleDisplay(value,this.treeData)
this.searchValue = value
this.$forceUpdate()
if(expandedKeys.length===0) return
Object.assign(this, {
expandedKeys,
autoExpandParent: true
})
this.$nextTick(()=>{
setTimeout(()=>{
if(machArr.length>0) {
document.getElementById(machArr[0]).scrollIntoView()
}
},300)
})
},
generateList(data) {
for (let i = 0; i < data.length; i++) {
const node = data[i]
const key = node.key
const title = node.title
this.dataList.push({ key, title })
if (node.children) {
this.generateList(node.children)
}
}
},
onSelect(keys, node) {
node.selected ? this.$emit('checkNode', node.node.dataRef) : this.$emit('checkNode', {})
},
computedTreeHeight() {
let recipeTreeDom = document.getElementById('recipeTree')
let screenHeight = document.body.clientHeight
let recipeTreeDomTop = recipeTreeDom&& recipeTreeDom.getBoundingClientRect().top + 30
this.TreeDomHeight = screenHeight - recipeTreeDomTop + 'px'
}
},
created() {
this.getCompanyList()
},
beforeDestroy() {
window.removeEventListener('resize', this.computedTreeHeight)
},
mounted() {
this.computedTreeHeight()
window.addEventListener('resize', this.computedTreeHeight)
}
}
</script>
<style scoped lang="less">
.statusButton {
cursor: pointer;
}
.hasRecipeSuccess {
position: relative;
border-radius: 100%;
display: inline-block;
width: 12px;
top: 1px;
height: 12px;
margin-right: 4px;
background-color: rgb(15, 187, 78);
}
.hasRecipeWarning {
position: relative;
border-radius: 100%;
display: inline-block;
width: 12px;
top: 1px;
height: 12px;
margin-right: 4px;
background-color: #ffb048;
}
.equipmentList-wrap {
height: 100%;
font-size: 14px;
font-weight: 400;
overflow: hidden;
.left_tree_wrapper {
position: relative;
// flex: 1 0 22%;
overflow: auto;
.loading-spin {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
/deep/ .poros-tree {
font-size: 14px;
color: #333;
font-weight: 400;
> li {
> .poros-tree-node-content-wrapper {
font-weight: bold;
}
}
li {
padding: 4px 0;
.poros-tree-node-content-wrapper {
padding-left: 0;
}
.poros-tree-node-content-wrapper.poros-tree-node-selected {
background-color: @primary-color;
color: #fff;
}
span.poros-tree-switcher {
width: 20px;
height: 24px;
line-height: 24px;
color: #848484;
}
}
}
}
.equipment-item {
color: #000;
font-size: 14px;
list-style: none;
cursor: pointer;
user-select: none;
padding: 4px 0px;
}
.equipment-item:hover {
color: #000;
background-color: #e8e8e8;
font-size: 14px;
list-style: none;
cursor: pointer;
user-select: none;
}
.equipment-item.active {
color: #fff;
background-color: blue;
font-size: 14px;
list-style: none;
cursor: pointer;
user-select: none;
}
</style>