facilitydistribute.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. <!-- -->
  2. <template>
  3. <div
  4. class="pestbox"
  5. v-loading="pestboxloading"
  6. element-loading-text="拼命加载中"
  7. element-loading-spinner="el-icon-loading"
  8. element-loading-background="rgba(0, 0, 0, 0.8)"
  9. >
  10. <div
  11. :style="{ height: '100%', width: '100%' }"
  12. id="mychart"
  13. ref="mychart"
  14. ></div>
  15. <div class="searchbox">
  16. <el-select
  17. v-model="inoffvalue"
  18. placeholder="请选择所在监测点"
  19. size="mini"
  20. >
  21. <el-option
  22. v-for="item in inoffoptions"
  23. :key="item.point_id"
  24. :label="item.point_name"
  25. :value="item.point_id"
  26. >
  27. </el-option>
  28. </el-select>
  29. <el-select
  30. v-model="versionsvalue2"
  31. placeholder="请选择隶属海关"
  32. size="mini"
  33. >
  34. <el-option
  35. v-for="item in versionsoptions2"
  36. :key="item.org_name"
  37. :label="item.org_name"
  38. :value="item.org_id"
  39. >
  40. </el-option>
  41. </el-select>
  42. <el-select v-model="statevalue" placeholder="请选择设备状态" size="mini">
  43. <el-option
  44. v-for="item in stateoptions"
  45. :key="item.value"
  46. :label="item.label"
  47. :value="item.value"
  48. >
  49. </el-option>
  50. </el-select>
  51. <el-select v-model="typevalue" placeholder="请选择设备类型" size="mini">
  52. <el-option
  53. v-for="item in typeoptions"
  54. :key="item.type_id"
  55. :label="item.type_name"
  56. :value="item.type_id"
  57. >
  58. </el-option>
  59. </el-select>
  60. <div class="inputbox">
  61. <el-input
  62. v-model="idinput"
  63. placeholder="请输入设备编号"
  64. size="mini"
  65. ></el-input>
  66. </div>
  67. <el-button type="info" @click="search" size="mini">搜索</el-button>
  68. <el-button @click="reset" size="mini">重置</el-button>
  69. </div>
  70. <div class="tallybox">
  71. <p
  72. class="tallybox_item"
  73. v-for="(item, index) in typeoptions"
  74. :key="index"
  75. >
  76. <span
  77. class="tallybox_dian"
  78. :style="{ backgroundColor: item.colour }"
  79. ></span>
  80. <span class="tallybox_text">{{ item.type_name }}</span>
  81. </p>
  82. </div>
  83. <div class="piebox">
  84. <p
  85. :class="
  86. pietf ? 'iconbox el-icon-arrow-right' : 'iconbox el-icon-arrow-left'
  87. "
  88. @click="pietf = !pietf"
  89. style="cursor: pointer"
  90. ></p>
  91. <div class="tishi" :style="{ width: width }" v-if="baseinfo.length == 0">
  92. <p>请点击设备标点,查看设备详情</p>
  93. </div>
  94. <div
  95. v-else
  96. :style="{ width: width }"
  97. id="mychartpie"
  98. ref="mychartpie"
  99. v-loading="loading"
  100. element-loading-text="拼命加载中"
  101. element-loading-spinner="el-icon-loading"
  102. element-loading-background="rgba(0, 0, 0, 0.8)"
  103. >
  104. <div class="infobox">
  105. <h3>设备信息</h3>
  106. <p>
  107. <span>设备名称:</span
  108. ><span>{{
  109. baseinfo[0].device_name == "" ? "暂无" : baseinfo[0].device_name
  110. }}</span>
  111. </p>
  112. <p>
  113. <span>设备编号:</span><span>{{ baseinfo[0].device_id }}</span>
  114. </p>
  115. <p>
  116. <span>所属监测点:</span><span>{{ baseinfo[0].poin_name }}</span>
  117. </p>
  118. <p>
  119. <span>隶属海关:</span
  120. ><span
  121. v-for="item in baseinfo[0].temp_org_list"
  122. :key="item.org_id"
  123. >{{ item.org_name + "、" }}</span
  124. >
  125. </p>
  126. </div>
  127. <div class="wornbox" v-if="device_type_id == 4">
  128. <h3>有害生物监测信息(统计)</h3>
  129. <div class="wornbox_item">
  130. <p v-for="(item, index) in baseinfo[0].pest_list" :key="index">
  131. <span>{{ item.pest_name }}</span
  132. ><span>{{ item.sum }}</span>
  133. </p>
  134. <p style="color: #fff; width: 100%; text-align: center" v-if="baseinfo[0].pest_list.length==0">暂无数据</p>
  135. </div>
  136. </div>
  137. <div class="cbdinfobox" v-if="device_type_id == 3">
  138. <h3>设备状态</h3>
  139. <div class="cbdinfobox_item">
  140. <p>
  141. 环境温度:<span>{{ baseinfo[0].device_data.at }} ℃</span>
  142. </p>
  143. <p>
  144. 环境湿度:<span>{{ baseinfo[0].device_data.ah }} %RH</span>
  145. </p>
  146. </div>
  147. <div class="cbdinfobox_item">
  148. <p>
  149. 设备开关:<span>{{
  150. baseinfo[0].device_data.ds == 0 ? "关机" : "开机"
  151. }}</span>
  152. </p>
  153. <p>
  154. 工作状态:<span>{{
  155. baseinfo[0].device_data.ws == 0 ? "待机" : "工作"
  156. }}</span>
  157. </p>
  158. </div>
  159. <div class="cbdinfobox_item">
  160. <p>
  161. 信号强度:<span>{{ baseinfo[0].device_data.csq }}</span>
  162. </p>
  163. <p>
  164. 最新上报时间:<span>{{ baseinfo[0].uptime }}</span>
  165. </p>
  166. </div>
  167. </div>
  168. <div class="cbdimg" v-if="device_type_id == 3">
  169. <h3 class="title">最新虫情图片</h3>
  170. <el-carousel :interval="5000" arrow="always">
  171. <el-carousel-item
  172. v-for="(item, index) in baseinfo[0].photo_data"
  173. :key="index"
  174. >
  175. <img :src="item.addr" alt="" />
  176. </el-carousel-item>
  177. </el-carousel>
  178. </div>
  179. <div class="videoBonbox" v-if="device_type_id == 6">
  180. <h3 class="title">实时监控</h3>
  181. <div id="videoBon"></div>
  182. </div>
  183. </div>
  184. </div>
  185. </div>
  186. </template>
  187. <script>
  188. //这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  189. import * as echarts from "echarts";
  190. import "../../../node_modules/echarts/map/js/china";
  191. export default {
  192. //import引入的组件需要注入到对象中才能使用
  193. components: {},
  194. data() {
  195. //这里存放数据
  196. return {
  197. pietf: false,
  198. width: "0px",
  199. inoffvalue: "", //监测点 选择
  200. inoffoptions: [], //监测点列表
  201. versionsvalue2: "", //隶属海关 选择
  202. versionsoptions2: [], //隶属海关列表
  203. statevalue: "", //设备状态
  204. stateoptions: [
  205. {
  206. value: "0",
  207. label: "停用(离线)",
  208. },
  209. {
  210. value: "1",
  211. label: "正常(在线)",
  212. },
  213. ], //设备状态列表
  214. typevalue: "", //设备类型
  215. typeoptions: [], //设备类型 列表
  216. idinput: "", //设备编号
  217. baseinfo: [], //设备详情
  218. loading: false,
  219. device_type_id: 0,
  220. myVideo2: {},
  221. pestboxloading: true,
  222. };
  223. },
  224. //监听属性 类似于data概念
  225. computed: {},
  226. //监控data中的数据变化
  227. watch: {
  228. pietf: function (val) {
  229. // console.log(this.width)
  230. if (val) {
  231. this.width = "500px";
  232. } else {
  233. this.width = "0";
  234. if (this.myVideo2[`myPlayer`]) {
  235. this.myVideo2[`myPlayer`].stop();
  236. }
  237. }
  238. // console.log(this.width)
  239. },
  240. device_type_id: function (val) {
  241. console.log(val);
  242. if (val != 6) {
  243. if (this.myVideo2[`myPlayer`]) {
  244. this.myVideo2[`myPlayer`].stop();
  245. }
  246. }
  247. },
  248. },
  249. //方法集合
  250. methods: {
  251. init(data1, data2) {
  252. var that = this;
  253. let myChart = echarts.init(document.getElementById("mychart"));
  254. var arr = [];
  255. const mapData = require("./json/shenzhen.json");
  256. // const name = "深圳";
  257. arr.push(mapData.features);
  258. // echarts.registerMap(name, mapData);
  259. const mapData2 = require("./json/shanwei.json");
  260. console.log(mapData2);
  261. arr.push(mapData2.features);
  262. // const name2 = "汕尾";
  263. // echarts.registerMap(name2, mapData2);
  264. const mapData3 = require("./json/huizhou.json");
  265. arr.push(mapData3.features);
  266. // const name3 = "惠州";
  267. // echarts.registerMap(name3, mapData3);
  268. var arr2 = arr.reduce(function (a, b) {
  269. return a.concat(b);
  270. });
  271. // console.log(arr2);
  272. var xbMap = {
  273. type: "FeatureCollection",
  274. features: arr2,
  275. };
  276. echarts.registerMap("深圳", xbMap);
  277. // let myChart = echarts.init(document.getElementById("mychart"));
  278. window.addEventListener("resize", function () {
  279. // undefined;
  280. myChart.resize();
  281. });
  282. var data = data1;
  283. var geoCoordMap = data2;
  284. myChart.on("click", (params) => {
  285. if (params.componentType == "series") {
  286. console.log(params.value[2]);
  287. this.device_type_id = params.value[2];
  288. this.pietf = true;
  289. // if(this.device_type_id == 6){
  290. this.getbaseinfo(params.name);
  291. // }
  292. }
  293. });
  294. var convertData = function (data) {
  295. var res = [];
  296. for (var i = 0; i < data.length; i++) {
  297. var geoCoord = geoCoordMap[data[i].name];
  298. if (geoCoord) {
  299. res.push({
  300. name: data[i].name,
  301. value: geoCoord.concat(data[i].value),
  302. });
  303. }
  304. }
  305. return res;
  306. };
  307. var option = {
  308. backgroundColor: "#252b45",
  309. title: {
  310. text: "",
  311. subtext: "",
  312. sublink: "",
  313. left: "center",
  314. textStyle: {
  315. color: "#fff",
  316. },
  317. },
  318. // tooltip: {
  319. // trigger: "item",
  320. // },
  321. legend: {
  322. orient: "vertical",
  323. y: "bottom",
  324. x: "right",
  325. data: ["haidilao"],
  326. textStyle: {
  327. color: "#fff",
  328. },
  329. },
  330. geo: {
  331. map: "深圳",
  332. label: {
  333. normal: {
  334. show: true,
  335. color: "#fff",
  336. },
  337. emphasis: {
  338. show: true,
  339. },
  340. },
  341. roam: true, //是否允许缩放
  342. layoutCenter: ["50%", "105%"], //地图位置
  343. layoutSize: "200%",
  344. itemStyle: {
  345. normal: {
  346. color: "#031525", //地图背景色
  347. borderColor: "rgba(100,149,237,1)", //省市边界线
  348. },
  349. emphasis: {
  350. color: "rgba(37, 43, 61, .5)", //悬浮背景
  351. },
  352. },
  353. scaleLimit: {
  354. //所属组件的z分层,z值小的图形会被z值大的图形覆盖
  355. min: 0.5, //最小的缩放值
  356. max: 50,
  357. },
  358. },
  359. series: [
  360. {
  361. name: "Top 5",
  362. type: "effectScatter",
  363. coordinateSystem: "geo",
  364. data: convertData(
  365. data.sort(function (a, b) {
  366. return b.value - a.value;
  367. })
  368. ),
  369. symbolSize: 12,
  370. showEffectOn: "render",
  371. rippleEffect: {
  372. brushType: "stroke",
  373. },
  374. hoverAnimation: true,
  375. label: {
  376. normal: {
  377. formatter: "{b}",
  378. position: "right",
  379. show: false,
  380. },
  381. },
  382. itemStyle: {
  383. normal: {
  384. color: function (e) {
  385. // console.log(e.data.value[2]);
  386. var color = "";
  387. for (var i = 0; i < that.typeoptions.length; i++) {
  388. if (e.data.value[2] == that.typeoptions[i].type_id) {
  389. color = that.typeoptions[i].colour;
  390. }
  391. }
  392. // console.log(color)
  393. return color;
  394. },
  395. shadowBlur: 10,
  396. shadowColor: "#333",
  397. },
  398. },
  399. zlevel: 1,
  400. },
  401. ],
  402. };
  403. echarts.init(document.getElementById("mychart")).setOption(option);
  404. this.pestboxloading = false;
  405. },
  406. getbaselist() {
  407. // this.pestboxloading = true
  408. this.$axios({
  409. method: "POST",
  410. url: "/api/api_gateway?method=monitor_manage.home_map.device_distribute",
  411. data: this.qs.stringify({
  412. trap_number: this.idinput, // 非必传(string) 设备编号 搜索项
  413. point_id: this.inoffvalue, // 非必传(string) 设备所属监测点id 搜索项
  414. org_id: this.versionsvalue2, // 非必传(string) 设备所属组织id 搜索项
  415. trap_status: this.statevalue, // 非必传(num) 诱捕器状态 0停用 1正常 搜索项
  416. type_id: this.typevalue, // 非必传(num) 3测报灯 4诱捕器 6监控 搜索项
  417. }),
  418. }).then((res) => {
  419. // console.log(res.data.data);
  420. var data = res.data.data;
  421. var arr1 = [];
  422. var obj2 = {};
  423. for (var i = 0; i < data.length; i++) {
  424. var obj = {
  425. name: data[i].d_id,
  426. value: data[i].device_type_id,
  427. };
  428. arr1.push(obj);
  429. obj2[data[i].d_id] = [Number(data[i].lat), Number(data[i].lng)];
  430. // console.log(obj2)
  431. }
  432. // console.log(arr1,obj2)
  433. this.init(arr1, obj2);
  434. // this.inoffoptions = res.data.data.point_data;
  435. });
  436. },
  437. search() {
  438. this.getbaselist();
  439. },
  440. reset() {
  441. this.inoffvalue = "";
  442. this.versionsvalue2 = "";
  443. this.statevalue = "";
  444. this.typevalue = "";
  445. this.idinput = "";
  446. this.getbaselist();
  447. },
  448. // getmon() {
  449. // //获取监测点列表 组织列表
  450. // this.$axios({
  451. // method: "POST",
  452. // url: "/api/api_gateway?method=sysmenage.usermanager.org_list",
  453. // }).then((res) => {
  454. // console.log(res.data.data);
  455. // this.inoffoptions = res.data.data.point_data;
  456. // });
  457. // },
  458. getmon2() {
  459. this.$axios({
  460. method: "POST",
  461. url: "/api/api_gateway?method=monitor_manage.trap_manage.trap_org",
  462. data: this.qs.stringify({
  463. page_item: "1000000",
  464. }),
  465. }).then((res) => {
  466. console.log(res.data.data);
  467. this.versionsoptions2 = res.data.data.org_data;
  468. this.inoffoptions = res.data.data.point_data;
  469. });
  470. },
  471. gettype() {
  472. this.$axios({
  473. method: "POST",
  474. url: "/api/api_gateway?method=monitor_manage.home_map.home_map_device_type",
  475. }).then((res) => {
  476. console.log(res.data.data);
  477. this.typeoptions = res.data.data;
  478. this.getbaselist();
  479. });
  480. },
  481. getbaseinfo(d_id) {
  482. this.loading = true;
  483. this.$axios({
  484. method: "POST",
  485. url: "/api/api_gateway?method=monitor_manage.home_map.device_distribute_details",
  486. data: this.qs.stringify({
  487. d_id: d_id,
  488. }),
  489. }).then((res) => {
  490. console.log(res.data.data);
  491. this.loading = false;
  492. this.baseinfo = res.data.data;
  493. if (this.baseinfo[0].device_info) {
  494. // console.log(this.baseinfo[0].device_info.hlsHd)
  495. let hlsHd = this.baseinfo[0].device_info.hlsHd;
  496. let playHtml = `<video id="myPlayer" muted autoplay poster='' controls playsInline webkit-playsinline src="${hlsHd}" style="width:100%; height:100%;"></video>`;
  497. // console.log(hlsHd);
  498. this.$nextTick(() => {
  499. document.getElementById("videoBon").innerHTML = playHtml;
  500. this.myVideo2[`myPlayer`] = new EZUIKit.EZUIPlayer(`myPlayer`);
  501. setTimeout(() => {
  502. this.myVideo2[`myPlayer`].play();
  503. }, 150);
  504. });
  505. } else {
  506. var dom = document.getElementById("myPlayer");
  507. dom.style.display = "none";
  508. }
  509. });
  510. },
  511. },
  512. beforeCreate() {}, //生命周期 - 创建之前
  513. //生命周期 - 创建完成(可以访问当前this实例)
  514. created() {},
  515. beforeMount() {}, //生命周期 - 挂载之前
  516. //生命周期 - 挂载完成(可以访问DOM元素)
  517. mounted() {
  518. // this.getmon();
  519. this.getmon2();
  520. this.gettype();
  521. },
  522. beforeUpdate() {}, //生命周期 - 更新之前
  523. updated() {}, //生命周期 - 更新之后
  524. beforeDestroy() {
  525. if (this.myVideo2[`myPlayer`]) {
  526. this.myVideo2[`myPlayer`].stop();
  527. }
  528. }, //生命周期 - 销毁之前
  529. destroyed() {
  530. if (this.myVideo2[`myPlayer`]) {
  531. this.myVideo2[`myPlayer`].stop();
  532. }
  533. }, //生命周期 - 销毁完成
  534. activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  535. };
  536. </script>
  537. <style lang="less" scoped>
  538. .pestbox {
  539. width: 100%;
  540. height: 97%;
  541. position: relative;
  542. overflow: hidden;
  543. background-color: #252b45;
  544. .tishi {
  545. // width: 500px;
  546. height: 50px;
  547. color: #fff;
  548. line-height: 50px;
  549. background-color: #04243e;
  550. text-align: center;
  551. transition: width 1s ease;
  552. overflow: hidden;
  553. }
  554. .searchbox {
  555. position: absolute;
  556. top: 10px;
  557. left: 15px;
  558. display: flex;
  559. /deep/.el-select {
  560. margin-right: 10px;
  561. }
  562. /deep/.el-date-editor {
  563. margin-right: 10px;
  564. }
  565. /deep/.el-button--info {
  566. background-color: #409eff;
  567. border-color: #409eff;
  568. }
  569. .inputbox {
  570. margin-right: 10px;
  571. /deep/.el-input {
  572. width: 200px;
  573. }
  574. }
  575. }
  576. .tallybox {
  577. position: absolute;
  578. top: 50px;
  579. left: 15px;
  580. .tallybox_item {
  581. margin-bottom: 5px;
  582. .tallybox_dian {
  583. display: inline-block;
  584. width: 6px;
  585. height: 6px;
  586. // background-color: #fff;
  587. border-radius: 50%;
  588. }
  589. .tallybox_text {
  590. // background-color: #fff;
  591. // display: inline-block;
  592. font-size: 14px;
  593. color: #fff;
  594. }
  595. }
  596. }
  597. .piebox {
  598. position: absolute;
  599. top: 0;
  600. right: 0;
  601. display: flex;
  602. // height: 100%;
  603. transition: width 1s ease;
  604. overflow: hidden;
  605. .iconbox {
  606. width: 30px;
  607. height: 50px;
  608. background-color: chocolate;
  609. color: #fff;
  610. line-height: 50px;
  611. text-align: center;
  612. font-size: 25px;
  613. }
  614. #mychartpie {
  615. transition: all 1s ease;
  616. background-color: #04243e;
  617. // padding: 20px;
  618. box-sizing: border-box;
  619. overflow: hidden;
  620. border-radius: 10px;
  621. .infobox {
  622. padding: 20px 20px 0 20px;
  623. h3 {
  624. margin-top: 0;
  625. color: #fff;
  626. }
  627. p {
  628. margin-bottom: 15px;
  629. color: #fff;
  630. font-size: 14px;
  631. span {
  632. color: #04d5e8;
  633. }
  634. span:first-child {
  635. display: inline-block;
  636. width: 85px;
  637. color: #fff;
  638. }
  639. }
  640. }
  641. .wornbox {
  642. padding: 0 20px 20px;
  643. h3 {
  644. margin-top: 0;
  645. color: #fff;
  646. }
  647. .wornbox_item {
  648. display: flex;
  649. flex-wrap: wrap;
  650. p {
  651. width: 40%;
  652. margin-bottom: 15px;
  653. color: #fff;
  654. display: flex;
  655. justify-content: space-between;
  656. font-size: 14px;
  657. margin-right: 20px;
  658. span:nth-child(2) {
  659. color: #04d5e8;
  660. }
  661. }
  662. }
  663. }
  664. .cbdinfobox {
  665. padding: 0 20px 20px;
  666. h3 {
  667. margin-top: 0;
  668. color: #fff;
  669. }
  670. .cbdinfobox_item {
  671. display: flex;
  672. width: 100%;
  673. margin: 0 15px 10px 0;
  674. p {
  675. color: #fff;
  676. font-size: 14px;
  677. margin-right: 20px;
  678. span {
  679. color: #04d5e8;
  680. }
  681. }
  682. p:first-child {
  683. width: 150px;
  684. }
  685. }
  686. }
  687. .cbdimg {
  688. padding: 0px 20px 0 20px;
  689. .title {
  690. margin-top: 0;
  691. color: #fff;
  692. }
  693. img {
  694. width: 100%;
  695. height: 100%;
  696. }
  697. }
  698. .videoBonbox {
  699. padding: 0 20px 20px;
  700. h3 {
  701. margin-top: 0;
  702. color: #fff;
  703. }
  704. }
  705. }
  706. }
  707. }
  708. </style>