index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. <template>
  2. <div class='equipment-facilities'>
  3. <!-- 左侧菜单 -->
  4. <SystemMenu class='left' @chooseSystem='changeSystem' />
  5. <div class='right' v-show='showRight'>
  6. <div class='top' :key='listKey'>
  7. <!-- <van-cell :title='`消防电系统原理示意图`' :border='false' is-link :value='`19条`' @click='handleClick' />
  8. <van-cell :title='`消防喷淋系统示意图`' :border='false' is-link value='无' @click='handleClick' />
  9. <van-cell :title='`消防窗喷系统示意图`' :border='false' is-link value='无' @click='handleClick' />
  10. <van-cell :title='`配电室低压柜及出线明细`' :border='false' is-link value='无' @click='handleClick' />
  11. <van-cell :title='`消防泵房引出管路分布图`' :border='false' is-link value='无' @click='handleClick' />
  12. <van-cell :title='`楼层分布+其他数据`' :border='false' is-link value='无' @click='handleClick' />-->
  13. <van-cell
  14. v-for='(item,index ) in listData[currentSmsxt]'
  15. :key='index'
  16. :title='item.text'
  17. :border='false'
  18. is-link
  19. :value='`${item.count||""}`'
  20. @click='handleClick(item)'
  21. />
  22. </div>
  23. <!-- 分割线 -->
  24. <div class='divider'></div>
  25. <!-- 设备卡片 -->
  26. <div class='card-container'>
  27. <m-card
  28. class='card'
  29. :type='item.type'
  30. :name='item.name'
  31. :unit='item.unit'
  32. :total='item.total'
  33. :number='item.number'
  34. v-for='item in cardList'
  35. :key='item.category_name'
  36. @click.native='goToEquipment(item)'
  37. />
  38. <!-- 更多主要设备 -->
  39. <m-card class='card' :type='4' name unit :total='0' @click.native='goToMoreEquipment' />
  40. </div>
  41. </div>
  42. <!-- 原理图 -->
  43. <ImagePreview :key='imgKey' class='update-img-preview' :visible.sync='showImgPreview' :imgList='imgList' />
  44. </div>
  45. </template>
  46. <script>
  47. import Vue from 'vue'
  48. import { Cell, Toast } from 'vant'
  49. Vue.use(Cell).use(Toast)
  50. import { mapGetters, mapMutations } from 'vuex'
  51. import { querySystemCount, querySystemCard, querySystemImage, querySystemTuJianImage, queryRoomCount } from '@/api/equipmentList'
  52. import { appGraphElementQuery } from '@/api/public'
  53. import MCard from '@/components/equipmentFacilities/Card'
  54. import SystemMenu from '@/components/systemMenu'
  55. import ImagePreview from '@/components/ImagePreview'
  56. export default {
  57. name: 'EquipmentFacilities',
  58. props: {},
  59. components: { SystemMenu, MCard, ImagePreview },
  60. computed: {
  61. ...mapGetters(['plazaId', 'smsxt', 'categoryId', 'floorsArr']),
  62. },
  63. data() {
  64. return {
  65. currentSmsxt: '1001', //系统值,默认供电系统
  66. systemText: '供电系统',
  67. module: '1002', // 广场管理说明书图片上传视图查询条件 1001 项目概况 1004其他事项 1003楼层分布 1002 设备设施
  68. neTypename: '位置布置图',
  69. listData: {
  70. //上部列表数据
  71. 1001: [
  72. //供电
  73. { text: '供电系统原理图', dataType: 'img', typecode: '2010', count: '无' },
  74. { text: '机房平面布置图', dataType: 'room' },
  75. { text: '配电室低压柜及出线明细', dataType: 'dyg' },
  76. { text: '楼层分布', dataType: 'floor', value: ' ' },
  77. { text: '电井控制商铺范围', dataType: 'electricWell' },
  78. ],
  79. 1002: [
  80. //暖通
  81. { text: '空调系统原理图', dataType: 'img', typecode: '2011', count: '无' },
  82. { text: '分水器支路分布图', dataType: 'fbt', categoryId: 'FZQZL' },
  83. { text: '机房平面布置图', dataType: 'room' },
  84. { text: '楼层分布', dataType: 'floor' },
  85. ],
  86. 1003: [
  87. //消防
  88. { text: '消防电系统原理示意图', dataType: 'img', typecode: '2014', count: '无' },
  89. { text: '消防喷淋系统示意图', dataType: 'img', typecode: '2015', count: '无' },
  90. { text: '消防窗喷系统示意图', dataType: 'img', typecode: '2016', count: '无' },
  91. { text: '消火栓系统示意图', dataType: 'img', typecode: '2017', count: '无' },
  92. { text: '消防泵房引出管路分布图', dataType: 'fbt', categoryId: 'XFBFYCFL' },
  93. { text: '机房平面布置图', dataType: 'room' },
  94. { text: '楼层分布+附加数据', dataType: 'floor' },
  95. ],
  96. 1004: [
  97. //弱电
  98. { text: '门禁管理系统原理图', dataType: 'img', typecode: '2019', count: '无' },
  99. { text: 'BA楼宇智能化系统原理图', dataType: 'img', typecode: '2020', count: '无' },
  100. { text: '机房平面布置图', dataType: 'room' },
  101. { text: '楼层分布+附加数据', dataType: 'floor' },
  102. ],
  103. 1005: [
  104. //给排水
  105. { text: '给水系统原理示意图', dataType: 'img', typecode: '2021', count: '无' },
  106. { text: '排水系统原理示意图', dataType: 'img', typecode: '2022', count: '无' },
  107. { text: '机房平面布置图', dataType: 'room' },
  108. { text: '楼层分布', dataType: 'floor' },
  109. ],
  110. 1006: [
  111. //电梯
  112. { text: '扶梯原理图', dataType: 'img', typecode: '2023', count: '无' },
  113. { text: '直梯原理图', dataType: 'img', typecode: '2024', count: '无' },
  114. { text: '楼层分布', dataType: 'floor' },
  115. ],
  116. 1007: [
  117. // 燃气
  118. { text: '燃气系统原理示意图', dataType: 'img', typecode: '2025', count: '无' },
  119. { text: '楼层分布', dataType: 'floor' },
  120. ],
  121. 1008: [
  122. // 土建
  123. // 2026 东外立面
  124. // 2029 北外立面
  125. // 2028 南外立面
  126. // 2027 西外立面
  127. // { text: '建筑立面图', dataType: 'img', typecode: '2026', count: '无' },
  128. { text: '建筑立面图', dataType: 'img', typecode: ['2026', '2027', '2028', '2029'], count: '无' },
  129. { text: '楼层分布', dataType: 'floor' },
  130. ],
  131. },
  132. listKey: `list_${new Date().getTime()}`,
  133. cardList: [],
  134. showRight: false, //是否显示右侧内容
  135. showImgPreview: false, //是否展示图片预览
  136. imgList: [], //图片数组
  137. imgKey: `img${new Date().getTime()}`,
  138. fbtArr: [], //分布图使用的楼层数据
  139. }
  140. },
  141. watch: {
  142. // 前五个系统更改,查询机房平面布置图数量
  143. smsxt: {
  144. handler(newV, oldV) {
  145. let smsxtArr = ['1001', '1002', '1003', '1004', '1005']
  146. if (smsxtArr.includes(newV)) {
  147. // 查询机房平面布置图数量
  148. this.getRoomCount()
  149. }
  150. // 暖通,消防,查询 分水器支路分布图,消防泵房引出管路分布图 对应的楼层图例数据
  151. if (['1002', '1003'].includes(newV)) {
  152. let dict = {
  153. 1002: 'FZQZL',
  154. 1003: 'XFBFYCFL',
  155. }
  156. this.getTuliData({ smsxt: newV, system_code: dict[newV] })
  157. }
  158. },
  159. immediate: true,
  160. },
  161. },
  162. async created() {
  163. // let initSys = {
  164. // text: '供电',
  165. // categoryId: 'GDXT',
  166. // smsxt: '1001',
  167. // }
  168. this.systemText = '供电系统'
  169. this.currentSmsxt = '1001'
  170. this.SETCATEGORYID('GDXT')
  171. this.SETSMSXT('1001')
  172. this.showRight = false
  173. // 查询图片数量,设备卡片
  174. await Promise.all([this.getPicCount(), this.getCard()])
  175. this.showRight = true
  176. // this.changeSystem(initSys)
  177. },
  178. beforeMount() {},
  179. mounted() {},
  180. methods: {
  181. ...mapMutations(['SETCATEGORYID', 'SETSMSXT']),
  182. /**
  183. * 左侧菜单切换事件
  184. * @param { String } text 系统名称
  185. * @param { String } category 系统拼音简称 NTXT ...
  186. * @param { String } currentSmsxt 系统id? 1001 - 1008
  187. */
  188. async changeSystem({ text, categoryId, smsxt }) {
  189. this.showRight = false
  190. this.currentSmsxt = smsxt
  191. this.systemText = text + '系统'
  192. console.log(this.systemText)
  193. /**
  194. * 查询图片数量,设备卡片
  195. */
  196. await Promise.all([this.getPicCount(), this.getCard()])
  197. this.showRight = true
  198. },
  199. /**
  200. * 查询图片数量
  201. */
  202. async getPicCount() {
  203. let getParams = {
  204. plazaId: this.plazaId,
  205. system: this.currentSmsxt,
  206. }
  207. let res
  208. Toast.loading({
  209. message: '加载中...',
  210. forbidClick: true,
  211. })
  212. try {
  213. res = await querySystemCount({ getParams })
  214. } catch (error) {}
  215. // TODO: 123123
  216. if (!res?.data) {
  217. return false
  218. }
  219. let data = res.data
  220. let currentSys = this.listData[this.currentSmsxt]
  221. // console.log(this.listData, currentSys)
  222. currentSys.map((item) => {
  223. if (item.dataType === 'img') {
  224. let detail = data.filter((v) => v.typecode == item.typecode)[0]
  225. // console.log(detail)
  226. item.count = detail?.cnt ? detail?.cnt + '张' : '无' // + '张' || '无'
  227. }
  228. })
  229. // console.log(this.currentSmsxt)
  230. // 土建装饰单独处理 将东西南北合并到一起
  231. if (this.currentSmsxt === '1008') {
  232. // console.log(data)
  233. let count = data.reduce((prev, current) => {
  234. return prev + current.cnt
  235. }, 0)
  236. // console.log(count)
  237. currentSys.map((item) => {
  238. if (item.dataType === 'img') {
  239. item.count = count ? count + '张' : '无' // + '张' || '无'
  240. }
  241. })
  242. }
  243. // console.log(currentSys)
  244. this.listKey = `list_${new Date().getTime()}`
  245. this.$set(this.listData, this.currentSmsxt, currentSys)
  246. Toast.clear()
  247. // console.log(this.listData)
  248. },
  249. /**
  250. * 查询机房平面布置图数量
  251. */
  252. async getRoomCount() {
  253. let getParams = {
  254. plazaId: this.plazaId,
  255. systemCode: this.smsxt,
  256. }
  257. // 查询机房平面布置图数量
  258. let res = await queryRoomCount({ getParams })
  259. // 取出listData中对应的系统数据
  260. let data = this.listData[this.smsxt]
  261. data.map((item, index, arr) => {
  262. if (item.dataType === 'room') {
  263. item.count = res?.count ? res?.count + '张' : '无'
  264. }
  265. })
  266. this.listKey = `list_${new Date().getTime()}`
  267. },
  268. /**
  269. * 分水器支路分布图,消防泵房引出管路分布图 对应的楼层图例数据
  270. */
  271. async getTuliData({ smsxt, system_code }) {
  272. let params = {
  273. BuildingID: '1',
  274. CategoryID: system_code,
  275. ProjectID: this.plazaId,
  276. Floors: this.floorsArr.map((item) => {
  277. return {
  278. FloorId: item.gname,
  279. FloorName: item.code,
  280. }
  281. }),
  282. }
  283. console.log(params)
  284. let res = await appGraphElementQuery(params)
  285. console.log(res)
  286. if (!res?.Data) {
  287. return false
  288. }
  289. let Data = res.Data || []
  290. // 过滤有Statistics的条数
  291. Data = Data.filter((v) => v.Statistics?.length)
  292. let fbtArr = []
  293. Data.map((item) => {
  294. fbtArr.push({
  295. code: item.FloorName,
  296. gname: item.FloorId,
  297. })
  298. })
  299. this.fbtArr = fbtArr
  300. let count = Data.length ? Data.length + '张' : '无'
  301. let systemData = this.listData[smsxt]
  302. console.log(systemData)
  303. systemData.map((item, index, arr) => {
  304. if (item.dataType === 'fbt') {
  305. arr[index].count = count
  306. }
  307. })
  308. this.$set(this.listData, smsxt, systemData)
  309. this.listKey = `list_${new Date().getTime()}`
  310. // .then(res => {
  311. // this.floorData = res.Data.map(floor => {
  312. // floor.Open = false;
  313. // return floor;
  314. // });
  315. // })
  316. },
  317. /**
  318. * 查询设备卡片
  319. */
  320. async getCard() {
  321. this.cardList = []
  322. let getParams = {
  323. plazaId: this.plazaId,
  324. smsxt: this.smsxt,
  325. }
  326. let res
  327. try {
  328. res = await querySystemCard({ getParams })
  329. } catch (error) {}
  330. // console.log('设备卡片')
  331. // console.log(res.data)
  332. if (!res && !res?.data?.length) {
  333. return false
  334. }
  335. let data = res.data
  336. // 取出assetTypeList
  337. let cardList = data[0]?.assetTypeList || []
  338. // console.log(cardList)
  339. cardList.map((item) => {
  340. item.total = item.asset_num // card 第二行台数
  341. item.name = item.category_name //card 第一行名称
  342. // 设备卡片单位处理
  343. if (item.name === '屋面logo') {
  344. item.unit = '个'
  345. } else if (item.name === '玻璃护栏') {
  346. item.unit = '段'
  347. } else {
  348. item.unit = '台'
  349. }
  350. /**
  351. * type 1: 正常运维 2:重要维保 3:重要维修
  352. */
  353. // 默认正常
  354. item.type = 1
  355. item.number = 0
  356. if (item.is_exception || item.is_exception_num) {
  357. // 有异常
  358. item.type = 3
  359. item.number = item.is_exception_num
  360. } else if (item.is_detecting || item.is_detecting_num) {
  361. // 检测中
  362. item.type = 2
  363. item.number = item.is_detecting_num
  364. }
  365. })
  366. this.cardList = cardList
  367. console.log('=============')
  368. console.log(this.cardList)
  369. console.log('=============')
  370. },
  371. handleClick(item) {
  372. switch (item.dataType) {
  373. // 原理图
  374. case 'img':
  375. this.handleImg(item)
  376. break
  377. // 机房平面布置图
  378. case 'room':
  379. this.handleRoom(item)
  380. break
  381. // 楼层分布
  382. case 'floor':
  383. this.handleFloor(item)
  384. break
  385. case 'fbt':
  386. this.handleFbt(item)
  387. break
  388. // 电井间商铺控制范围
  389. case 'electricWell':
  390. this.hanldeElectricWell(item)
  391. break
  392. // 配电室低压柜及出线明细
  393. case 'dyg':
  394. this.hanldeDyg(item)
  395. break
  396. default:
  397. break
  398. }
  399. },
  400. /**
  401. * 显示原理图预览
  402. */
  403. handleImg(item) {
  404. if (item.count === '无') {
  405. return false
  406. }
  407. this.showImage(item)
  408. },
  409. /**
  410. * 显示原理图
  411. */
  412. async showImage(item) {
  413. console.log('显示原理图')
  414. console.log(item)
  415. this.imgList = []
  416. this.imgKey = 'img_' + new Date().getTime()
  417. if (Array.isArray(item.typecode)) {
  418. return this.getTuJianImage(item)
  419. }
  420. let getParams = {
  421. plazaId: this.plazaId,
  422. module: this.module,
  423. neTypename: '位置布置图',
  424. typecode: item.typecode,
  425. system: this.smsxt,
  426. }
  427. let res = await querySystemImage({ getParams })
  428. // console.log(res)
  429. if (!res && !res?.data) {
  430. return false
  431. }
  432. let data = res.data
  433. let imgList = []
  434. data.map((item) => {
  435. imgList.push(item.url)
  436. })
  437. this.imgList = imgList
  438. imgList.length && (this.showImgPreview = true)
  439. },
  440. /**
  441. * 土建立面图(typecode为数组,查询多种图)
  442. */
  443. // TODO: 土建立面图
  444. async getTuJianImage(item) {
  445. let data = {
  446. plazaId: this.plazaId,
  447. module: this.module,
  448. neTypename: '位置布置图',
  449. system: this.smsxt,
  450. },
  451. postParams = {
  452. typecode: item.typecode,
  453. }
  454. let res = await querySystemTuJianImage({ data, postParams })
  455. // console.log(res)
  456. if (!res && !res?.data) {
  457. return false
  458. }
  459. let resData = res.data
  460. let imgList = []
  461. resData?.data.map((item) => {
  462. imgList.push(item.url)
  463. })
  464. this.imgList = imgList
  465. imgList.length && (this.showImgPreview = true)
  466. },
  467. /**
  468. * 跳转 机房平面布置图
  469. */
  470. handleRoom(item) {
  471. if (!item.count || item.count === '无') {
  472. return false
  473. }
  474. // TODO: 机房平面布置图
  475. this.$router.push({ name: 'EngineRoomPicture', params: {} })
  476. },
  477. /**
  478. * 配电室低压柜及出线明细
  479. */
  480. hanldeDyg() {
  481. // TODO: 11111
  482. this.$router.push({ name: 'LowVoltageCabinet', params: {} })
  483. },
  484. /**
  485. * 跳转 楼层分布
  486. */
  487. handleFloor(item) {
  488. let title = this.systemText + ' - 楼层分布'
  489. this.$router.push({ name: 'SystemFloor', query: { title } })
  490. },
  491. /**
  492. * 分水器支路分布图
  493. */
  494. handleFbt(item) {
  495. console.log(item)
  496. let currentSystem = this.listData[this.smsxt]
  497. let fbt = currentSystem.filter((v) => v.dataType === 'fbt')[0]
  498. if (!fbt || fbt.count === '无') {
  499. return false
  500. }
  501. const { categoryId, text } = item
  502. this.SETCATEGORYID(categoryId)
  503. let query = { title: text }
  504. // mockData
  505. // this.fbtArr = [
  506. // {
  507. // code: 'RF',
  508. // gname: 'g80',
  509. // },
  510. // ]
  511. if (this.fbtArr.length) {
  512. query.fbtArr = JSON.stringify(this.fbtArr)
  513. query.fbt = true
  514. }
  515. this.$router.push({ name: 'SystemFloor', query })
  516. },
  517. /**
  518. * 跳转 电井间控制商铺范围
  519. */
  520. hanldeElectricWell(item) {
  521. this.$router.push({ name: 'ElectricWell', params: {} })
  522. },
  523. /**
  524. * 点击卡片,跳转设备列表页面
  525. */
  526. goToEquipment(data) {
  527. console.log(data)
  528. let { name, category_code } = data
  529. this.$router.push({ name: 'EquipmentList', params: { title: name, category_code } })
  530. },
  531. /**
  532. * 点击更多设备卡片,跳转设备列表页面
  533. */
  534. goToMoreEquipment() {
  535. // TODO: 更多设备
  536. this.$router.push({ name: 'MoreEquipmentList', params: {} })
  537. },
  538. },
  539. }
  540. </script>
  541. <style lang='less' scoped>
  542. .equipment-facilities {
  543. width: 100%;
  544. height: calc(100% - 100px);
  545. padding: 0;
  546. display: flex;
  547. .left {
  548. width: 80px;
  549. height: 100%;
  550. }
  551. .right {
  552. flex: 1;
  553. height: 100%;
  554. padding: 16px 16px 16px 12px;
  555. overflow: auto;
  556. .top {
  557. width: 100%;
  558. /deep/ .van-cell {
  559. font-size: 14px;
  560. font-weight: 400;
  561. color: #333333;
  562. background: #f8f9fa;
  563. border-radius: 4px;
  564. margin-bottom: 4px;
  565. .van-cell__value {
  566. width: 40px;
  567. max-width: 50px;
  568. flex: none;
  569. }
  570. }
  571. }
  572. .divider {
  573. border-bottom: 1px solid #e6e6e6;
  574. margin: 20px 0;
  575. }
  576. .card-container {
  577. width: 100%;
  578. display: flex;
  579. flex-wrap: wrap;
  580. flex-flow: wrap;
  581. .card {
  582. flex: 1;
  583. width: 50%;
  584. margin: 2% 0;
  585. min-width: 50%; // 加入这两个后每个item的宽度就生效了
  586. max-width: 50%; // 加入这两个后每个item的宽度就生效了
  587. height: 110px;
  588. }
  589. }
  590. }
  591. }
  592. </style>