index copy.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  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">
  12. <infoPanel :and-info="false" :is-handle="false"></infoPanel>
  13. </div>
  14. <div class="bottom" v-if="Object.keys(iotcard).length || assets.length">
  15. <div class="header" style="margin-bottom: 10px;">
  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.balance }}
  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="0"
  105. :data="[{title:detail.params.Longitude.paramname,value:detail.params.Longitude.lastvalue || '--'},{title:detail.params.Latitude.paramname,value,value:detail.params.Latitude.lastvalue || '--'},{title:'地址',value,value:address}]"
  106. ></dataBlock>
  107. <dataBlock
  108. v-if="detail.params.OpenDeg"
  109. :title="detail.params.OpenDeg.paramname"
  110. :top="0"
  111. :left="350"
  112. :data="[{value:detail.params.OpenDeg.lastvalue,unit:detail.params.OpenDeg.unit}]"
  113. ></dataBlock>
  114. <dataBlock
  115. v-if="detail.params.Voltage"
  116. :title="detail.params.Voltage.paramname"
  117. :top="80"
  118. :left="350"
  119. :data="[{value:detail.params.Voltage.lastvalue,unit:detail.params.Voltage.unit}]"
  120. ></dataBlock>
  121. <img :src="imgUrl" alt="">
  122. <div style="clear: both;"></div>
  123. </div>
  124. </div>
  125. <div class="chart">
  126. <MyChart ref="chart" :options="[{label:'阀门开度',value:['OpenDeg'],sumShow:true}]" :sumShow="false"></MyChart>
  127. </div>
  128. <div class="message-header">
  129. <customBtn :btnOptions="[{label:wrapper ? '退出全屏' : '进入全屏'}]" :btn="true" style="width:70px" @clickBtn="clickBtn"></customBtn>
  130. <!-- <Message></Message> -->
  131. </div>
  132. </div>
  133. <div class="control-right">
  134. <div class="header">
  135. <span style="color:#ffffff">上传日志</span>
  136. </div>
  137. <div class="upinfo" v-load-directive="historyLoad">
  138. <div class="upinfo-wrapper" v-if="uphistory.length">
  139. <div class="upinfo-item" v-for="(item) in uphistory" :key="item.rowindex">
  140. <div class="name">{{ item.createdate }}</div>
  141. <div class="value">
  142. <a-tooltip>
  143. <template #title>
  144. {{ item.content }}
  145. </template>
  146. {{ item.content }}
  147. </a-tooltip>
  148. </div>
  149. </div>
  150. </div>
  151. <a-empty :image="simpleImage" v-else />
  152. </div>
  153. </div>
  154. </div>
  155. </template>
  156. <script setup>
  157. import infoPanel from '../../modules/infoPanel.vue'
  158. import MyChart from '../../modules/MyChart.vue'
  159. import customBtn from '../../modules/customBtn.vue'
  160. import dataBlock from '../../modules/dataBlock.vue'
  161. import {ref, defineProps, defineEmits, onMounted, provide, onBeforeMount, onUnmounted, computed, watch, nextTick} from 'vue'
  162. import {Modal} from 'ant-design-vue'
  163. import { onBeforeRouteUpdate, useRouter } from 'vue-router'
  164. import { useAuthStore } from '@/stores/modules/auth'
  165. import Api from '@/api/api'
  166. import Http from '@/api/http'
  167. import utils from '@/utils/utils'
  168. import { calcSizeFun,setIntervalFun } from '../../modules/util.js'
  169. import { Empty } from 'ant-design-vue';
  170. const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
  171. let AuthStore = useAuthStore()
  172. let map1 = ref()
  173. let router = useRouter()
  174. let emit = defineEmits(['onSuccess'])
  175. let props = defineProps({})
  176. let refresh = ref(true)
  177. let wrapper = ref(false)
  178. let detail = ref('')
  179. provide('detail',detail)
  180. let calcSize = ref(1)
  181. calcSizeFun((size) => {
  182. calcSize.value = size
  183. })
  184. let imgUrl = computed(() => {
  185. let arr = detail.value.attinfos.filter(item => item.usetype == 'previewImage')
  186. return arr[arr.length - 1] && arr[arr.length - 1].url
  187. })
  188. let clickBtn = (tag) => {
  189. tag.label == '进入全屏' ? wrapper.value = true : wrapper.value = false
  190. refresh.value = false
  191. setTimeout(() => {
  192. refresh.value = true
  193. })
  194. }
  195. let calcUnit = computed(() => {
  196. return (value) => {
  197. if (value) {
  198. return (value / 1024).toFixed(2) + 'MB'
  199. } else {
  200. return '0.0MB'
  201. }
  202. }
  203. })
  204. let chart = ref()
  205. let iotcard = ref({})
  206. let assets = ref([])
  207. let uphistory = ref([])
  208. let upParam = ref({
  209. id:20230701132202,
  210. content: {
  211. type:1,
  212. pageNumber:1,
  213. pageSize:20,
  214. w_deviceid:router.currentRoute.value.query.id
  215. }
  216. })
  217. let detailFun = async () => {
  218. let res = await Api.requested({
  219. "id": "20230628084901",
  220. "content": {
  221. "w_deviceid": router.currentRoute.value.query.id
  222. }
  223. })
  224. detail.value = res.data
  225. detail.value.isSite = AuthStore.nowAccount.sitename == detail.value.sitename //是否本站点设备
  226. let res2 = await Api.requested({
  227. id:20230826160402,
  228. content: {
  229. w_deviceid:router.currentRoute.value.query.id
  230. }
  231. })
  232. iotcard.value = res2.data.length ? res2.data[0] : {}
  233. console.log(iotcard.value,'物联卡信息');
  234. let res3 = await Api.requested({
  235. id:20230802163102,
  236. content: {
  237. assettype:'阀门',
  238. pageNumber:1,
  239. pageSize:999999,
  240. w_deviceid:router.currentRoute.value.query.id
  241. }
  242. })
  243. assets.value = res3.data
  244. console.log(assets.value,'阀门资产信息');
  245. }
  246. provide('detailFun',detailFun)
  247. let address = ref('')
  248. let ready = async () => {
  249. address.value = detail.value.paramvalues.Longitude && detail.value.paramvalues.Latitude ? await utils.getLocation({lng:detail.value.paramvalues.Longitude,lat:detail.value.paramvalues.Latitude}) : '--'
  250. console.log(address,'地址');
  251. }
  252. let vLoadDirective = {
  253. mounted (el,binding) {
  254. let tableWarp = el
  255. function handleFun (e) {
  256. if (tableWarp.scrollTop + tableWarp.clientHeight >= tableWarp.scrollHeight) {
  257. binding.value()
  258. }
  259. }
  260. tableWarp.addEventListener('scroll',handleFun)
  261. el.tableWarp = tableWarp
  262. el.handleFun = handleFun
  263. },
  264. unmounted(el) {
  265. el.tableWarp.removeEventListener('scroll',el.handleFun)
  266. },
  267. }
  268. let TotalPage = ref(0)
  269. let loading = ref(false)
  270. let historyLoad = () => {
  271. if (upParam.value.content.pageNumber == TotalPage.value || loading.value == true) return
  272. upParam.value.content.pageNumber += 1
  273. console.log(upParam.value);
  274. getHistoryData()
  275. }
  276. let getHistoryData = async () => {
  277. loading.value = true
  278. upParam.value.content.timer = new Date().getTime()
  279. let res = await Api.requested(upParam.value)
  280. console.log(res);
  281. uphistory.value = upParam.value.content.pageNumber == 1 ? res.data : uphistory.value.concat(res.data)
  282. TotalPage.value = res.pageTotal
  283. setTimeout(() => {
  284. loading.value = false
  285. },1500)
  286. console.log(uphistory.value,'上传日志信息');
  287. }
  288. //刷新数据
  289. let timer = setIntervalFun(detailFun,router.currentRoute.value.query.id)
  290. onMounted( () => {
  291. detailFun()
  292. getHistoryData()
  293. })
  294. onUnmounted(() => {
  295. clearInterval(timer)
  296. })
  297. </script>
  298. <style scoped>
  299. /deep/.ant-empty-description {
  300. color: #ffffff !important;
  301. }
  302. *{
  303. box-sizing: border-box;
  304. }
  305. .control {
  306. display: flex;
  307. height: calc(100vh - 115px);
  308. width: 100%;
  309. padding: 10px 0;
  310. background: linear-gradient(90deg, #001D6A 0%, #0060B2 82%, #007BD5 100%) !important;
  311. }
  312. .wrapper {
  313. position: absolute;
  314. top: 0;
  315. left: 0;
  316. z-index: 999;
  317. height: 100vh !important;
  318. padding: 20px;
  319. }
  320. .control .control-left {
  321. width: 290px;
  322. height: 100%;
  323. display: flex;
  324. flex-direction: column;
  325. justify-content: space-between;
  326. }
  327. .control .control-left .top {
  328. width: 100%;
  329. height: 49.5%;
  330. background: rgb(0, 0, 0,.05);
  331. padding: 10px;
  332. }
  333. .control .control-left .bottom {
  334. width: 100%;
  335. min-width: 290px;
  336. height: 49.5%;
  337. background: rgb(0, 0, 0,.05);
  338. padding: 10px;
  339. margin-top: 20px;
  340. }
  341. .control .control-content {
  342. flex:1;
  343. height: 100%;
  344. padding: 0 10px;
  345. display: flex;
  346. flex-direction: column;
  347. justify-content: space-between;
  348. position: relative;
  349. overflow: hidden;
  350. }
  351. .control .control-content .message-header {
  352. display: flex;
  353. justify-content: space-between;
  354. align-items: center;
  355. position: absolute;
  356. top: 0;
  357. left: 0;
  358. width: 100%;
  359. padding-left: 10px;
  360. }
  361. .control .control-content .map {
  362. width: 100%;
  363. height: calc(100vh - 245px);
  364. position: relative;
  365. display: flex;
  366. align-items: center;
  367. width: 684px;
  368. padding: 10px 70px 0 70px;
  369. margin: auto;
  370. }
  371. .control .control-content .map img {
  372. width: 100%;
  373. object-fit: scale-down;
  374. z-index: 1;
  375. margin-bottom: 30px;
  376. }
  377. .control .control-content .chart {
  378. width: 100%;
  379. height: 255px;
  380. background: rgb(0, 0, 0,.05);
  381. padding: 0 10px 10px 0;
  382. }
  383. .control .control-right {
  384. width: 272px;
  385. height: 100%;
  386. background: rgb(0, 0, 0,.05);
  387. padding: 10px;
  388. }
  389. .control .control-right .upinfo {
  390. overflow-y: scroll;
  391. height: calc(100% - 10px);
  392. scrollbar-width: none;
  393. }
  394. .control .control-right .upinfo .upinfo-item {
  395. display: flex;
  396. margin-bottom: 10px;
  397. }
  398. .control .control-right .upinfo .upinfo-item .name {
  399. font-size: 12px;
  400. color: #ffffff;
  401. background: rgb(255, 225, 255,.25);
  402. padding: 0 10px;
  403. width: 100px;
  404. text-align: center;
  405. display: -webkit-box;
  406. -webkit-box-align: center;
  407. -webkit-align-items: center;
  408. }
  409. .control .control-right .upinfo .upinfo-item .value {
  410. font-size: 12px;
  411. color:#16FFF6;
  412. background: rgb(255, 225, 255,.10);
  413. padding: 0 10px;
  414. flex: 100;
  415. overflow: hidden;
  416. word-break: break-all;
  417. }
  418. .info {
  419. overflow-y: scroll;
  420. height: calc(100% - 25px);
  421. scrollbar-width: none;
  422. }
  423. ::-webkit-scrollbar {
  424. display: none;
  425. }
  426. .info .info-item {
  427. display: flex;
  428. line-height: 32px;
  429. white-space: nowrap;
  430. }
  431. .info .info-item .name {
  432. font-size: 12px;
  433. color: #ffffff;
  434. background: rgb(255, 225, 255,.25);
  435. padding: 0 10px;
  436. width: 100px;
  437. }
  438. .info .info-item .value {
  439. font-size: 12px;
  440. color:#16FFF6;
  441. background: rgb(255, 225, 255,.10);
  442. padding: 0 10px;
  443. flex: 100;
  444. text-align: right;
  445. overflow: hidden;
  446. }
  447. .info .info-item .value img {
  448. width: 100%;
  449. }
  450. .info .assets {
  451. margin-top: 10px;
  452. }
  453. .info .assets .info-item {
  454. margin-bottom: 0px !important;
  455. }
  456. </style>