details.vue 34 KB

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