smallPest.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. <template>
  2. <view>
  3. <view :class="['info', equipInfo.is_online == 1 ? 'on' : 'off']">
  4. <view class="" @click="copy(equipInfo)">
  5. 设备ID:{{ equipInfo.imei || equipInfo.device_id }}
  6. <image
  7. :src="$imageURL+'/bigdata_app/image/environment/fuzhi.png'"
  8. mode=""
  9. class="tishi"
  10. >
  11. </image>
  12. </view>
  13. <view class="">
  14. 设备名称:{{
  15. equipInfo.device_name == '' ? '无' : equipInfo.device_name
  16. }}
  17. </view>
  18. <!-- <view class="">
  19. 设备类型:吸虫塔
  20. </view> -->
  21. <view class="">
  22. 最新上报时间:{{ equipInfo.uptime || equipInfo.uptime | timeFormat }}
  23. </view>
  24. <view class=""> 设备地址:{{ equipInfo.address || city }} </view>
  25. </view>
  26. <view class="caobox">
  27. <view class="caobox_item" v-if="$QueryPermission(351)" @click="tophoto">
  28. <image
  29. :src="$imageURL+'/bigdata_app/image/cb/1.png'"
  30. mode="widthFix"
  31. ></image>
  32. <view class=""> 查看图片 </view>
  33. </view>
  34. <view class="caobox_item" v-if="$QueryPermission(350)" @click="toset">
  35. <image
  36. :src="$imageURL+'/bigdata_app/image/cb/4.png'"
  37. mode="widthFix"
  38. ></image>
  39. <view class=""> 设备控制 </view>
  40. </view>
  41. <view class="caobox_item" v-if="$QueryPermission(353)" @click="toanal">
  42. <image
  43. :src="$imageURL+'/bigdata_app/image/cb/3.png'"
  44. mode="widthFix"
  45. ></image>
  46. <view class=""> 虫情分析 </view>
  47. </view>
  48. <view class="caobox_item" @click="simRouter">
  49. <image
  50. :src="$imageURL+'/bigdata_app/image/cb/6.png'"
  51. mode="widthFix"
  52. ></image>
  53. <view class=""> SIM卡 </view>
  54. </view>
  55. </view>
  56. <view class="" v-if="$QueryPermission(352)">
  57. <view class=""> 历史数据 </view>
  58. <view class="timebox">
  59. <view class="firsttime" @click="timeshow = true">
  60. <view class="" v-if="start_time != ''">
  61. {{ (start_time / 1000) | timeFormat() }}
  62. </view>
  63. <view class="" v-else>
  64. {{ start_time == '' ? '请选择开始时间' : start_time }}
  65. </view>
  66. </view>
  67. <view class="jiange"> - </view>
  68. <view class="endtime" @click="timeshow = true">
  69. <view class="" v-if="end_time != ''">
  70. {{ (end_time / 1000) | timeFormat() }}
  71. </view>
  72. <view class="" v-else>
  73. {{ end_time == '' ? '请选择结束时间' : end_time }}
  74. </view>
  75. </view>
  76. <u-calendar
  77. v-model="timeshow"
  78. :mode="mode"
  79. @change="timechange"
  80. ></u-calendar>
  81. </view>
  82. <view class="shuju_one">
  83. <view class="canvastishi" v-if="!canvastishiTF && !dataloadingtf">
  84. 暂无数据
  85. </view>
  86. <view class="canvastishi" v-if="dataloadingtf">
  87. <p class="dataloading">加载中</p>
  88. </view>
  89. <canvas
  90. v-if="canvastishiTF"
  91. canvas-id="canvasColumnA"
  92. id="canvasColumnA"
  93. class="charts"
  94. @touchstart="touchLineA($event)"
  95. @touchmove="moveLineA($event)"
  96. @touchend="touchEndLineA($event)"
  97. disable-scroll="true"
  98. :style="{
  99. width: cWidth * pixelRatio + 'px',
  100. height: cHeight * pixelRatio + 'px',
  101. transform: 'scale(' + 1 / pixelRatio + ')',
  102. 'margin-left': (-cWidth * (pixelRatio - 1)) / 2 + 'px',
  103. 'margin-top': (-cHeight * (pixelRatio - 1)) / 2 + 'px',
  104. }"
  105. ></canvas>
  106. </view>
  107. <view class="condition">
  108. <scroll-view scroll-top="0" scroll-x="true" class="scroll-X">
  109. <table class="table" v-if="$QueryPermission(354)">
  110. <tr class="tr">
  111. <th
  112. class="th"
  113. v-for="(item, index) in tableHeadTxt"
  114. :key="'a' + index"
  115. >
  116. {{ item }}
  117. </th>
  118. </tr>
  119. <tr
  120. class="tr"
  121. v-for="(items, indexs) in historylistdata"
  122. :key="'b' + indexs"
  123. v-if="!forbidden"
  124. >
  125. <td class="td">{{ items.d_h_t.addtime | timeFormat() }}</td>
  126. <td class="td">{{ items.d_h_t.at }}</td>
  127. <td class="td">{{ items.d_h_t.ah }}</td>
  128. <td class="td">{{ items.d_h_t.dver }}</td>
  129. <td class="td">{{ items.d_h_t.nrps }}</td>
  130. <td class="td">{{ items.d_h_t.ntps }}</td>
  131. <td class="td">{{ items.d_h_t.lps }}</td>
  132. <td class="td">{{ items.d_h_t.lamp }}</td>
  133. <td class="td">{{ items.d_h_t.current }}</td>
  134. <td class="td">{{ items.d_h_t.vbat }}</td>
  135. <td class="td">{{ items.d_h_t.lng }}</td>
  136. <td class="td">{{ items.d_h_t.lat }}</td>
  137. </tr>
  138. <tr class="tr" v-if="forbidden">
  139. <td class="td" v-for="item in 9">暂无数据</td>
  140. </tr>
  141. </table>
  142. <table class="table" v-else>
  143. <tr class="tr">
  144. <th
  145. class="th"
  146. v-for="(item, index) in tableHeadTxt2"
  147. :key="'a' + index"
  148. >
  149. {{ item }}
  150. </th>
  151. </tr>
  152. <tr
  153. class="tr"
  154. v-for="(items, indexs) in historylistdata"
  155. :key="'b' + indexs"
  156. v-if="!forbidden"
  157. >
  158. <td class="td">{{ items.d_h_t.addtime | timeFormat() }}</td>
  159. <td class="td">{{ items.d_h_t.at }}</td>
  160. <td class="td">{{ items.d_h_t.ah }}</td>
  161. <td class="td">{{ items.d_h_t.dver }}</td>
  162. <td class="td">{{ items.d_h_t.lps }}</td>
  163. <td class="td">{{ items.d_h_t.lng }}</td>
  164. <td class="td">{{ items.d_h_t.lat }}</td>
  165. </tr>
  166. <tr class="tr" v-if="forbidden">
  167. <td class="td" v-for="item in 7">暂无数据</td>
  168. </tr>
  169. </table>
  170. </scroll-view>
  171. <view class="pagenumber">
  172. <button @click="prev">上一页</button>
  173. <view class="pagenumber_page"> 第 {{ page }} 页 </view>
  174. <view class="pagenumber_page"> 共 {{ pagesum }} 页 </view>
  175. <button @click="next" :disabled="forbidden">下一页</button>
  176. </view>
  177. </view>
  178. </view>
  179. <view class="" v-else> 暂无数据 </view>
  180. </view>
  181. </template>
  182. <script>
  183. import uCharts from '../../../components/js_sdk/u-charts/u-charts/u-charts.js';
  184. // import Circulation from "../../../static/js/equipState_dict.json"
  185. var canvaColumnA = null;
  186. export default {
  187. data() {
  188. return {
  189. equipInfo: {},
  190. canvastishiTF: false,
  191. dataloadingtf: false,
  192. cWidth: '400',
  193. cHeight: '400',
  194. pixelRatio: 1,
  195. start_time: '',
  196. end_time: '',
  197. timeshow: false,
  198. mode: 'range',
  199. historydatas: [],
  200. tableHeadTxt: [
  201. '上报时间',
  202. '环境温度(°C)',
  203. '环境湿度(%)',
  204. '版本号',
  205. '雨控状态',
  206. '温控状态',
  207. '光控状态',
  208. '灯管状态',
  209. '电流(mA)',
  210. '电压(V)',
  211. '经度',
  212. '纬度',
  213. ],
  214. tableHeadTxt2: [
  215. '上报时间',
  216. '环境温度(°C)',
  217. '环境湿度(%)',
  218. '版本号',
  219. '光控状态',
  220. '经度',
  221. '纬度',
  222. ],
  223. historylistdata: [],
  224. pagesum: 10,
  225. page: 1,
  226. forbidden: false,
  227. };
  228. },
  229. methods: {
  230. copy(item) {
  231. console.log(item);
  232. uni.setClipboardData({
  233. data: item.imei || item.device_id,
  234. success: function () {
  235. console.log('success');
  236. },
  237. });
  238. },
  239. toset() {
  240. uni.navigateTo({
  241. url:
  242. './xctset?device_id=' +
  243. this.equipInfo.imei +
  244. '&d_id=' +
  245. this.equipInfo.d_id +
  246. '&dtype=' +
  247. this.equipInfo.dtype +
  248. '&device_name=' +
  249. this.equipInfo.device_name,
  250. });
  251. },
  252. tophoto() {
  253. uni.navigateTo({
  254. url:
  255. './photolist?device_id=' +
  256. this.equipInfo.imei +
  257. '&d_id=' +
  258. this.equipInfo.d_id,
  259. });
  260. },
  261. toanal() {
  262. uni.navigateTo({
  263. url:
  264. './analyse?d_id=' +
  265. this.equipInfo.d_id +
  266. '&device_id=' +
  267. this.equipInfo.imei +
  268. '&device_type=12&disable=' +
  269. this.equipInfo.disable,
  270. });
  271. },
  272. simRouter() {
  273. uni.navigateTo({
  274. url: '/pages/prevention/sim?id=' + this.equipInfo.d_id,
  275. });
  276. },
  277. timechange(e) {
  278. this.start_time = +new Date(e.startDate);
  279. this.end_time = +new Date(e.endDate);
  280. this.history();
  281. this.getwind();
  282. },
  283. async history() {
  284. //历史数据列表折线图
  285. this.dataloadingtf = true;
  286. const res = await this.$myRequest({
  287. url: '/api/api_gateway?method=forecast.haomi.haomi_line',
  288. data: {
  289. d_id: this.equipInfo.d_id,
  290. device_type_id: 28,
  291. start: Math.floor(+new Date(this.start_time) / 1000),
  292. end: Math.floor(+new Date(this.end_time) / 1000),
  293. },
  294. });
  295. console.log('响应成功:', res);
  296. this.dataloadingtf = false;
  297. this.historydatas = res;
  298. console.log(this.historydatas);
  299. if (this.historydatas.length == 0) {
  300. this.canvastishiTF = false;
  301. } else {
  302. this.canvastishiTF = true;
  303. var arr1 = [];
  304. var arr2 = [];
  305. var arr3 = [];
  306. var xtitle = [];
  307. for (var i = 0; i < res.length; i++) {
  308. var times = new Date(res[i].addtime * 1000);
  309. xtitle.push(
  310. times.getMonth() +
  311. 1 +
  312. '/' +
  313. times.getDate() +
  314. '-' +
  315. times.getHours() +
  316. ':' +
  317. times.getMinutes()
  318. );
  319. arr1.push(res[i].at == '' ? '0' : res[i].at);
  320. arr2.push(res[i].ah == '' ? '0' : res[i].ah);
  321. }
  322. // console.log(arr1)
  323. var obj = [
  324. {
  325. name: '温度',
  326. data: arr1,
  327. color: '#00E29D',
  328. },
  329. {
  330. name: '湿度',
  331. data: arr2,
  332. color: '#6CBBFF',
  333. },
  334. ];
  335. this.showColumn('canvasColumnA', xtitle, obj);
  336. }
  337. },
  338. showColumn(id, xtitle, xinfo) {
  339. var _self = this;
  340. const ctx = uni.createCanvasContext(id, this);
  341. canvaColumnA = new uCharts({
  342. context: ctx,
  343. type: 'line',
  344. legend: {
  345. position: 'top',
  346. },
  347. fontSize: 11,
  348. background: '#FFFFFF',
  349. pixelRatio: 1,
  350. animation: true,
  351. dataLabel: false,
  352. categories: xtitle,
  353. series: xinfo,
  354. enableScroll: true, //开启图表拖拽功能
  355. xAxis: {
  356. disableGrid: true,
  357. type: 'grid',
  358. gridType: 'dash',
  359. itemCount: 4, //x轴单屏显示数据的数量,默认为5个
  360. scrollShow: true, //新增是否显示滚动条,默认false
  361. // scrollAlign: 'left', //滚动条初始位置
  362. scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
  363. scrollColor: '#DEE7F7', //默认为 #A6A6A6
  364. },
  365. yAxis: {
  366. gridType: 'dash',
  367. gridColor: '#CCCCCC',
  368. dashLength: 8,
  369. splitNumber: 5,
  370. format: (val) => {
  371. return val.toFixed(1);
  372. },
  373. },
  374. width: _self.cWidth * 1,
  375. height: _self.cHeight * 1,
  376. extra: {
  377. line: {
  378. type: 'curve',
  379. },
  380. },
  381. });
  382. },
  383. touchLineA(e) {
  384. console.log(e);
  385. canvaColumnA.scrollStart(e);
  386. },
  387. moveLineA(e) {
  388. canvaColumnA.scroll(e);
  389. },
  390. touchEndLineA(e) {
  391. canvaColumnA.scrollEnd(e);
  392. //下面是toolTip事件,如果滚动后不需要显示,可不填写
  393. canvaColumnA.showToolTip(e, {
  394. format: function (item, category) {
  395. return category + ' ' + item.name + ':' + item.data;
  396. },
  397. });
  398. },
  399. async getwind() {
  400. const res = await this.$myRequest({
  401. url: '/api/api_gateway?method=forecast.haomi.haomi_data',
  402. data: {
  403. d_id: this.equipInfo.d_id,
  404. start: Math.floor(+new Date(this.start_time) / 1000),
  405. end: Math.floor(+new Date(this.end_time) / 1000),
  406. page: this.page,
  407. page_size: '10',
  408. },
  409. });
  410. console.log(res);
  411. if (res.data.length) {
  412. this.historylistdata = res.data;
  413. this.pagesum = Math.ceil(res.counts / 10);
  414. this.forbidden = false;
  415. } else {
  416. this.forbidden = true;
  417. }
  418. },
  419. prev() {
  420. //上一页
  421. if (this.page > 1) {
  422. this.page--;
  423. this.getwind();
  424. }
  425. },
  426. next() {
  427. //下一页
  428. if (this.page < this.pagesum) {
  429. this.page++;
  430. this.getwind();
  431. }
  432. },
  433. },
  434. onLoad(option) {
  435. console.log(JSON.parse(option.info));
  436. this.equipInfo = JSON.parse(option.info);
  437. this.end_time = +new Date();
  438. this.start_time = +new Date() - 1 * 4 * 60 * 60 * 1000;
  439. this.cWidth = uni.upx2px(650);
  440. this.cHeight = uni.upx2px(500);
  441. this.history();
  442. this.getwind();
  443. },
  444. };
  445. </script>
  446. <style lang="scss">
  447. page {
  448. padding: 20rpx;
  449. box-sizing: border-box;
  450. .info {
  451. padding: 20rpx 40rpx;
  452. color: #fff;
  453. line-height: 50rpx;
  454. font-size: 26rpx;
  455. background-size: 100% auto;
  456. background-repeat: no-repeat;
  457. background-color: #0dc6b6;
  458. background-position: top left;
  459. box-sizing: border-box;
  460. width: 100%;
  461. .tishi {
  462. width: 28rpx;
  463. height: 28rpx;
  464. margin: 0rpx 0 0 20rpx;
  465. }
  466. }
  467. .on {
  468. background-image: url('https://s3.hnyfwlw.com/webstaticimg/bigdata_app/image/cb/onBg.png');
  469. }
  470. .off {
  471. background-image: url('https://s3.hnyfwlw.com/webstaticimg/bigdata_app/image/cb/offBg.png');
  472. }
  473. .caobox {
  474. display: flex;
  475. flex-wrap: wrap;
  476. text-align: center;
  477. font-size: 28rpx;
  478. color: #666;
  479. line-height: 50rpx;
  480. image {
  481. width: 52rpx;
  482. }
  483. .caobox_item {
  484. padding: 20rpx 0;
  485. box-sizing: border-box;
  486. flex-basis: 25%;
  487. }
  488. }
  489. .timebox {
  490. box-shadow: 0 0 10rpx #bcb9ca;
  491. display: flex;
  492. background-color: #fff;
  493. padding: 10px;
  494. border-top-right-radius: 5px;
  495. border-top-left-radius: 5px;
  496. margin-top: 30rpx;
  497. .jiange {
  498. width: 5%;
  499. text-align: center;
  500. }
  501. .firsttime,
  502. .endtime {
  503. width: 45%;
  504. text-align: center;
  505. }
  506. }
  507. .shuju_one {
  508. position: relative;
  509. width: 100%;
  510. margin: 40rpx auto;
  511. box-shadow: 0 0 10rpx #bcb9ca;
  512. padding-top: 20rpx;
  513. height: 550rpx;
  514. .canvastishi {
  515. font-size: 32rpx;
  516. position: absolute;
  517. top: 50%;
  518. left: 50%;
  519. margin-left: -64rpx;
  520. margin-top: -21rpx;
  521. .dataloading:after {
  522. overflow: hidden;
  523. display: inline-block;
  524. vertical-align: bottom;
  525. animation: ellipsis 2s infinite;
  526. content: '\2026';
  527. }
  528. @keyframes ellipsis {
  529. from {
  530. width: 2px;
  531. }
  532. to {
  533. width: 15px;
  534. }
  535. }
  536. }
  537. .shuju_one_title {
  538. width: 70%;
  539. margin: 0 auto;
  540. display: flex;
  541. .tltle_text {
  542. width: 25%;
  543. border: 2rpx solid #b2b2b2;
  544. color: #57c878;
  545. text-align: center;
  546. font-size: 24rpx;
  547. height: 50rpx;
  548. line-height: 50rpx;
  549. }
  550. .title_text_color {
  551. width: 25%;
  552. border: 2rpx solid #57c878;
  553. background-color: #57c878;
  554. color: #fff;
  555. text-align: center;
  556. font-size: 24rpx;
  557. height: 50rpx;
  558. line-height: 50rpx;
  559. }
  560. }
  561. }
  562. }
  563. .condition {
  564. display: flex;
  565. flex-wrap: wrap;
  566. width: 100%;
  567. margin: 30rpx auto;
  568. box-shadow: 0 0 10rpx #bcb9ca;
  569. margin-bottom: 30rpx;
  570. .scroll-X {
  571. width: 95%;
  572. margin: 20rpx auto;
  573. .table {
  574. // width: 1672px;
  575. }
  576. .tr {
  577. display: flex;
  578. overflow: hidden;
  579. .th,
  580. .td {
  581. display: inline-block;
  582. padding: 5rpx;
  583. width: 240rpx;
  584. text-align: center;
  585. height: 52rpx;
  586. line-height: 52rpx;
  587. border: 2rpx solid #f1f1f1;
  588. }
  589. .th:first-child,
  590. .td:first-child {
  591. width: 300rpx;
  592. }
  593. }
  594. .tr:nth-child(2n-1) {
  595. background-color: #f5fff8;
  596. }
  597. .tr:first-child {
  598. background-color: #57c878;
  599. color: #fff;
  600. }
  601. }
  602. .pagenumber {
  603. display: flex;
  604. margin: 20rpx auto;
  605. button {
  606. width: 150rpx;
  607. height: 50rpx;
  608. line-height: 50rpx;
  609. font-size: 26rpx;
  610. text-align: center;
  611. background-color: #57c878;
  612. color: #ffffff;
  613. }
  614. .pagenumber_page {
  615. width: 150rpx;
  616. height: 50rpx;
  617. line-height: 50rpx;
  618. font-size: 26rpx;
  619. text-align: center;
  620. }
  621. }
  622. }
  623. ::v-deep .u-calendar__action {
  624. display: flex;
  625. justify-content: space-around;
  626. .u-calendar__action__text {
  627. line-height: 25px;
  628. }
  629. }
  630. </style>