xctdetail.vue 17 KB

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