完成 树组件搜索功能,并且对样式做了优化

完成 树组件搜索功能,并且对样式做了优化
This commit is contained in:
TimSpan 2024-08-02 09:32:58 +08:00
parent 98b7b2d5d2
commit 11e52b490a
2 changed files with 230 additions and 102 deletions

View File

@ -7,12 +7,11 @@
</template>
<script setup lang="ts">
import {useAutoResize} from "./useAutoResize";
import {ref} from "vue";
import { useAutoResize } from './useAutoResize'
import { ref } from 'vue'
const currentDom = ref<HTMLElement>(null)
const state = useAutoResize(currentDom)
</script>
<style lang="less" scoped>
@ -24,4 +23,4 @@ const state = useAutoResize(currentDom)
transform-origin: left top;
z-index: 999;
}
</style>
</style>

View File

@ -22,17 +22,29 @@
</div>
<div class="searchBox" v-show="show3">
<el-form-item label="">
<el-input v-model="value1" placeholder="快速选择"></el-input>
<el-input v-model="searchValue" placeholder="请输入搜索关键词">
<template #append>
<el-button @click="onSearch" :icon="Search" />
</template>
</el-input>
</el-form-item>
<!-- <el-input v-model="0"></el-input> -->
</div>
<!-- <button @click="refreshTreeData">刷新</button> -->
<div v-loading="loading" style="padding: 0px 20px; height: 75%; overflow: auto">
<!-- <div v-loading="loading"> -->
<!-- :load-data="onLoadData" -->
<!-- height="500" -->
<!-- 重要的事情说三遍 key 值必须唯一 -->
<!-- 重要的事情说三遍 key 值必须唯一 -->
<!-- 重要的事情说三遍 key 值必须唯一 -->
<!-- <button @click="stop">关闭</button> -->
<div style="padding: 0px 20px; height: 75%; overflow: auto" v-show="show3">
<a-tree
v-loading="loading"
:fieldNames="{ key: 'code', title: 'title', children: 'children' }"
v-if="treedataall.length > 0"
ref="treeRef"
:show-icon="true"
:default-expand-all="true"
:default-expand-all="false"
v-model:expandedKeys="expandedKeys"
v-model:selectedKeys="selectedKeys"
v-model:checkedKeys="checkedKeys"
@ -115,51 +127,60 @@
</div>
</div>
<ul class="dataList" v-show="isActive1 == '1'">
<li v-if="jinbao.length > 0" v-for="(item, index) in jinbao" :key="index" @click="toinfo(item, index)">
<p>
<el-icon> <LocationFilled /> </el-icon>{{ item.address }}
</p>
<p>
<el-icon> <Clock /> </el-icon>{{ item.timestamp }}
</p>
<p>
<el-icon> <PhoneFilled /> </el-icon>{{ item.user1Phone }}
</p>
<p>设备号{{ item.deviceId }}</p>
<p>平台来源{{ item.alarmSource }}</p>
</li>
<div v-if="jinbao.length > 0">
<li v-for="(item, index) in jinbao" :key="index" @click="toinfo(item, index)">
<p>
<el-icon> <LocationFilled /> </el-icon>{{ item.address }}
</p>
<p>
<el-icon> <Clock /> </el-icon>{{ item.timestamp }}
</p>
<p>
<el-icon> <PhoneFilled /> </el-icon>{{ item.user1Phone }}
</p>
<p>设备号{{ item.deviceId }}</p>
<p>平台来源{{ item.alarmSource }}</p>
</li>
</div>
<el-empty v-else description="暂无数据"></el-empty>
</ul>
<ul class="dataList" v-show="isActive1 == '2'">
<li v-if="jinqing.length > 0" v-for="(item, index) in jinqing" :key="index" @click="toinfo(item, index)">
<p>
<el-icon> <LocationFilled /> </el-icon>{{ item.address }}
</p>
<p>
<el-icon> <Clock /> </el-icon>{{ item.timestamp }}
</p>
<p>
<el-icon> <PhoneFilled /> </el-icon>{{ item.user1Phone }}
</p>
<p>设备号{{ item.alarmSource }}</p>
<p>平台来源{{ item.station }}</p>
</li>
<div v-if="jinqing.length > 0">
<li v-for="(item, index) in jinqing" :key="index" @click="toinfo(item, index)">
<p>
<el-icon> <LocationFilled /> </el-icon>{{ item.address }}
</p>
<p>
<el-icon> <Clock /> </el-icon>{{ item.timestamp }}
</p>
<p>
<el-icon> <PhoneFilled /> </el-icon>{{ item.user1Phone }}
</p>
<p>设备号{{ item.alarmSource }}</p>
<p>平台来源{{ item.station }}</p>
</li>
</div>
<el-empty v-else description="暂无数据"></el-empty>
</ul>
<ul class="dataList" v-show="isActive1 == '3'">
<li v-if="AIyujing.length > 0" v-for="(item, index) in AIyujing" :key="index" @click="toinfo(item, index)">
<p>
<el-icon> <LocationFilled /> </el-icon>{{ item.address }}
</p>
<p>
<el-icon> <Clock /> </el-icon>{{ item.timestamp }}
</p>
<p>
<el-icon> <PhoneFilled /> </el-icon>{{ item.user1Phone }}
</p>
<p>设备号{{ item.deviceId }}</p>
<p>平台来源{{ item.alarmSource }}</p>
</li>
<div v-if="AIyujing.length > 0">
<li v-for="(item, index) in AIyujing" :key="index" @click="toinfo(item, index)">
<p>
<el-icon> <LocationFilled /> </el-icon>{{ item.address }}
</p>
<p>
<el-icon> <Clock /> </el-icon>{{ item.timestamp }}
</p>
<p>
<el-icon> <PhoneFilled /> </el-icon>{{ item.user1Phone }}
</p>
<p>设备号{{ item.deviceId }}</p>
<p>平台来源{{ item.alarmSource }}</p>
</li>
</div>
<el-empty v-else description="暂无数据"></el-empty>
</ul>
</div>
@ -352,16 +373,15 @@
</div>
</template>
<script lang="ts" setup>
import { cloneDeep } from 'lodash'
import type { TreeProps } from 'ant-design-vue'
import { Search } from '@element-plus/icons-vue'
import { createMqttData } from '@/utils/createMqttData'
import { sendMqtt } from '@/utils/sendMqtt'
import { DownOutlined, SmileOutlined, FrownOutlined, FrownFilled } from '@ant-design/icons-vue'
import { useWebSocket } from '@vueuse/core'
import { wsUrl } from '@/utils/webSocket'
import * as _ from 'lodash'
import api from '@/axios'
import { useUserStore } from '@/stores/modules/userStore'
import { MoreFilled } from '@element-plus/icons-vue'
import { CLIENT_TYPE } from '@/configs'
import { ElMessage } from 'element-plus'
import no from './imag/no.png'
import yes from './imag/yes.png'
@ -372,7 +392,6 @@ import image4 from './imag/dsds.png'
import closeimag from './imag/infoClose.png'
import { Ref, ref, watch, onMounted, onBeforeMount, reactive, getCurrentInstance, nextTick } from 'vue'
// import AMapLoader from "@amap/amap-jsapi-loader";
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'
const showIframe = ref(false)
const videoUrl = ref('')
@ -381,34 +400,20 @@ const { proxy } = getCurrentInstance() as any
const day = proxy.day
const size = ref('')
const lodash = proxy.lodash
const value1 = ref('a1')
const zoom = ref('12')
const center = ref([121.59996, 31.197646])
let map: any
const expandedKeys = ref([])
const selectedKeys = ref([])
const checkedKeys = ref([])
const expandedKeysb = ref([])
const selectedKeysb = ref([])
const checkedKeysb = ref([])
const expandedKeysc = ref([])
const selectedKeysc = ref([])
const checkedKeysc = ref([])
const dialogTableVisible = ref(false)
const deviceTreeData = ref([])
const deviceTreeDatab = ref([])
const deviceTreeDatac = ref([])
const treeData = ref([])
const treeDatab = ref([])
const treeDatac = ref([])
const boroughList = ref([])
const detachmentList = ref([])
const stationDataA = ref([])
const stationDataB = ref([])
const dialogTableVisible = ref(false)
const visible = ref(false)
const visibleb = ref(false)
import { useRouter } from 'vue-router'
const activeName = ref('first')
const router = useRouter()
const env = ref(import.meta.env.VITE_APP_BASE_API)
@ -503,17 +508,24 @@ const lock = (data: any) => {
}
})
}
//
const printLeafs = (tree: any, jirearr: any) => {
if (!tree.children) {
if (tree.children === null) {
if (tree.hasOwnProperty('stationId')) {
tree.code = tree?.stationId
// tree.code = '111'
}
tree.children = []
jirearr.forEach((x: any) => {
if (tree.stationId == x.stationId) {
//
tree.children.push(x)
}
})
} else {
tree.children.forEach((child: any) => printLeafs(child, jirearr))
tree.children.forEach((child: any) => {
printLeafs(child, jirearr)
})
}
}
const isActive = ref('6')
@ -540,9 +552,85 @@ const qhzty = (data: any) => {
break
}
}
const fieldNames: TreeProps['fieldNames'] = {
// children: 'children',
// title: 'title',
key: 'code',
}
const loading = ref(false)
//
const treedataall = ref([])
const searchValue = ref('') //
const treeRef = ref() // ref a-tree
// checkKeyExists___ key
const checkKeyExists = (nodes: any, key: string): boolean => {
return nodes.some((node: any) => {
if (node.code === key) return true
if (node.children) return checkKeyExists(node.children, key)
return false
})
}
//
const scrollToKey = (key: string) => {
console.log('scrollToKey', key)
// console.log('treeRef________', treeRef.value.scrollTo)
// key
// const exists = treedataall.value.some((node) => node.key === key || node.children?.some((child: any) => child.key === key))
const exists = checkKeyExists(treedataall.value, key)
if (!exists) {
console.error(`Key ${key} not found in the tree.`)
return
}
// scrollTo
nextTick(() => {
treeRef.value.scrollTo({
key,
align: 'top', // top, bottom, auto
offset: 0, //
})
})
}
//
const onSearch = () => {
let keysToExpand: any[]
keysToExpand = []
let keysToSelect: any[]
keysToSelect = []
const findKeys = (nodes: any, parentKeyPath: any[]) => {
nodes.forEach((node: any) => {
const nodeId = node.code
const currentPath = [...parentKeyPath, nodeId]
if (node.title.includes(searchValue.value)) {
console.log('node______', node)
keysToSelect.push(nodeId)
currentPath.forEach((key) => keysToExpand.push(key))
}
if (node.children && node.children.length > 0) {
findKeys(node.children, currentPath) //
}
})
}
findKeys(treedataall.value, [])
console.log('Expanded Keys:', Array.from(keysToExpand))
console.log('Selected Keys:', keysToSelect)
expandedKeys.value = [...new Set(keysToExpand)]
selectedKeys.value = keysToSelect
if (selectedKeys.value.length > 0) {
console.log('selectedKeys.value', selectedKeys.value)
scrollToKey(selectedKeys.value[0])
}
}
const refreshTreeData = () => {
treedataall.value = [...treedataall.value]
}
const gettree4 = (data: any) => {
loading.value = true
api
@ -558,12 +646,21 @@ const gettree4 = (data: any) => {
hylxdm: data,
})
.then((res1) => {
let data = [res.data]
data.forEach((x) => {
printLeafs(x, res1.data)
res1.data.forEach((ele: any) => {
// getlist code
// ele.code = ele.stationId
ele.code = ele.pointId
})
// console.log('4', res.data)
treedataall.value = data
let data = [res.data]
// console.log('data_____________', data)
data.forEach((tree) => {
console.log(tree)
printLeafs(tree, res1.data)
})
treedataall.value = [...data]
loading.value = false
})
} else {
@ -571,6 +668,22 @@ const gettree4 = (data: any) => {
}
})
}
const onLoadData: TreeProps['loadData'] = (treeNode) => {
return new Promise<void>((resolve) => {
if (treeNode.dataRef.children) {
resolve()
return
}
setTimeout(() => {
treeNode.dataRef.children = [
{ title: 'Child Node', key: `${treeNode.eventKey}-0` },
{ title: 'Child Node', key: `${treeNode.eventKey}-1` },
]
treedataall.value = [...treedataall.value]
resolve()
}, 1000)
})
}
//
const close = (info: any) => {
api
@ -684,6 +797,7 @@ const clickKz = (dat2a: any) => {
}
onMounted(() => {
// await nextTick()
gettotal()
initMap()
gettree4('')
@ -708,7 +822,9 @@ const treedata = () => {
.then((res) => {
var gridSize = 60
// console.log('', res)
var points: any[]
// var points: any[]
var points = []
res.data.map((x: any) => {
const marker = new AMap.Marker({
position: new AMap.LngLat(x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude),
@ -889,7 +1005,7 @@ const gettotal = () => {
//
let deviceInfoWindow = ref(null)
const selectA = (selectedKeys: any, e: any) => {
// console.log('selectedKeys',selectedKeys,e)
console.log('selectedKeys', selectedKeys, e)
if (selectedKeys[0].length >= 13) {
let targetLangLat = [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude]
deviceInfoWindow = new AMap.InfoWindow({
@ -902,18 +1018,18 @@ const selectA = (selectedKeys: any, e: any) => {
state.map.setZoomAndCenter(205, targetLangLat)
}
}
const selectB = (selectedKeys: any, e: any) => {
if (e.selectedNodes[0]) {
let targetLangLat = [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude]
state.map.panTo(targetLangLat)
}
}
const selectC = (selectedKeys: any, e: any) => {
if (e.selectedNodes[0]) {
let targetLangLat = [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude]
state.map.panTo(targetLangLat)
}
}
// const selectB = (selectedKeys: any, e: any) => {
// if (e.selectedNodes[0]) {
// let targetLangLat = [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude]
// state.map.panTo(targetLangLat)
// }
// }
// const selectC = (selectedKeys: any, e: any) => {
// if (e.selectedNodes[0]) {
// let targetLangLat = [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude]
// state.map.panTo(targetLangLat)
// }
// }
const createSubstanceInfowindow = (obj: any, type: any) => {
//
var mdinfoTop = document.createElement('div')
@ -1330,6 +1446,9 @@ const defaultProps = {
</script>
<style scoped lang="scss">
// .input-with-select .el-input-group__prepend {
// background-color: var(--el-fill-color-blank);
// }
.slide-fade-enter-active {
transition: all 0.3s linear;
}
@ -1760,15 +1879,14 @@ const defaultProps = {
color: #fff;
}
:deep(.el-input__wrapper) {
background-color: transparent;
// box-shadow: 0 0 0 1px var(--el-input-border-color,var(--el-border-color)) inset;
box-shadow: 0 0 0 1px #ccc;
}
// :deep(.el-input__wrapper) {
// background-color: transparent;
// box-shadow: 0 0 0 1px #ccc;
// }
:deep(.el-input__inner) {
color: #fff;
}
// :deep(.el-input__inner) {
// color: #fff;
// }
:deep(.el-select .el-input .el-select__caret) {
color: #ccc;
@ -1816,6 +1934,12 @@ const defaultProps = {
background-color: transparent;
}
:deep(.ant-tree-iconEle) {
display: flex !important;
justify-content: center;
align-items: center;
}
:deep(
:where(.css-dev-only-do-not-override-1qb1s0s).ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected,
:where(.css-dev-only-do-not-override-1qb1s0s).ant-tree .ant-tree-checkbox + span.ant-tree-node-selected
@ -1823,6 +1947,11 @@ const defaultProps = {
background-color: transparent;
}
:deep(.ant-tree-node-content-wrapper) {
display: flex;
align-items: center;
}
::v-deep .ant-tree .ant-tree-list-holder-inner {
// background: #cccccc2b;
background: #fff;