index copy.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. <template>
  2. <baidu-map
  3. class="view"
  4. :center="latlng"
  5. :zoom="zoom"
  6. :scroll-wheel-zoom="true"
  7. @ready="ready">
  8. </baidu-map>
  9. <div :class="['control',{'wrapper':wrapper}]" v-if="detail">
  10. <div class="control-left">
  11. <div class="top" :style="Object.keys(iotcard).length || assets.length ? '--height:49.5%' : '--height:100%'">
  12. <infoPanel :and-info="false" :is-handle="true"></infoPanel>
  13. </div>
  14. <div class="bottom" :style="Object.keys(iotcard).length || assets.length ? '--height:49.5%' : '--height:0%'" v-if="Object.keys(iotcard).length || assets.length">
  15. <div class="header">
  16. <span style="color:#ffffff">关联信息</span>
  17. </div>
  18. <div class="info">
  19. <div v-if="Object.keys(iotcard).length">
  20. <div class="info-item">
  21. <div class="name">物联卡</div>
  22. <div class="value">
  23. <a-tooltip>
  24. <template #title>
  25. {{ iotcard.iccid }}
  26. </template>
  27. {{ iotcard.iccid }}
  28. </a-tooltip>
  29. </div>
  30. </div>
  31. <div class="info-item">
  32. <div class="name">剩余流量</div>
  33. <div class="value">
  34. <a-tooltip>
  35. <template #title>
  36. {{ calcUnit(iotcard.data_remainamount) }}
  37. </template>
  38. {{ calcUnit(iotcard.data_remainamount) }}
  39. </a-tooltip>
  40. </div>
  41. </div>
  42. <div class="info-item">
  43. <div class="name">余额</div>
  44. <div class="value">
  45. <a-tooltip>
  46. <template #title>
  47. {{ iotcard.balance }}
  48. </template>
  49. {{ iotcard.data_useamount }}
  50. </a-tooltip>
  51. </div>
  52. </div>
  53. </div>
  54. <div class="assets" v-for="(item) in assets" :key="item.w_device_assetid">
  55. <div class="info-item">
  56. <div class="name">阀门资产</div>
  57. <div class="value">
  58. <a-tooltip>
  59. <template #title>
  60. {{ item.itemname }}
  61. </template>
  62. {{ item.itemname }}
  63. </a-tooltip>
  64. </div>
  65. </div>
  66. <div class="info-item">
  67. <div class="name">型号</div>
  68. <div class="value">
  69. <a-tooltip>
  70. <template #title>
  71. {{ item.model }}
  72. </template>
  73. {{ item.model }}
  74. </a-tooltip>
  75. </div>
  76. </div>
  77. <div class="info-item">
  78. <div class="name">规格</div>
  79. <div class="value">
  80. <a-tooltip>
  81. <template #title>
  82. {{ item.spec }}
  83. </template>
  84. {{ item.spec }}
  85. </a-tooltip>
  86. </div>
  87. </div>
  88. <div class="info-item">
  89. <div class="name" style="line-height: 88px;">图片</div>
  90. <div class="value">
  91. <img :src="item.attinfos.length ? item.attinfos[0].url : ''" alt="">
  92. </div>
  93. </div>
  94. </div>
  95. </div>
  96. </div>
  97. </div>
  98. <div class="control-content" v-if="refresh">
  99. <div class="map" :style="{transform:`scale(${calcSize})`}">
  100. <div style="display: inline-block;position: relative">
  101. <dataBlock
  102. style="transform: scale(0.9)"
  103. :top="20"
  104. :left="-40"
  105. title="位置"
  106. :data="[{title:'地址',value:address.address || '--'},{title:detail.params.Longitude.paramname,value:detail.params.Longitude.lastvalue || '--',fontSize:'12px'},{title:detail.params.Latitude.paramname,value,value:detail.params.Latitude.lastvalue || '--',fontSize:'12px'}]"
  107. >
  108. <template #handle>
  109. <a-button v-if="detail.function['position']" size="small" @click="positionCheck" style="width: 100%;margin-top: 5px;" ghost>{{ detail.params.position.paramname }}</a-button>
  110. </template>
  111. </dataBlock>
  112. <dataBlock
  113. v-if="detail.params.OpenDeg"
  114. :title="detail.params.OpenDeg.paramname"
  115. :top="20"
  116. :left="420"
  117. :data="[{value:detail.params.OpenDeg.lastvalue,unit:detail.params.OpenDeg.unit}]"
  118. ></dataBlock>
  119. <dataBlock
  120. v-if="detail.params.Voltage"
  121. :title="detail.params.Voltage.paramname"
  122. :top="110"
  123. :left="420"
  124. :data="[{value:detail.params.Voltage.lastvalue,unit:detail.params.Voltage.unit}]"
  125. ></dataBlock>
  126. <!-- <div style="position: absolute;top: 180px;left: 10px;" v-if="detail.function['position']">
  127. <a-button size="small" @click="positionCheck">{{ detail.params.position.paramname }}</a-button>
  128. </div> -->
  129. <img :src="imgUrl" alt="">
  130. <div style="clear: both;"></div>
  131. </div>
  132. </div>
  133. <div class="chart">
  134. <MyChart ref="chart" :options="[{label:'阀门开度',value:['OpenDeg'],sumShow:true}]"></MyChart>
  135. </div>
  136. <div class="message-header">
  137. <customBtn :btnOptions="[{label:wrapper ? '退出全屏' : '进入全屏'}]" :btn="true" style="width:70px" @clickBtn="clickBtn"></customBtn>
  138. <!-- <Message></Message> -->
  139. </div>
  140. </div>
  141. <div class="control-right">
  142. <div class="header">
  143. <span style="color:#ffffff">上传日志</span>
  144. </div>
  145. <div class="upinfo" v-load-directive="historyLoad">
  146. <div class="upinfo-wrapper" v-if="uphistory.length">
  147. <div class="upinfo-item" v-for="(item) in uphistory" :key="item.rowindex">
  148. <div class="name">{{ item.createdate }}</div>
  149. <div class="value">
  150. <a-tooltip>
  151. <template #title>
  152. {{ item.content }}
  153. </template>
  154. {{ item.content }}
  155. </a-tooltip>
  156. </div>
  157. </div>
  158. </div>
  159. <a-empty :image="simpleImage" v-else />
  160. </div>
  161. </div>
  162. </div>
  163. </template>
  164. <script setup>
  165. import infoPanel from '../../modules/infoPanel.vue'
  166. import MyChart from '../../modules/MyChart.vue'
  167. import customBtn from '../../modules/customBtn.vue'
  168. import dataBlock from '../../modules/dataBlock.vue'
  169. import Map from '@/operation/moduleNormal/equipmentMag/modules/map.vue'
  170. import {ref, defineProps, defineEmits, onMounted, provide, onBeforeMount, onUnmounted, computed, watch, nextTick} from 'vue'
  171. import {Modal} from 'ant-design-vue'
  172. import { onBeforeRouteUpdate, useRouter } from 'vue-router'
  173. import { useAuthStore } from '@/stores/modules/auth'
  174. import Api from '@/api/api'
  175. import Http from '@/api/http'
  176. import utils from '@/utils/utils'
  177. import { calcSizeFun,setIntervalFun } from '../../modules/util.js'
  178. import { Empty } from 'ant-design-vue';
  179. const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
  180. let AuthStore = useAuthStore()
  181. let map1 = ref()
  182. let router = useRouter()
  183. let emit = defineEmits(['onSuccess'])
  184. let props = defineProps({})
  185. let refresh = ref(true)
  186. let wrapper = ref(false)
  187. let detail = ref('')
  188. provide('detail',detail)
  189. let calcSize = ref(1)
  190. calcSizeFun((size) => {
  191. calcSize.value = size
  192. })
  193. let imgUrl = computed(() => {
  194. let arr = detail.value.attinfos.filter(item => item.usetype == 'previewImage')
  195. return arr[arr.length - 1] && arr[arr.length - 1].url
  196. })
  197. let clickBtn = (tag) => {
  198. tag.label == '进入全屏' ? wrapper.value = true : wrapper.value = false
  199. refresh.value = false
  200. setTimeout(() => {
  201. refresh.value = true
  202. })
  203. }
  204. let calcUnit = computed(() => {
  205. return (value) => {
  206. if (value) {
  207. return (value / 1024).toFixed(2) + 'MB'
  208. } else {
  209. return '0.0MB'
  210. }
  211. }
  212. })
  213. let chart = ref()
  214. let iotcard = ref({})
  215. let assets = ref([])
  216. let uphistory = ref([])
  217. let upParam = ref({
  218. id:20230701132202,
  219. content: {
  220. type:1,
  221. pageNumber:1,
  222. pageSize:20,
  223. w_deviceid:router.currentRoute.value.query.id
  224. }
  225. })
  226. let detailFun = async () => {
  227. let res = await Api.requested({
  228. "id": "20230628084901",
  229. "content": {
  230. "w_deviceid": router.currentRoute.value.query.id
  231. }
  232. })
  233. detail.value = res.data
  234. detail.value.isSite = AuthStore.nowAccount.sitename == detail.value.sitename //是否本站点设备
  235. let res2 = await Api.requested({
  236. id:20230826160402,
  237. content: {
  238. w_deviceid:router.currentRoute.value.query.id
  239. }
  240. })
  241. iotcard.value = res2.data.length ? res2.data[0] : {}
  242. console.log(iotcard.value,'物联卡信息');
  243. let res3 = await Api.requested({
  244. id:20230802163102,
  245. content: {
  246. assettype:'阀门',
  247. pageNumber:1,
  248. pageSize:999999,
  249. w_deviceid:router.currentRoute.value.query.id
  250. }
  251. })
  252. assets.value = res3.data
  253. console.log(assets.value,'阀门资产信息');
  254. if (!detail.value.isfeedback) {
  255. let keys = Object.keys(detail.value.paramcmdvalues)
  256. keys.forEach(item => {
  257. detail.value.paramcmdvalues[item] = detail.value.paramvalues[item]
  258. })
  259. }
  260. }
  261. provide('detailFun',detailFun)
  262. let address = ref('')
  263. let ready = async () => {
  264. address.value = detail.value.paramvalues.Longitude && detail.value.paramvalues.Latitude ? await utils.getLocation({lng:detail.value.paramvalues.Longitude,lat:detail.value.paramvalues.Latitude}) : '--'
  265. console.log(address,'地址');
  266. }
  267. let positionCheck = () => {
  268. Modal.confirm({
  269. title:`确定下发检测位置操作吗?`,
  270. async onOk () {
  271. let res = await Api.requested({
  272. "id": "20230627163701",
  273. "content": {
  274. "w_deviceid": router.currentRoute.value.query.id,
  275. "w_functionid": detail.value.function['position'].w_functionid,
  276. "params": {
  277. 'position':1
  278. }
  279. }
  280. })
  281. utils.message(res,'操作成功', async () => {
  282. detailFun()
  283. })
  284. }
  285. })
  286. }
  287. let vLoadDirective = {
  288. mounted (el,binding) {
  289. let tableWarp = el
  290. function handleFun (e) {
  291. if (tableWarp.scrollTop + tableWarp.clientHeight >= tableWarp.scrollHeight) {
  292. binding.value()
  293. }
  294. }
  295. tableWarp.addEventListener('scroll',handleFun)
  296. el.tableWarp = tableWarp
  297. el.handleFun = handleFun
  298. },
  299. unmounted(el) {
  300. el.tableWarp.removeEventListener('scroll',el.handleFun)
  301. },
  302. }
  303. let TotalPage = ref(0)
  304. let loading = ref(false)
  305. let historyLoad = () => {
  306. if (upParam.value.content.pageNumber == TotalPage.value || loading.value == true) return
  307. upParam.value.content.pageNumber += 1
  308. console.log(upParam.value);
  309. getHistoryData()
  310. }
  311. let getHistoryData = async () => {
  312. loading.value = true
  313. upParam.value.content.timer = new Date().getTime()
  314. let res = await Api.requested(upParam.value)
  315. console.log(res);
  316. uphistory.value = upParam.value.content.pageNumber == 1 ? res.data : uphistory.value.concat(res.data)
  317. TotalPage.value = res.pageTotal
  318. setTimeout(() => {
  319. loading.value = false
  320. },1500)
  321. console.log(uphistory.value,'上传日志信息');
  322. }
  323. //刷新数据
  324. let timer = setIntervalFun(detailFun,router.currentRoute.value.query.id)
  325. onMounted( () => {
  326. detailFun()
  327. getHistoryData()
  328. })
  329. onUnmounted(() => {
  330. clearInterval(timer)
  331. })
  332. </script>
  333. <style scoped>
  334. /deep/.ant-empty-description {
  335. color: #ffffff !important;
  336. }
  337. *{
  338. box-sizing: border-box;
  339. }
  340. .control {
  341. display: flex;
  342. height: calc(100vh - 115px);
  343. width: 100%;
  344. padding: 10px 0;
  345. background: linear-gradient(90deg, #001D6A 0%, #0060B2 82%, #007BD5 100%) !important;
  346. }
  347. .wrapper {
  348. position: absolute;
  349. top: 0;
  350. left: 0;
  351. z-index: 999;
  352. height: 100vh !important;
  353. padding: 20px;
  354. }
  355. .control .control-left {
  356. width: 290px;
  357. height: 100%;
  358. display: flex;
  359. flex-direction: column;
  360. justify-content: space-between;
  361. }
  362. .control .control-left .top {
  363. width: 100%;
  364. height: var(--height);
  365. background: rgb(0, 0, 0,.05);
  366. padding: 10px;
  367. }
  368. .control .control-left .bottom {
  369. width: 100%;
  370. min-width: 290px;
  371. height: var(--height);
  372. background: rgb(0, 0, 0,.05);
  373. padding: 10px;
  374. margin-top: 20px;
  375. }
  376. .control .control-content {
  377. flex:1;
  378. height: 100%;
  379. padding: 0 10px;
  380. display: flex;
  381. flex-direction: column;
  382. justify-content: space-between;
  383. position: relative;
  384. overflow: hidden;
  385. }
  386. .control .control-content .message-header {
  387. display: flex;
  388. justify-content: space-between;
  389. align-items: center;
  390. position: absolute;
  391. top: 0;
  392. left: 0;
  393. width: 100%;
  394. padding-left: 10px;
  395. }
  396. .control .control-content .map {
  397. width: 100%;
  398. height: calc(100vh - 245px);
  399. position: relative;
  400. display: flex;
  401. align-items: center;
  402. width: 684px;
  403. padding: 10px 70px 0 70px;
  404. margin: auto;
  405. }
  406. .control .control-content .map img {
  407. width: 100%;
  408. object-fit: scale-down;
  409. z-index: 1;
  410. margin-bottom: 30px;
  411. }
  412. .control .control-content .chart {
  413. width: 100%;
  414. height: 255px;
  415. background: rgb(0, 0, 0,.05);
  416. padding: 0 10px 10px 0;
  417. }
  418. .control .control-right {
  419. width: 272px;
  420. height: 100%;
  421. background: rgb(0, 0, 0,.05);
  422. padding: 10px;
  423. }
  424. .control .control-right .upinfo {
  425. overflow-y: scroll;
  426. height: calc(100% - 10px);
  427. scrollbar-width: none;
  428. }
  429. .control .control-right .upinfo .upinfo-item {
  430. display: flex;
  431. margin-bottom: 10px;
  432. }
  433. .control .control-right .upinfo .upinfo-item .name {
  434. font-size: 12px;
  435. color: #ffffff;
  436. background: rgb(255, 225, 255,.25);
  437. padding: 0 10px;
  438. width: 100px;
  439. text-align: center;
  440. display: -webkit-box;
  441. -webkit-box-align: center;
  442. -webkit-align-items: center;
  443. }
  444. .control .control-right .upinfo .upinfo-item .value {
  445. font-size: 12px;
  446. color:#16FFF6;
  447. background: rgb(255, 225, 255,.10);
  448. padding: 0 10px;
  449. flex: 100;
  450. overflow: hidden;
  451. word-break: break-all;
  452. }
  453. .info {
  454. overflow-y: scroll;
  455. height: calc(100% - 25px);
  456. scrollbar-width: none;
  457. }
  458. ::-webkit-scrollbar {
  459. display: none;
  460. }
  461. .info .info-item {
  462. display: flex;
  463. line-height: 32px;
  464. white-space: nowrap;
  465. }
  466. .info .info-item .name {
  467. font-size: 12px;
  468. color: #ffffff;
  469. background: rgb(255, 225, 255,.25);
  470. padding: 0 10px;
  471. width: 100px;
  472. }
  473. .info .info-item .value {
  474. font-size: 12px;
  475. color:#16FFF6;
  476. background: rgb(255, 225, 255,.10);
  477. padding: 0 10px;
  478. flex: 100;
  479. text-align: right;
  480. overflow: hidden;
  481. }
  482. .info .info-item .value img {
  483. width: 100%;
  484. }
  485. .info .assets {
  486. margin-top: 10px;
  487. }
  488. .info .assets .info-item {
  489. margin-bottom: 0px !important;
  490. }
  491. /deep/.ant-btn-background-ghost:hover {
  492. border-color: #16FFF6 !important;
  493. color: #16FFF6 !important;
  494. background: rgb(22,255,246,.30) !important;
  495. }
  496. </style>