details -新设计图无动态接入.vue 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435
  1. <template>
  2. <view class="box">
  3. <!-- 上面要素值 -->
  4. <view :class="`bigBox ${show ? 'bigOpen' : ''}`">
  5. <view class="topInfo">
  6. <u-row gutter="10">
  7. <u-col span="3" v-for="item in ElementList">
  8. <view class="item">
  9. <view>{{ item.value }}</view>
  10. <view>{{ item.unit }}</view>
  11. <view>{{ item.name }}</view>
  12. </view>
  13. </u-col>
  14. </u-row>
  15. <view
  16. class="readmore"
  17. v-if="!show"
  18. @click="
  19. show = true;
  20. getHistoryData();
  21. "
  22. >
  23. 查看详情<u-icon name="arrow-down" color="#93FFDE" size="28"></u-icon>
  24. </view>
  25. </view>
  26. <!-- 统计图 -->
  27. <view class="hisBox" v-show="show">
  28. <view class="axiosBox">
  29. <view class="title"> 历史数据 </view>
  30. <view class="histimeBox">
  31. <u-icon name="calendar" color="#C1C1C1" size="24"></u-icon>
  32. <view class="time" @click="calendarshow = true">
  33. {{
  34. historyTime.startDate
  35. ? historyTime.startDate
  36. : timestampToDateTime(new Date().getTime() / 1000)
  37. }}
  38. </view>
  39. <view class="">至</view>
  40. <view class="time" @click="calendarshow = true">
  41. {{
  42. historyTime.endDate
  43. ? historyTime.endDate
  44. : timestampToDateTime(new Date().getTime() / 1000)
  45. }}
  46. </view>
  47. <u-icon
  48. name="close-circle"
  49. color="#C1C1C1"
  50. size="28"
  51. @click="
  52. historyTime = {};
  53. getHistoryData();
  54. "
  55. v-if="historyTime.startDate"
  56. ></u-icon>
  57. </view>
  58. <u-calendar
  59. v-model="calendarshow"
  60. mode="range"
  61. @change="changeDate"
  62. ></u-calendar>
  63. <view class="chartBox">
  64. <canvas
  65. canvas-id="canvasColumnA"
  66. id="canvasColumnA"
  67. class="charts"
  68. @touchstart="touchLineA($event)"
  69. @touchmove="moveLineA($event)"
  70. @touchend="touchEndLineA($event)"
  71. ></canvas>
  72. </view>
  73. </view>
  74. <view class="readmoreHIs" @click="show = false">
  75. 收起详情<u-icon name="arrow-up" color="#14A478" size="28"></u-icon>
  76. </view>
  77. </view>
  78. </view>
  79. <view class="" v-if="!show">
  80. <!-- 历史记录弹框 -->
  81. <u-tabs
  82. :list="list"
  83. active-color="#14A478"
  84. bar-width="100"
  85. :is-scroll="false"
  86. :current="current"
  87. @change="change"
  88. ></u-tabs>
  89. <!-- 设备图 -->
  90. <view class="devicePhoto" v-if="current == 0">
  91. <view class="titleBox">
  92. <u-alert-tips
  93. type="primary"
  94. :title-style="alertTipColor"
  95. title="点击按钮可对应控制阀门开关,开即打开,关即关闭"
  96. :show-icon="true"
  97. ></u-alert-tips>
  98. <!-- <view class="btn" @click="statusPanel=true">控制面板</view> -->
  99. <!-- <u-popup v-model="statusPanel" mode="bottom">
  100. <view class="consoleBox">
  101. <view class="swichBox">
  102. <u-row :gutter="16" justify="space-between">
  103. <u-col span="6" v-for="(item, index) in buttonList" v-if="(index + 1) % 2 == 1">
  104. <view class="preSwich">
  105. <view>肥料{{ (index + 1) / 2 > 1 ? (index + 2) / 2 : 1 }}</view>
  106. <u-switch v-model="item.off" active-color="#14A478" inactive-color="#AEB4C2"
  107. :loading="item.disabled"
  108. @change="switchchange($event, item.number, item, index, true)"></u-switch>
  109. </view>
  110. </u-col>
  111. <u-col span="6" v-for="(item, index) in facilityvalve"
  112. v-if="index > buttonList.length - 1">
  113. <view class="preSwich">
  114. <view>{{item.name}}</view>
  115. <u-switch v-model="item.off" active-color="#14A478" inactive-color="#AEB4C2"
  116. :loading="item.disabled"
  117. @change="switchchange($event, item.number, item, index)"></u-switch>
  118. </view>
  119. </u-col>
  120. </u-row>
  121. </view>
  122. <u-button type="success" @click="statusPanel=false">确定</u-button>
  123. </view>
  124. </u-popup> -->
  125. </view>
  126. <view class="main">
  127. <image
  128. class="mainContent"
  129. src="../../static/images/waterandfernew/mainNew.png"
  130. ></image>
  131. <!-- <view class="sourceBox">
  132. <view class="smallBox">
  133. 水源
  134. </view>
  135. </view> -->
  136. <!-- 桶 -->
  137. <view class="colList">
  138. <view
  139. class="preClo"
  140. v-for="(item, index) in buttonList"
  141. v-if="(index + 1) % 2 == 1"
  142. :key="`fei${index}`"
  143. >
  144. <view> 肥料{{ (index + 1) / 2 > 1 ? (index + 2) / 2 : 1 }} </view>
  145. <image
  146. src="../../static/images/waterandfernew/colNew.png"
  147. v-if="buttonList.length == 2"
  148. >
  149. </image>
  150. <image
  151. src="../../static/images/waterandfernew/colLeft.png"
  152. v-else-if="buttonList.length > 2 && index == 0"
  153. ></image>
  154. <image
  155. src="../../static/images/waterandfernew/colRight.png"
  156. v-else-if="
  157. buttonList.length > 2 && index == buttonList.length - 2
  158. "
  159. ></image>
  160. <image
  161. src="../../static/images/waterandfernew/colCenter.png"
  162. v-else
  163. ></image>
  164. <view class="jiaoBtn" v-if="facilityvalve.length > 0">
  165. <u-switch
  166. v-model="
  167. facilityvalve[`${index == 0 ? 10 : index == 2 ? 9 : 8}`][
  168. 'off'
  169. ]
  170. "
  171. active-color="#14A478"
  172. inactive-color="#AEB4C2"
  173. :loading="
  174. facilityvalve[`${index == 0 ? 10 : index == 2 ? 9 : 8}`][
  175. 'disabled'
  176. ]
  177. "
  178. @change="
  179. switchchange(
  180. $event,
  181. facilityvalve[`${index == 0 ? 10 : index == 2 ? 9 : 8}`][
  182. 'number'
  183. ],
  184. facilityvalve[`${index == 0 ? 10 : index == 2 ? 9 : 8}`],
  185. index == 0 ? 10 : index == 2 ? 9 : 8
  186. )
  187. "
  188. ></u-switch>
  189. </view>
  190. <view class="shanBox" v-if="facilityvalve.length > 0">
  191. <image
  192. v-if="
  193. !facilityvalve[`${index == 0 ? 10 : index == 2 ? 9 : 8}`][
  194. 'off'
  195. ]
  196. "
  197. src="../../static/images/waterandfernew/shan.png"
  198. ></image>
  199. <image
  200. v-else
  201. class="circleAnm"
  202. src="../../static/images/waterandfernew/shanannimate.png"
  203. ></image>
  204. </view>
  205. <view
  206. class="btnBox"
  207. @click="switchchange($event, item.number, item, index, true)"
  208. >
  209. <image
  210. v-if="item.off"
  211. src="../../static/images/waterandfernew/feiopen.png"
  212. ></image>
  213. <image
  214. v-else
  215. src="../../static/images/waterandfernew/feiclose.png"
  216. ></image>
  217. </view>
  218. </view>
  219. </view>
  220. <!-- 废料管口 -->
  221. <view class="exit">
  222. <image src="../../static/images/waterandfernew/exit.png"></image>
  223. </view>
  224. <!-- 注肥泵 -->
  225. <view
  226. class="feiLight"
  227. @click="
  228. switchchange(
  229. !feiBeng,
  230. facilityvalve[6].number,
  231. facilityvalve[6],
  232. 6
  233. )
  234. "
  235. >
  236. <image
  237. v-if="feiBeng"
  238. src="../../static/images/waterandfernew/feiAllopen.png"
  239. ></image>
  240. <image
  241. v-else
  242. src="../../static/images/waterandfernew/feiAllclose.png"
  243. ></image>
  244. </view>
  245. <!-- 控制柜 -->
  246. <view class="kongBox">
  247. <image
  248. v-if="feiBeng"
  249. src="../../static/images/waterandfernew/kongclose.png"
  250. ></image>
  251. <image
  252. v-else
  253. src="../../static/images/waterandfernew/kongopen.png"
  254. ></image>
  255. </view>
  256. <!-- 进水泵 -->
  257. <view
  258. class="warterIn"
  259. @click="
  260. switchchange(
  261. !mainBeng,
  262. facilityvalve[7].number,
  263. facilityvalve[7],
  264. 7
  265. )
  266. "
  267. >
  268. <image
  269. v-if="mainBeng"
  270. src="../../static/images/waterandfernew/feiopen.png"
  271. ></image>
  272. <image
  273. v-else
  274. src="../../static/images/waterandfernew/feiclose.png"
  275. ></image>
  276. </view>
  277. <!-- 进水指示 -->
  278. <view class="warterLight">
  279. <image
  280. v-if="mainBeng"
  281. src="../../static/images/waterandfernew/bengopen.png"
  282. ></image>
  283. <image
  284. v-else
  285. src="../../static/images/waterandfernew/bengclose.png"
  286. ></image>
  287. </view>
  288. <!-- 电风扇 -->
  289. <!-- <view class="fengBox">
  290. <view class="relativeBox">
  291. <image src="../../static/images/waterandfernew/fengmain.png"></image>
  292. <image :class="feiBeng ? 'circleAnm' : ''"
  293. src="../../static/images/waterandfernew/fengleafs.png"></image>
  294. </view>
  295. </view> -->
  296. <!-- 水管控制阀 -->
  297. <view class="benList">
  298. <!-- <view class="preBen" v-for="item, index in buttonList" v-if="(index + 1) % 2 == 1"
  299. @click="switchchange(!item.off, item.number, item, index, true)">
  300. <image class="daoguan" src="../../static/images/waterandfernew/bottomNew.png"
  301. v-if="(index + 1) % 2 < 4"></image>
  302. <view class="info">
  303. 肥料{{ (index + 1) / 2 > 1 ? (index + 2) / 2 : 1 }}开关
  304. </view>
  305. <image class="status" v-if="item.off" src="../../static/images/waterandfernew/open.png">
  306. </image>
  307. <image class="status" v-else src="../../static/images/waterandfernew/close.png"></image>
  308. </view> -->
  309. <view
  310. class="preBen"
  311. v-for="(item, index) in facilityvalve"
  312. v-if="index > 10"
  313. @click="switchchange(!item.off, item.number, item, index)"
  314. >
  315. <image
  316. class="daoguan"
  317. src="../../static/images/waterandfernew/bottomNew.png"
  318. v-if="index > 10"
  319. ></image>
  320. <view class="info">
  321. {{ item.name }}
  322. </view>
  323. <image
  324. class="status"
  325. v-if="item.off"
  326. src="../../static/images/waterandfernew/open.png"
  327. >
  328. </image>
  329. <image
  330. class="status"
  331. v-else
  332. src="../../static/images/waterandfernew/close.png"
  333. ></image>
  334. </view>
  335. </view>
  336. </view>
  337. </view>
  338. <!-- 操作记录 -->
  339. <view class="consoleList" v-else>
  340. <view class="histimeBox">
  341. <u-icon name="calendar" color="#C1C1C1" size="24"></u-icon>
  342. <view class="time" @click="consoleshow = true">
  343. {{ consoleTime.startDate ? consoleTime.startDate : '开始' }}
  344. </view>
  345. <view class="">至</view>
  346. <view class="time" @click="consoleshow = true"
  347. >{{ consoleTime.endDate ? consoleTime.endDate : '结束' }}
  348. </view>
  349. <u-icon
  350. name="close-circle"
  351. color="#C1C1C1"
  352. size="28"
  353. @click="clearContime"
  354. v-if="consoleTime.startDate"
  355. ></u-icon>
  356. </view>
  357. <u-calendar
  358. v-model="consoleshow"
  359. mode="range"
  360. @change="changeConsoleDate"
  361. ></u-calendar>
  362. <view class="tableList tableTitle">
  363. <view>设备名称</view>
  364. <view>操作内容</view>
  365. <view>操作时间</view>
  366. </view>
  367. <view
  368. class="tableList"
  369. v-for="(item, index) in tableData"
  370. :key="item.uptime + index"
  371. >
  372. <view>{{ item.device_name }}</view>
  373. <view :class="item.status ? 'success' : 'error'">{{
  374. item.operation_content
  375. }}</view>
  376. <view>{{ item.uptime }}</view>
  377. </view>
  378. <u-loadmore :status="status" />
  379. </view>
  380. </view>
  381. </view>
  382. </template>
  383. <script>
  384. import uCharts from '../../components/js_sdk/u-charts/u-charts/u-charts.js';
  385. var canvaColumnA = null;
  386. var canvasRing = null;
  387. export default {
  388. data() {
  389. return {
  390. alertTipColor: {
  391. color: '#1890FF',
  392. fontSize: '12px',
  393. },
  394. device_id: '',
  395. mainBeng: false,
  396. feiBeng: false,
  397. calendarshow: false,
  398. historyTime: {},
  399. cWidth: '350',
  400. cHeight: '350',
  401. pixelRatio: 1,
  402. facilityvalve: [],
  403. feiNum: 0, //肥料桶实际占据通道个数
  404. buttonList: [], // 肥料开关列表
  405. colomRoundList: ['j1', 'j2', 'j3', 'j4', 'j5', 'j6', 'j7', 'j8'], // 废料桶的通道
  406. ElementList: [],
  407. typename: [
  408. '-',
  409. '风机',
  410. '水泵',
  411. '增氧机',
  412. '湿帘',
  413. '遮阳',
  414. '开窗',
  415. '保温',
  416. '投食机',
  417. ],
  418. show: false,
  419. list: [
  420. {
  421. name: '设备控制',
  422. },
  423. {
  424. name: '执行结果',
  425. },
  426. {
  427. name: '操作记录',
  428. },
  429. ],
  430. statusPanel: false,
  431. current: 0,
  432. consoleshow: false,
  433. consoleTime: {},
  434. tableData: [],
  435. page: 1,
  436. total: 0,
  437. status: 'loadmore',
  438. };
  439. },
  440. methods: {
  441. changeTimeStatus(item, changeIndex) {
  442. this.timer = setTimeout(() => {
  443. item.disabled = false; // 改变值
  444. this.facilityvalve[changeIndex].disabled = false;
  445. this.getEquipstatus();
  446. this.timer = null; // 清空定时器引用
  447. }, 15000);
  448. },
  449. // 选择日期
  450. changeDate(e) {
  451. console.log(e);
  452. this.historyTime = e;
  453. this.getHistoryData();
  454. },
  455. // 绘制折线图
  456. showColumn(id, xtitle, xinfo) {
  457. var _self = this;
  458. const ctx = uni.createCanvasContext(id, this);
  459. canvaColumnA = new uCharts({
  460. context: ctx,
  461. type: 'line',
  462. legend: {
  463. position: 'top',
  464. },
  465. fontSize: 11,
  466. background: '#FFFFFF',
  467. pixelRatio: 1,
  468. animation: true,
  469. dataLabel: false,
  470. categories: xtitle,
  471. series: xinfo,
  472. enableScroll: true, //开启图表拖拽功能
  473. xAxis: {
  474. disabled: true,
  475. disableGrid: false,
  476. type: 'grid',
  477. gridType: 'dash',
  478. itemCount: 15, //x轴单屏显示数据的数量,默认为5个
  479. scrollShow: true, //新增是否显示滚动条,默认false
  480. scrollAlign: 'right', //滚动条初始位置
  481. scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
  482. scrollColor: '#DEE7F7', //默认为 #A6A6A6
  483. },
  484. yAxis: {},
  485. width: _self.cWidth * 1,
  486. height: _self.cHeight * 1,
  487. extra: {
  488. line: {
  489. type: 'curve',
  490. },
  491. },
  492. });
  493. },
  494. touchLineA(e) {
  495. // console.log(e)
  496. canvaColumnA.scrollStart(e);
  497. },
  498. moveLineA(e) {
  499. canvaColumnA.scroll(e);
  500. },
  501. touchEndLineA(e) {
  502. canvaColumnA.touchLegend(e);
  503. // canvaColumnA.showToolTip(e);
  504. canvaColumnA.scrollEnd(e);
  505. //下面是toolTip事件,如果滚动后不需要显示,可不填写
  506. canvaColumnA.showToolTip(e, {
  507. format: function (item, category) {
  508. return category + ' ' + item.name + ':' + item.data;
  509. },
  510. });
  511. },
  512. // 时间戳转换
  513. timestampToDateTime(timestamp, isTime) {
  514. var date = new Date(timestamp * 1000); // 将时间戳转换为毫秒并创建一个日期对象
  515. var year = date.getFullYear(); // 获取年份
  516. var month = ('0' + (date.getMonth() + 1)).slice(-2); // 获取月份,并补零
  517. var day = ('0' + date.getDate()).slice(-2); // 获取日期,并补零
  518. var hours = ('0' + date.getHours()).slice(-2); // 获取小时,并补零
  519. var minutes = ('0' + date.getMinutes()).slice(-2); // 获取分钟,并补零
  520. var seconds = ('0' + date.getSeconds()).slice(-2); // 获取秒数,并补零
  521. if (isTime) {
  522. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  523. } else {
  524. return `${year}-${month}-${day}`;
  525. }
  526. },
  527. // 历史数据
  528. async getHistoryData() {
  529. uni.showLoading({
  530. title: '加载中',
  531. });
  532. const { historyTime } = this;
  533. // 获取当前日期
  534. var currentDate = new Date();
  535. // 设置时间为 0 点
  536. currentDate.setHours(0, 0, 0, 0);
  537. let begin = historyTime.startDate
  538. ? new Date(historyTime.startDate).getTime() / 1000 - 8 * 3600
  539. : Math.floor(currentDate.getTime() / 1000);
  540. // 设置时间为 24 点
  541. currentDate.setHours(24, 0, 0, 0);
  542. let end = historyTime.endDate
  543. ? new Date(historyTime.endDate).getTime() / 1000 - 8 * 3600
  544. : Math.floor(currentDate.getTime() / 1000);
  545. //折线图数据
  546. let res = await this.$myRequest({
  547. url: '/api/api_gateway?method=weather.weather.sf_data_chart',
  548. data: {
  549. device_id: this.device_id,
  550. begin: begin,
  551. end: end,
  552. },
  553. });
  554. uni.hideLoading();
  555. var conf = res.conf.eleName;
  556. var dat = res.dat.reverse();
  557. //console.log(dat);
  558. conf = conf.split('/');
  559. // var arr1 = [];
  560. var regroupData = []; //重组数据
  561. let options = [];
  562. var timeList = [];
  563. for (var i = 0; i < conf.length; i++) {
  564. // var arr = [];
  565. if (conf[i] != '-') {
  566. var optionobj = {};
  567. optionobj.value = i;
  568. optionobj.label = conf[i];
  569. options.push(optionobj);
  570. var reddata = [];
  571. dat.forEach((item, index) => {
  572. if (timeList.length < dat.length) {
  573. timeList.push(this.timestampToDateTime(item.uptime, true));
  574. }
  575. var status = item.device_status.split(',');
  576. // //console.log(status);
  577. var arr = [];
  578. for (var j = 0; j < status.length; j++) {
  579. if (status[j].indexOf('e') + 1) {
  580. arr.push(status[j]);
  581. }
  582. }
  583. // //console.log(arr)
  584. var dataobj = {};
  585. for (var k = 0; k < arr.length; k++) {
  586. var indexs = arr[k].indexOf(':');
  587. // //console.log(arr[k])
  588. if (k == 0) {
  589. dataobj[arr[k].slice(1, indexs).trim()] = arr[k]
  590. .substr(indexs + 1)
  591. .trim();
  592. } else {
  593. dataobj[arr[k].slice(0, indexs).trim()] = arr[k]
  594. .substr(indexs + 1)
  595. .trim();
  596. }
  597. }
  598. // //console.log(dataobj)
  599. for (var key in dataobj) {
  600. // //console.log(i)
  601. var str = "'e" + (i + 1) + "'";
  602. // //console.log(key,str);
  603. if (key == str) {
  604. if (Number(dataobj[key]) == 32767) {
  605. // reddata.push([]);
  606. } else {
  607. reddata.push(Number(dataobj[key]));
  608. }
  609. }
  610. }
  611. });
  612. regroupData.push({
  613. name: conf[i],
  614. type: 'spline',
  615. fillColor: {
  616. linearGradient: [0, 0, 0, 300],
  617. },
  618. data: reddata,
  619. });
  620. }
  621. }
  622. // console.log(timeList);
  623. this.showColumn('canvasColumnA', timeList, regroupData);
  624. },
  625. // 切换选项卡
  626. change(index) {
  627. this.page = 1;
  628. this.total = 0;
  629. this.current = index;
  630. this.status = 'loadmore';
  631. this.tableData = [];
  632. this.getEquipcontroldata();
  633. },
  634. // 获取要素实时数据
  635. async getElmentInfo() {
  636. uni.showLoading({
  637. title: '加载中',
  638. });
  639. let res = await this.$myRequest({
  640. url: '/api/api_gateway?method=xphsp.views.device_elements',
  641. data: {
  642. device_id: this.device_id,
  643. },
  644. });
  645. uni.hideLoading();
  646. var conf = res.conf.eleName.split('/');
  647. var dataList = [res.data.device_data];
  648. if (dataList.length == 0) return;
  649. this.ElementList = [];
  650. conf.forEach((item, index) => {
  651. let obj = {};
  652. if (item == '-') return;
  653. obj.name = item;
  654. let valList = dataList[0][`e${index + 1}`].split('#');
  655. obj.value = valList[0];
  656. obj.unit = valList[1];
  657. obj.time = dataList[0].uptime;
  658. this.ElementList.push(obj);
  659. });
  660. // console.log(this.ElementList)
  661. },
  662. async getEquipstatus() {
  663. uni.showLoading({
  664. title: '加载中',
  665. });
  666. this.facilityvalve = [];
  667. let res = await this.$myRequest({
  668. url: '/api/api_gateway?method=xphsp.views.device_info',
  669. data: {
  670. device_id: this.device_id,
  671. },
  672. });
  673. uni.hideLoading();
  674. var conf = res.conf.relayName;
  675. var dataobj = res.device_status;
  676. var relayNum = res.conf.relayNum;
  677. var arr = [];
  678. function numberToArray(number) {
  679. // 将数字转换为字符串
  680. let numString = number.toString();
  681. // 创建一个空数组,用于存储结果
  682. let result = [];
  683. // 遍历字符串的每个字符,并将其转换为对应的数字
  684. for (let i = 0; i < numString.length; i++) {
  685. result.push(parseInt(numString.charAt(i)));
  686. }
  687. return result;
  688. }
  689. for (var i = 0; i < dataobj.length; i++) {
  690. // if (offobj[i].indexOf("j") + 1) {
  691. arr.push(offobj[i]);
  692. // }
  693. }
  694. conf = conf.split('/');
  695. relayNum = relayNum.split('/');
  696. var arr1 = [];
  697. var reg = /\d/;
  698. let totalP = Math.ceil(conf.length / 32); //总圈数
  699. for (var i = 0; i < conf.length; i++) {
  700. var obj = {};
  701. obj.name = conf[i];
  702. // if (reg.test(conf[i])) {
  703. // obj.name2 = conf[i].slice(0, conf[i].length - 1);
  704. // } else {
  705. // obj.name2 = conf[i];
  706. // }
  707. obj.name2 = this.typename[relayNum[i]];
  708. obj.number = i;
  709. obj.type = `j${i + 1}`;
  710. obj.disabled = false;
  711. // "state": 1 继电器打开 ;"state": 0 继电器关闭
  712. // 处理开关值
  713. // J开头表示状态,总共只有32长度,超过32则从头赋值 位数多一位
  714. // 例:1和33是都在J1里面,返回值是一个二进制数 倒数第一位表示第一个 第二位表示33状态 以此类推
  715. // 根据总长度 为超过32的j赋值
  716. // 当前是循环的第几轮
  717. let baseP = Math.ceil((i + 1) / 32);
  718. if (i > 31) {
  719. dataobj[`j${i + 1}`] =
  720. dataobj[`j${(i + 1) % 32 == 0 ? 32 : (i + 1) % 32}`]; // 当前脚标/32取余 当恰好整除的时候 取32
  721. }
  722. dataobj[`j${i + 1}`] = dataobj[`j${i + 1}`].slice(-totalP); // 截取当前圈数的最后几位数字
  723. let baseOff = numberToArray(dataobj[`j${i + 1}`]); // 把当前值根据位数 转换为数组
  724. obj.off = baseOff[baseP - 1] == '0' ? false : true; // 根据当前圈数,取对应的数组的值
  725. arr1.push(obj);
  726. }
  727. for (var i = 0; i < arr1.length; i++) {
  728. if (arr1[i].name != '-') {
  729. this.facilityvalve.push(arr1[i]);
  730. }
  731. }
  732. this.facilityvalve.forEach((item) => {
  733. item.disabled = false;
  734. if (item.type == 'j9' && item.off == true) {
  735. // 判断注水泵是否打开
  736. this.mainBeng = true;
  737. }
  738. if (item.type == 'j10' && item.off == true) {
  739. // 判断施肥阀是否打开
  740. this.feiBeng = true;
  741. }
  742. });
  743. let feiNum = 0; // 记录废料桶占据通道个数,两个通道为一个肥料桶
  744. this.buttonList = [];
  745. this.facilityvalve.forEach((item, index) => {
  746. if (this.colomRoundList.indexOf(item.type) > -1) {
  747. feiNum++;
  748. this.buttonList.push(item);
  749. }
  750. if (item.type == 'j10' && item.off == true) {
  751. // 判断注水泵是否打开
  752. this.mainBeng = true;
  753. }
  754. if (item.type == 'j9' && item.off == true) {
  755. // 判断施肥阀是否打开
  756. this.feiBeng = true;
  757. }
  758. });
  759. this.feiNum = feiNum;
  760. console.log(this.facilityvalve);
  761. },
  762. async getEquipcontrol(num, state, double_order) {
  763. //设备控制
  764. uni.showLoading({
  765. title: '正在下发指令',
  766. });
  767. let res = await this.$myRequest({
  768. url: '/api/api_gateway?method=xphsp.views.control_order',
  769. data: {
  770. device_id: this.device_id,
  771. relayNum: num,
  772. relayState: state,
  773. double_order,
  774. },
  775. });
  776. uni.hideLoading();
  777. if (res.msg_code == 200) {
  778. uni.showToast({
  779. title: '指令下发成功',
  780. duration: 2000,
  781. icon: 'none',
  782. });
  783. } else {
  784. uni.showToast({
  785. title: res.msg,
  786. duration: 2000,
  787. icon: 'none',
  788. });
  789. setTimeout(() => {
  790. this.getEquipstatus();
  791. }, 2000);
  792. }
  793. },
  794. // sf_control_data
  795. // 操作记录日期
  796. changeConsoleDate(e) {
  797. this.consoleTime = e;
  798. this.tableData = [];
  799. this.page = 1;
  800. this.getEquipcontroldata();
  801. },
  802. clearContime() {
  803. this.consoleTime = {};
  804. this.tableData = [];
  805. this.page = 1;
  806. this.getEquipcontroldata();
  807. },
  808. //操作记录
  809. async getEquipcontroldata() {
  810. uni.showLoading({
  811. title: '加载中',
  812. });
  813. const { consoleTime } = this;
  814. let begin = consoleTime.startDate
  815. ? new Date(consoleTime.startDate).getTime() / 1000
  816. : '';
  817. let end = consoleTime.endDate
  818. ? new Date(consoleTime.endDate).getTime() / 1000
  819. : '';
  820. //操作记录
  821. let res = await this.$myRequest({
  822. method: 'POST',
  823. url: '/api/api_gateway?method=xphsp.views.control_log',
  824. data: {
  825. device_id: this.device_id,
  826. page_num: this.page,
  827. page_size: 15,
  828. start: begin,
  829. end: end,
  830. sys_control: this.current - 1,
  831. },
  832. });
  833. uni.hideLoading();
  834. // this.tableData = [];
  835. var record = res.result;
  836. this.tableData = [...this.tableData, ...record];
  837. this.total = res.count;
  838. if (this.page * 15 > this.total) {
  839. this.status = 'nomore';
  840. } else {
  841. this.status = 'loadmore';
  842. }
  843. console.log(this.tableData);
  844. },
  845. switchchange(e, state, item, index, isfeiButton) {
  846. // 是否是肥料开关,是的话 两个合并为一个
  847. item.disabled = true;
  848. if (isfeiButton) {
  849. item.off = e;
  850. this.changeTimeStatus(item, index);
  851. // 当前是打开
  852. if (e) {
  853. // 打开通道传1,关闭通道传0
  854. this.getEquipcontrol(state, 1, 1);
  855. // this.getEquipcontrol(state + 1, 0);
  856. } else {
  857. // this.getEquipcontrol(state + 1, 0);
  858. this.getEquipcontrol(state, 0, 1);
  859. }
  860. return;
  861. }
  862. item.off = e;
  863. if (item.type == 'j10') {
  864. // 判断注水泵是否打开
  865. this.mainBeng = e;
  866. }
  867. if (item.type == 'j9') {
  868. // 判断施肥阀是否打开
  869. this.feiBeng = e;
  870. }
  871. // if (this.colomRoundList.indexOf(item.type) > -1) {
  872. // let changeIndex = index;
  873. // if ((index + 1) % 2 == 0) {
  874. // // 偶数 往前取值
  875. // this.facilityvalve[index - 1].disabled = true;
  876. // changeIndex = index - 1;
  877. // } else if ((index + 1) % 2 == 1) {
  878. // // 基数 往后取值
  879. // this.facilityvalve[index + 1].disabled = true;
  880. // changeIndex = index + 1;
  881. // }
  882. // item.disabled = true;
  883. // this.changeTimeStatus(item, changeIndex);
  884. // this.getEquipcontrol(changeIndex, Number(!e));
  885. // } else {
  886. // }
  887. item.disabled = true;
  888. this.changeTimeStatus(item, index);
  889. //console.log(Number(e), state);
  890. this.getEquipcontrol(state, Number(e));
  891. },
  892. currentchange(e) {
  893. //页码
  894. if (this.type == 0) {
  895. this.pageDialog = e;
  896. } else {
  897. this.page = e;
  898. }
  899. this.getEquipcontroldata(this.type);
  900. },
  901. },
  902. onReachBottom() {
  903. if (this.current != 0 && this.status == 'loadmore') {
  904. this.page++;
  905. this.getEquipcontroldata();
  906. }
  907. },
  908. onLoad(option) {
  909. let deviceItem = JSON.parse(option.shebei);
  910. this.device_id = deviceItem.device_id;
  911. this.getEquipstatus();
  912. this.getElmentInfo();
  913. this.getEquipcontroldata();
  914. },
  915. };
  916. </script>
  917. <style scoped lang="less">
  918. .circleAnm {
  919. animation: ancirle 1s linear infinite;
  920. }
  921. // 旋转
  922. @keyframes ancirle {
  923. 0% {
  924. transform: rotate(360deg);
  925. }
  926. 100% {
  927. transform: rotate(0);
  928. }
  929. }
  930. .box {
  931. position: relative;
  932. width: 100%;
  933. min-height: 100vh;
  934. overflow: auto;
  935. }
  936. .bigBox {
  937. width: 100%;
  938. }
  939. .bigOpen {
  940. height: 100vh;
  941. }
  942. ::v-deep .u-flex {
  943. display: flex;
  944. justify-content: center;
  945. }
  946. .topInfo {
  947. background: #14a478;
  948. color: #fff;
  949. font-size: 28rpx;
  950. padding-bottom: 32rpx;
  951. box-sizing: border-box;
  952. border-bottom-left-radius: 16rpx;
  953. border-bottom-right-radius: 16rpx;
  954. .u-col {
  955. box-sizing: border-box;
  956. margin-top: 32rpx;
  957. .item {
  958. text-align: center;
  959. view:first-child {
  960. font-size: 40rpx;
  961. }
  962. view:nth-child(2) {
  963. font-size: 24rpx;
  964. line-height: 40rpx;
  965. opacity: 0.72;
  966. }
  967. }
  968. }
  969. }
  970. .readmore {
  971. text-align: center;
  972. font-size: 26rpx;
  973. line-height: 40rpx;
  974. margin-top: 32rpx;
  975. color: #93ffde;
  976. .u-icon {
  977. margin-left: 15rpx;
  978. }
  979. }
  980. .histimeBox {
  981. display: flex;
  982. align-items: center;
  983. justify-content: space-between;
  984. height: 56rpx;
  985. padding: 6rpx 24rpx;
  986. box-sizing: border-box;
  987. border-radius: 8rpx;
  988. margin-top: 54rpx;
  989. border: 2rpx solid var(--neutral-color-border-light, #e4edea);
  990. .u-icon {
  991. z-index: 10;
  992. }
  993. .time {
  994. width: 280rpx;
  995. color: #c1c1c1;
  996. }
  997. view {
  998. color: #333333;
  999. text-align: center;
  1000. }
  1001. }
  1002. .consoleBox {
  1003. position: relative;
  1004. max-height: 75vh;
  1005. padding-bottom: 80rpx;
  1006. overflow: auto;
  1007. .u-row {
  1008. box-sizing: border-box;
  1009. .u-col {
  1010. box-sizing: border-box;
  1011. }
  1012. }
  1013. .u-btn {
  1014. position: absolute;
  1015. bottom: 0;
  1016. left: 0;
  1017. right: 0;
  1018. background: #14a478;
  1019. }
  1020. .swichBox {
  1021. position: relative;
  1022. padding: 32rpx;
  1023. overflow: hidden;
  1024. .preSwich {
  1025. display: flex;
  1026. align-items: center;
  1027. justify-content: space-between;
  1028. padding: 24rpx 18rpx;
  1029. border-radius: 8rpx;
  1030. background: #eff2fa;
  1031. margin-bottom: 32rpx;
  1032. view {
  1033. color: #333333;
  1034. font-size: 28rpx;
  1035. }
  1036. }
  1037. }
  1038. }
  1039. .hisBox {
  1040. position: relative;
  1041. width: 100vw;
  1042. padding-bottom: 100rpx;
  1043. box-sizing: border-box;
  1044. overflow-y: scroll;
  1045. .axiosBox {
  1046. position: relative;
  1047. padding: 48rpx 32rpx;
  1048. .title {
  1049. color: #333333;
  1050. font-size: 28rpx;
  1051. font-weight: 700;
  1052. }
  1053. .chartBox {
  1054. position: relative;
  1055. margin-top: 32rpx;
  1056. height: 800rpx;
  1057. overflow: hidden;
  1058. #canvasColumnA {
  1059. width: 100%;
  1060. height: 800rpx;
  1061. }
  1062. }
  1063. }
  1064. .readmoreHIs {
  1065. position: absolute;
  1066. bottom: 60rpx;
  1067. left: 50%;
  1068. transform: translate(-50%);
  1069. color: #14a478;
  1070. z-index: 5;
  1071. }
  1072. }
  1073. .devicePhoto {
  1074. padding: 32rpx;
  1075. .titleBox {
  1076. display: flex;
  1077. align-items: center;
  1078. justify-content: space-between;
  1079. .btn {
  1080. padding: 10rpx 14rpx;
  1081. border-radius: 8rpx;
  1082. background: #14a478;
  1083. color: #fff;
  1084. font-size: 28rpx;
  1085. }
  1086. }
  1087. .main {
  1088. position: relative;
  1089. width: 678rpx;
  1090. height: 612rpx;
  1091. margin-top: 10px;
  1092. .mainContent {
  1093. position: absolute;
  1094. left: 50%;
  1095. transform: translateX(-50%);
  1096. width: 678rpx;
  1097. top: 10rpx;
  1098. height: 602rpx;
  1099. z-index: 1;
  1100. }
  1101. .sourceBox {
  1102. position: absolute;
  1103. left: 20rpx;
  1104. z-index: 2;
  1105. display: flex;
  1106. align-items: center;
  1107. justify-content: center;
  1108. width: 112rpx;
  1109. height: 112rpx;
  1110. background: #e3fdff;
  1111. border-radius: 112rpx;
  1112. color: #fff;
  1113. view {
  1114. width: 85rpx;
  1115. height: 85rpx;
  1116. background: #1890ff;
  1117. border-radius: 85rpx;
  1118. text-align: center;
  1119. line-height: 85rpx;
  1120. font-size: 28rpx;
  1121. }
  1122. }
  1123. .colList {
  1124. position: absolute;
  1125. z-index: 2;
  1126. top: 44rpx;
  1127. left: 154rpx;
  1128. width: 528rpx;
  1129. display: flex;
  1130. justify-content: center;
  1131. overflow: hidden;
  1132. .preClo {
  1133. position: relative;
  1134. float: left;
  1135. width: 88rpx;
  1136. // margin-left: 40rpx;
  1137. view {
  1138. text-align: center;
  1139. color: #333333;
  1140. font-size: 28rpx;
  1141. margin-bottom: 20rpx;
  1142. }
  1143. image {
  1144. width: 88rpx;
  1145. height: 272rpx;
  1146. }
  1147. .shanBox {
  1148. position: absolute;
  1149. width: 64rpx;
  1150. height: 64rpx;
  1151. top: 116rpx;
  1152. left: 50%;
  1153. transform: translateX(-50%);
  1154. z-index: 2;
  1155. image {
  1156. width: 64rpx;
  1157. height: 64rpx;
  1158. }
  1159. }
  1160. .jiaoBtn {
  1161. position: absolute;
  1162. width: 64rpx;
  1163. height: 32rpx;
  1164. top: 72rpx;
  1165. left: 50%;
  1166. transform: translateX(-50%);
  1167. z-index: 2;
  1168. .u-switch {
  1169. width: 64rpx;
  1170. height: 32rpx;
  1171. ::v-deep .u-switch__node {
  1172. width: 28rpx !important;
  1173. height: 28rpx !important;
  1174. top: 2rpx !important;
  1175. }
  1176. ::v-deep .u-switch__loading {
  1177. height: 20rpx !important;
  1178. }
  1179. }
  1180. ::v-deep .u-switch--on .u-switch__node {
  1181. transform: translateX(36rpx) !important;
  1182. }
  1183. }
  1184. .btnBox {
  1185. position: absolute;
  1186. width: 66rpx;
  1187. height: 72rpx;
  1188. bottom: 40rpx;
  1189. left: 22rpx;
  1190. z-index: 2;
  1191. image {
  1192. width: 66rpx;
  1193. height: 72rpx;
  1194. }
  1195. }
  1196. }
  1197. }
  1198. .benList {
  1199. position: absolute;
  1200. width: 678rpx;
  1201. left: 50%;
  1202. transform: translateX(-50%);
  1203. top: 610rpx;
  1204. .preBen {
  1205. float: left;
  1206. text-align: center;
  1207. width: 20%;
  1208. .daoguan {
  1209. width: 20rpx;
  1210. height: 40rpx;
  1211. }
  1212. .info {
  1213. color: #333333;
  1214. font-size: 12px;
  1215. font-weight: 400;
  1216. }
  1217. .status {
  1218. width: 76rpx;
  1219. height: 100rpx;
  1220. margin-top: 10rpx;
  1221. }
  1222. }
  1223. }
  1224. .lineExit {
  1225. }
  1226. .exit {
  1227. position: absolute;
  1228. width: 22rpx;
  1229. height: 20rpx;
  1230. top: 360rpx;
  1231. right: 252rpx;
  1232. z-index: 2;
  1233. image {
  1234. width: 22rpx;
  1235. height: 20rpx;
  1236. }
  1237. }
  1238. .warterIn {
  1239. position: absolute;
  1240. width: 66rpx;
  1241. height: 72rpx;
  1242. top: 190rpx;
  1243. left: 52rpx;
  1244. z-index: 3;
  1245. image {
  1246. width: 66rpx;
  1247. height: 72rpx;
  1248. }
  1249. }
  1250. .warterLight {
  1251. position: absolute;
  1252. width: 72rpx;
  1253. height: 48rpx;
  1254. top: 506rpx;
  1255. left: 110rpx;
  1256. z-index: 3;
  1257. image {
  1258. width: 72rpx;
  1259. height: 48rpx;
  1260. }
  1261. }
  1262. .feiLight {
  1263. position: absolute;
  1264. width: 72rpx;
  1265. height: 66rpx;
  1266. top: 424rpx;
  1267. right: 140rpx;
  1268. z-index: 3;
  1269. image {
  1270. width: 72rpx;
  1271. height: 66rpx;
  1272. }
  1273. }
  1274. .kongBox {
  1275. position: absolute;
  1276. width: 84rpx;
  1277. height: 108rpx;
  1278. top: 390rpx;
  1279. right: 228rpx;
  1280. z-index: 3;
  1281. image {
  1282. width: 84rpx;
  1283. height: 108rpx;
  1284. }
  1285. }
  1286. .fengBox {
  1287. position: absolute;
  1288. right: 12rpx;
  1289. top: 270rpx;
  1290. width: 55rpx;
  1291. height: 44rpx;
  1292. z-index: 2;
  1293. .relativeBox {
  1294. position: relative;
  1295. width: 100%;
  1296. height: 100%;
  1297. image:nth-child(1) {
  1298. width: 16rpx;
  1299. height: 32rpx;
  1300. }
  1301. image:nth-child(2) {
  1302. position: absolute;
  1303. right: 0;
  1304. top: -6rpx;
  1305. width: 44rpx;
  1306. height: 44rpx;
  1307. }
  1308. }
  1309. }
  1310. }
  1311. }
  1312. .consoleList {
  1313. padding: 0 32rpx;
  1314. .histimeBox {
  1315. margin: 32rpx 0;
  1316. }
  1317. .tableTitle {
  1318. background: #e8f3f0;
  1319. color: #333;
  1320. font-weight: 600;
  1321. }
  1322. .tableList {
  1323. font-size: 28rpx;
  1324. height: 78rpx;
  1325. color: #666666;
  1326. display: flex;
  1327. justify-content: space-between;
  1328. align-items: center;
  1329. border-bottom: 2rpx solid var(--neutral-color-border-base, #dce6e3);
  1330. view {
  1331. text-align: center;
  1332. }
  1333. .success {
  1334. color: #14a478;
  1335. }
  1336. .error {
  1337. color: #ff5951;
  1338. }
  1339. view:nth-child(1) {
  1340. width: 120rpx;
  1341. text-align: left;
  1342. }
  1343. view:nth-child(2) {
  1344. width: 280rpx;
  1345. }
  1346. view:nth-child(3) {
  1347. width: 280rpx;
  1348. }
  1349. }
  1350. }
  1351. </style>