index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. <template>
  2. <div class="app-container page-nesting" style="position: relative">
  3. <!-- 树形组件start -->
  4. <div class="grid-content treeDom">
  5. <div style="text-align: center" class="mb-20">
  6. <el-button
  7. v-if="treeLevel == 3 || groupingId == 0 || treeLevel == 1"
  8. disabled
  9. >
  10. 添加分组
  11. </el-button>
  12. <el-button
  13. v-else
  14. type="primary"
  15. @click="addGroup()"
  16. :disabled="store.state.authorities.indexOf('新增') == -1"
  17. >
  18. 添加分组
  19. </el-button>
  20. <el-button
  21. v-if="treeLevel == 3 || groupingId == 0 || treeLevel == 1"
  22. disabled
  23. >
  24. 添加站点
  25. </el-button>
  26. <el-button
  27. v-else
  28. type="primary"
  29. @click="addSite()"
  30. :disabled="store.state.authorities.indexOf('新增') == -1"
  31. >
  32. 添加站点
  33. </el-button>
  34. </div>
  35. <el-input
  36. placeholder="输入关键字进行过滤"
  37. v-model="filterText"
  38. class="mb-20 searchInput"
  39. >
  40. <template>
  41. <i class="el-icon-search el-input__icon"></i>
  42. </template>
  43. </el-input>
  44. <!-- <el-scrollbar> -->
  45. <!-- <el-tree
  46. :data="data2"
  47. show-checkbox
  48. node-key="id"
  49. :default-expanded-keys="[1]"
  50. :default-checked-keys="[368]"
  51. :props="defaultProps2"
  52. /> -->
  53. <el-tree
  54. class="filter-tree siteTree"
  55. ref="tree"
  56. :data="data"
  57. node-key="id"
  58. :props="defaultProps"
  59. :filter-node-method="filterNode"
  60. @node-click="handleNodeClick"
  61. :expand-on-click-node="false"
  62. :highlight-current="showTree"
  63. default-expand-all
  64. :current-node-key="defaultExpand"
  65. >
  66. <template #default="{ node, data }">
  67. <span
  68. class="custom-tree-node"
  69. style="width: 100%"
  70. @mouseenter="mouseenter(data)"
  71. @mouseleave="mouseleave(data)"
  72. >
  73. <span>{{ node.label }}</span>
  74. <!-- <el-tooltip
  75. class="item"
  76. effect="dark"
  77. :content="node.label"
  78. placement="top-start"
  79. >
  80. <span>{{ node.label }}</span>
  81. </el-tooltip> -->
  82. <span>
  83. <a
  84. class="deleteLink"
  85. v-show="data.show"
  86. @click="remove(node, data)"
  87. >
  88. <!-- <i size="mini" class="el-icon-delete"></i> -->
  89. </a>
  90. </span>
  91. </span>
  92. </template>
  93. </el-tree>
  94. <!-- </el-scrollbar> -->
  95. </div>
  96. <!-- 树形组件end -->
  97. <!-- 站点主题start -->
  98. <div
  99. class="grid-content nestingDom"
  100. style="width: calc(100% - 300px)"
  101. v-if="flag2 && treeLevel != 1"
  102. >
  103. <el-tabs
  104. v-if="treeLevel == 3 || groupingId == 0"
  105. v-model="activeName"
  106. type="card"
  107. >
  108. <el-tab-pane label="基本信息" name="first">
  109. <basic-info
  110. class="basicInfo"
  111. :siteId="siteId"
  112. :groupingId="groupingId"
  113. :siteName="siteName"
  114. @func="getMsgFormSon3"
  115. :activeName="activeName"
  116. ></basic-info>
  117. </el-tab-pane>
  118. <el-tab-pane label="监控设备" name="second">
  119. <watch-dog
  120. v-on:success="success(res)"
  121. :activeName="activeName"
  122. @func="getMsgFormSon"
  123. :siteId="siteId"
  124. ></watch-dog>
  125. </el-tab-pane>
  126. <el-tab-pane label="变量列表" name="third">
  127. <variable-list
  128. :activeName="activeName"
  129. :siteId="siteId"
  130. ></variable-list>
  131. </el-tab-pane>
  132. <el-tab-pane label="摄像头" name="five">
  133. <camera :siteId="siteId" :activeName="activeName"></camera>
  134. </el-tab-pane>
  135. <el-tab-pane label="电能质量评分配置" name="six">
  136. <power-Score :siteId="siteId" :activeName="activeName"></power-Score>
  137. </el-tab-pane>
  138. </el-tabs>
  139. <!-- 分组信息start -->
  140. <group-info-com
  141. :groupingId="groupingId"
  142. :label="label"
  143. @func="getMsgFormSon2"
  144. v-else
  145. ></group-info-com>
  146. <!-- 分组信息end -->
  147. <!-- 新建分组start -->
  148. <add-group-com
  149. :dialogTitle="dialogTitle"
  150. :itemInfo="tableItem"
  151. @closeDialog="closeDialog('默认关闭')"
  152. :flag="showDialog"
  153. ></add-group-com>
  154. <!-- 新建分组end -->
  155. <!-- 新建站点start -->
  156. <add-site-com
  157. :dialogTitle="dialogTitle"
  158. :itemInfo="tableItem"
  159. :groupingId="groupingId"
  160. @closeDialog="closeDialog"
  161. :flag="showDialog2"
  162. @changeFather="getFromSon"
  163. ></add-site-com>
  164. <!-- 新建站点end -->
  165. </div>
  166. <!-- 站点主题end -->
  167. </div>
  168. </template>
  169. <script setup>
  170. import { ref, watch, onMounted, nextTick } from 'vue'
  171. import basicInfo from './basicInfo'
  172. import WatchDog from './watchDog'
  173. import variableList from './variableList'
  174. import camera from './camera'
  175. // import PowerScore from './powerScore'
  176. import groupInfoCom from './groupInfoCom'
  177. import addGroupCom from './addGroupCom'
  178. import addSiteCom from './addSiteCom'
  179. import * as api from '@/api/siteManage/index'
  180. import { ElMessage } from 'element-plus'
  181. import { useStore } from 'vuex'
  182. import { useRoute } from 'vue-router'
  183. const store = useStore()
  184. const route = useRoute()
  185. const flag2 = ref(false)
  186. const tree = ref(null)
  187. const showTree = ref(true)
  188. const defaultExpand = ref(0)
  189. const showDialog = ref(false)
  190. const showDialog2 = ref(false)
  191. const dialogTitle = ref('')
  192. const treeLevel = ref(3)
  193. const groupingId = ref(1)
  194. const siteId = ref(0)
  195. const labelCom = ref('')
  196. const siteName = ref('')
  197. const label = ref('')
  198. const activeName = ref('first')
  199. const filterText = ref('')
  200. const selectNode = ref(0)
  201. const data = ref([
  202. {
  203. label: '所有站点',
  204. children: [],
  205. },
  206. ])
  207. const defaultProps = ref({
  208. children: 'children',
  209. label: 'label',
  210. })
  211. const getMsgFormSon = () => {
  212. activeName.value = 'third'
  213. }
  214. const getMsgFormSon2 = () => {
  215. siteTreeList()
  216. setTimeout(() => {
  217. treeLevel.value = 1
  218. }, 1000)
  219. }
  220. //站点基本信息保存后触发
  221. const getMsgFormSon3 = (data) => {
  222. siteTreeList()
  223. setTimeout(() => {
  224. tree.value.setCurrentKey(selectNode.value)
  225. }, 1000)
  226. if (data == 0) {
  227. setTimeout(() => {
  228. treeLevel.value = 1
  229. }, 1000)
  230. }
  231. }
  232. function mouseenter(data) {
  233. data.show = true
  234. }
  235. function mouseleave(data) {
  236. data.show = false
  237. }
  238. const handleNodeClick = (data, obj, node) => {
  239. activeName.value = 'first'
  240. data, node
  241. flag2.value = true
  242. treeLevel.value = obj.level
  243. groupingId.value = obj.data.grouping_id
  244. label.value = obj.data.label
  245. // console.log('obj.data')
  246. // console.log(obj.data.id)
  247. selectNode.value = obj.data.id
  248. labelCom.value = obj.data.label
  249. store.state.siteManageLabelCom = obj.data.label
  250. store.state.basicInfoSiteName = ''
  251. if (treeLevel.value == 3) {
  252. siteId.value = obj.data.id
  253. }
  254. if (treeLevel.value == 2 && groupingId.value == 0) {
  255. // console.log(obj.data)
  256. siteId.value = obj.data.id
  257. }
  258. }
  259. function filterNode(value, data) {
  260. if (!value) return true
  261. return data.label.indexOf(value) !== -1
  262. }
  263. // 异步任务 用于给tree传值
  264. const writeValue = (val) => {
  265. return tree.value.filter(val)
  266. }
  267. // 定义 watch 监听
  268. watch(
  269. filterText,
  270. (newCount, old, clear) => {
  271. // 执行异步任务,并得到关闭异步任务的 id
  272. let id = writeValue(newCount, old)
  273. // 如果 watch 监听被重复执行了,则会先清除上次未完成的异步任务
  274. clear(() => clearTimeout(id))
  275. },
  276. // watch 刚被创建的时候不执行
  277. { lazy: true }
  278. )
  279. watch(
  280. activeName,
  281. (newCount, old, clear) => {
  282. newCount, old, clear
  283. // 清除定时器
  284. clear(() => clearTimeout(store.state.siteCameraTimer))
  285. },
  286. // watch 刚被创建的时候不执行
  287. { lazy: true }
  288. )
  289. // 新建分或站点的关闭操作
  290. const closeDialog = (res) => {
  291. if (store.state.basicInfoConst == 1 && res == '默认关闭') {
  292. // alert('1 并 默认关闭')
  293. showDialog.value = false
  294. showDialog2.value = false //弹框关闭
  295. siteTreeList()
  296. flag2.value = false //基本信息不显示
  297. treeLevel.value = 3 //新建站点 新建分组 按钮不可点击
  298. } else if (store.state.basicInfoConst == 1) {
  299. // alert('1')
  300. showDialog.value = false
  301. showDialog2.value = false
  302. }
  303. }
  304. //站点保存后关闭
  305. const getFromSon = (param, param2, param3) => {
  306. // alert('站点保存后关闭')
  307. siteId.value = param2
  308. siteName.value = param
  309. groupingId.value = param3
  310. flag2.value = true //基本信息显示
  311. treeLevel.value = 3 //新建站点 新建分组 按钮不可点击
  312. }
  313. //新建分组
  314. const tableItem = ref([])
  315. const addGroup = () => {
  316. tableItem.value = {
  317. groupingName: '',
  318. }
  319. dialogTitle.value = '新建分组'
  320. showDialog.value = true
  321. }
  322. //新建站点
  323. const addSite = () => {
  324. tableItem.value = {
  325. id: '',
  326. stationName: '',
  327. xh: '',
  328. userName: '',
  329. list: [],
  330. done: '',
  331. guaZai: '',
  332. checked: true,
  333. }
  334. dialogTitle.value = '新建站点'
  335. showDialog2.value = true
  336. }
  337. const remove = (node, data) => {
  338. const parent = node.parent
  339. const children = parent.data.children || parent.data
  340. const index = children.findIndex((d) => d.id === data.id)
  341. children.splice(index, 1)
  342. this.dataSource = [...this.dataSource]
  343. }
  344. //左侧树结构列表
  345. function siteTreeList() {
  346. api.siteTreeList({}).then((requset) => {
  347. if (requset.status === 'SUCCESS') {
  348. var jsona = JSON.stringify(requset.data)
  349. var jsonb = jsona.replace(/"grouping_name"/g, '"label"')
  350. jsonb = jsonb.replace(/"site_list"/g, '"children"')
  351. jsonb = jsonb.replace(/"site_name"/g, '"label"')
  352. jsonb = jsonb.replace(/"site_id"/g, '"id"')
  353. var jsonc = JSON.parse(jsonb)
  354. data.value[0].children = jsonc
  355. if (route.query.activeName && route.query.siteId) {
  356. setTimeout(() => {
  357. tree.value.setCurrentKey(route.query.siteId)
  358. }, 1000)
  359. flag2.value = true
  360. treeLevel.value = 3
  361. activeName.value = route.query.activeName
  362. siteId.value = route.query.siteId
  363. var bb = []
  364. jsonc.forEach(function (item) {
  365. if (item.id == siteId.value) {
  366. bb.push(item)
  367. }
  368. })
  369. store.state.siteManageLabelCom = bb[0].label
  370. }
  371. } else {
  372. ElMessage.error(requset.msg)
  373. }
  374. })
  375. }
  376. onMounted(() => {
  377. siteTreeList()
  378. })
  379. nextTick(() => {})
  380. </script>
  381. <style scoped lang="scss">
  382. .custom-tree-node {
  383. overflow: hidden;
  384. white-space: nowrap;
  385. text-overflow: ellipsis;
  386. display: block;
  387. }
  388. .app-container.page-nesting {
  389. padding: 0;
  390. background: rgba(0, 0, 0, 0);
  391. }
  392. .grid-content {
  393. background: #fff;
  394. height: calc(100vh - 130px);
  395. overflow-y: auto;
  396. }
  397. .el-input__inner {
  398. border-radius: 20px !important;
  399. }
  400. .treeDom {
  401. width: 290px;
  402. position: absolute;
  403. left: 0;
  404. // margin-left: 20px;
  405. padding: 20px;
  406. min-height: calc(100vh - 130px);
  407. .el-icon-search {
  408. color: #409eff;
  409. }
  410. .el-button {
  411. width: 100px;
  412. }
  413. }
  414. .nestingDom {
  415. margin-left: 300px;
  416. }
  417. </style>
  418. <style lang="scss">
  419. // tab重置样式
  420. .el-tabs--card > .el-tabs__header .el-tabs__item {
  421. line-height: 50px;
  422. height: 50px;
  423. font-size: 16px;
  424. }
  425. .el-tabs--card > .el-tabs__header .el-tabs__item.is-active {
  426. border-bottom: 2px solid #409eff;
  427. color: #409eff;
  428. }
  429. .el-tabs--card .el-tabs__header:hover,
  430. .el-tabs__item:hover {
  431. color: #409eff !important;
  432. }
  433. .el-tabs__header {
  434. margin-bottom: 0;
  435. }
  436. .el-tabs--card > .el-tabs__header .el-tabs__item,
  437. .el-tabs--card > .el-tabs__header .el-tabs__nav {
  438. border: none;
  439. }
  440. </style>