smallPest.vue 17 KB

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