detail.vue 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427
  1. <template>
  2. <view class="bigBox">
  3. <u-tabs :list="list" :is-scroll="false" :current="current" @change="change" active-color="#14A478"></u-tabs>
  4. <view class="currentBox">
  5. <view v-if="current == 0" class="infoBox">
  6. <view :class="['info',equipInfo.is_online==1?'on':'off']">
  7. <p @click="copy(equipInfo.imei)">设备ID:{{equipInfo.imei}}
  8. <image src="http://www.hnyfwlw.com:8006/bigdata_app/image/environment/fuzhi.png" mode=""
  9. class="tishi">
  10. </image>
  11. </p>
  12. <p>设备名称:{{equipInfo.device_name==""?"无":equipInfo.device_name}}</p>
  13. <p>最新上报时间:{{equipInfo.addtime | timeFormat}}</p>
  14. <p>最新地址:{{equipInfo.address}}</p>
  15. <p class="fillin">诱芯名称:{{equipInfo.decoy}}</p>
  16. <!-- <p @click="glass_show=true">诱芯更换时间:<span style="margin:0 20rpx;">{{yxchangetime}}</span><u-icon
  17. name="edit-pen" color="#f0ad4e" size="28"></u-icon></p> -->
  18. <p>诱芯到期时间:{{equipInfo.xy_expire}}</p>
  19. <!-- <u-calendar v-model="glass_show" mode="date" :max-date="date" @change="timeChange"></u-calendar>
  20. <u-calendar v-model="glass_showtwo" mode="date" :max-date="date" @change="timeChangetwo"></u-calendar> -->
  21. </view>
  22. <view class="cardInfo">
  23. <text class="title">设备控制</text>
  24. <view class="controlCard">
  25. <view class="preBtn" v-for="btn in btnList" :key="btn.class">
  26. <view :class="['btnBox' , btn.class]" @click="btnFun(btn.code)">
  27. <text :class="btn.icon"></text>
  28. </view>
  29. <view>{{btn.text}}</view>
  30. </view>
  31. </view>
  32. </view>
  33. <view class="cardInfo">
  34. <text class="title">监测数据</text>
  35. <view class="controlCard noBg">
  36. <view class="fleBox">
  37. <view class="preInfo" v-for="btn in dataList" :key="btn.icon">
  38. <view class="btnBox">
  39. <text :class="btn.icon"></text>
  40. </view>
  41. <view class="textBox">
  42. <view>
  43. {{newDataObj[btn.unit]}}
  44. </view>
  45. <view class="name">{{btn.text}}</view>
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. </view>
  51. <view class="cardInfo">
  52. <text class="title">设备信息</text>
  53. <view class="controlCard noBg">
  54. <u-cell-group class="widthSet">
  55. <u-cell-item v-for="btn in deviceDataList" :key="btn.icon" :title="btn.text"
  56. :value="deviceObj[btn.key]" :arrow="false" :border-bottom="true"></u-cell-item>
  57. </u-cell-group>
  58. </view>
  59. </view>
  60. </view>
  61. <!-- 数据统计 -->
  62. <view v-if="current == 1" class="infoBox">
  63. <view class="cardInfo">
  64. <text class="title">统计数据</text>
  65. <view class="chartBox">
  66. <view class="timeBox">
  67. <u-icon name="calendar" size="30" class="iconBox"></u-icon>
  68. <view class="text" @click="showRangeTime = true">{{photoTimeRangeText}}</view>
  69. <u-icon name="arrow-right" v-if="photoTimeRangeText == '请选择日期'"></u-icon>
  70. <u-icon name="close" v-else @click="clearTimeFun('chart')"></u-icon>
  71. <u-calendar v-model="showRangeTime" mode="range" @change="(e) => changePhotoTime(e, 'chart')"></u-calendar>
  72. </view>
  73. <canvas v-if="showCanvas && !showRangeTime" canvas-id="canvasColumnA" id="canvasColumnA" class="charts"
  74. @touchstart="touchLineA($event)" @touchmove="moveLineA($event)" @touchend="touchEndLineA($event)"
  75. disable-scroll=true
  76. :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}">
  77. </canvas>
  78. <view class="noEmpty" v-else>
  79. 暂无数据
  80. </view>
  81. </view>
  82. </view>
  83. <view class="cardInfo">
  84. <text class="title">虫情分析</text>
  85. <view class="chartBox">
  86. <view class="pestInfo">
  87. <view class="pest">
  88. <text>害虫种类</text>
  89. <text class="name">{{analyInfo.decoy}}</text>
  90. </view>
  91. <view class="pest">
  92. <text>日杀虫数量</text>
  93. <text class="name">{{analyInfo.count}}头</text>
  94. </view>
  95. <view class="pest">
  96. <text>处理意见</text>
  97. <text class="name">{{analyInfo.advice}}</text>
  98. </view>
  99. </view>
  100. <view class="pestStatus">
  101. <view :class="['block', analyInfo.count < 30 ? 'active' : '']">
  102. <view class="iconBox green">
  103. <text class="yficonfont icon-small"></text>
  104. </view>
  105. <view class="blueText">
  106. <view>平静期</view>
  107. <view>0-30</view>
  108. </view>
  109. </view>
  110. <view :class="['block', analyInfo.count >= 30 && analyInfo.count < 60? 'active' : '']">
  111. <view class="iconBox yellow">
  112. <text class="yficonfont icon-middle"></text>
  113. </view>
  114. <view class="yellowText">
  115. <view>始发期</view>
  116. <view>30-60</view>
  117. </view>
  118. </view>
  119. <view :class="['block', analyInfo.count >= 60 ? 'active' : '']">
  120. <view class="iconBox danger">
  121. <text class="yficonfont icon-most"></text>
  122. </view>
  123. <view class="redText">
  124. <view>爆发期</view>
  125. <view>≥60</view>
  126. </view>
  127. </view>
  128. </view>
  129. </view>
  130. </view>
  131. </view>
  132. <!-- 图片列表 -->
  133. <view v-if="current == 2" class="infoBox">
  134. <view class="imgList">
  135. <view class="preImg" v-for="(img, index) in photoList" :key="img.addtime">
  136. <text class="text">{{img.addtime}}</text>
  137. <u-image width="100%" height="226rpx" :src="img.addr" @click="examine(index)"></u-image>
  138. </view>
  139. <u-loadmore class="loadBox" :status="loadStatus" :icon-type="iconType" :load-text="loadText"
  140. @loadmore="loadMore" />
  141. </view>
  142. <view class="timeBox">
  143. <u-icon name="calendar" size="30" class="iconBox"></u-icon>
  144. <view class="text" @click="showRangeTime = true">{{photoTimeRangeText}}</view>
  145. <u-icon name="arrow-right" v-if="photoTimeRangeText == '请选择日期'"></u-icon>
  146. <u-icon name="close" v-else @click="clearTimeFun('photo')"></u-icon>
  147. <u-calendar v-if="showRangeTime" v-model="showRangeTime" mode="range" @change="e => changePhotoTime(e, 'photo')"></u-calendar>
  148. </view>
  149. </view>
  150. <!-- 设备控制 -->
  151. <view v-if="current == 3" class="bgColor">
  152. <u-form :model="equipContrlForm1" :label-width="180">
  153. <view class="" v-if="myuser_type">
  154. <u-divider>管理员操作</u-divider>
  155. <u-form-item label="升级文件地址" :label-width="220">
  156. <u-input v-model="ota_url" />
  157. </u-form-item>
  158. <u-button size="mini" type="primary" @click="equipBtnControl('reboot')">重启</u-button>
  159. <u-button size="mini" class="btn" type="primary"
  160. @click="equipBtnControl('update')">升级</u-button>
  161. <u-divider>设备控制</u-divider>
  162. </view>
  163. <!-- <u-form-item label="设备名称"><u-input v-model="equipContrlForm1.devname" /></u-form-item> -->
  164. <u-form-item label="高压包开关状态" :label-width="240">
  165. <u-radio-group v-model="equipContrlForm1.dev_work_onoff">
  166. <u-radio :name="1">开</u-radio>
  167. <u-radio :name="0">关</u-radio>
  168. </u-radio-group>
  169. </u-form-item>
  170. <u-form-item label="工作模式" :label-width="240">
  171. <u-radio-group v-model="equipContrlForm1.dev_work_mode">
  172. <u-radio :name="1">自动</u-radio>
  173. <u-radio :name="2">手动</u-radio>
  174. <u-radio :name="3">定时</u-radio>
  175. </u-radio-group>
  176. </u-form-item>
  177. <u-form-item label="定时时长" :label-width="240" v-if="equipContrlForm1.dev_work_mode == 3">
  178. <text @click="equipContrlForm1.show_st= true">{{equipContrlForm1.st}}</text>-
  179. <text @click="equipContrlForm1.show_et= true">{{equipContrlForm1.et}}</text>
  180. <u-picker mode="time" v-model="equipContrlForm1.show_st" :default-time="equipContrlForm1.st"
  181. :params="params" @confirm="(e) => changeControlTime(e, 'st')"></u-picker>
  182. <u-picker mode="time" v-model="equipContrlForm1.show_et" :default-time="equipContrlForm1.et"
  183. :params="params" @confirm="(e) => changeControlTime(e, 'et')"></u-picker>
  184. </u-form-item>
  185. <!-- <u-form-item label="SIM卡号" :label-width="200">
  186. <u-input v-model="equipContrlForm1.sim" />
  187. </u-form-item> -->
  188. <u-form-item label="心跳间隔(S)" :label-width="200">
  189. <u-input v-model="equipContrlForm1.heart_time" type="number" />
  190. </u-form-item>
  191. <u-form-item label="太阳能电压阈值(V)" :label-width="280">
  192. <u-input v-model="equipContrlForm1.solar_threshold" type="number" />
  193. </u-form-item>
  194. <u-form-item label="太阳能电压最大值(V)" :label-width="300">
  195. <u-input v-model="equipContrlForm1.solarmax" type="number" />
  196. </u-form-item>
  197. <u-form-item label="数据上传频率(min)" :label-width="300">
  198. <u-input v-model="equipContrlForm1.upload_time" type="number" />
  199. </u-form-item>
  200. <u-button size="medium " type="primary" @click="equipControlSubm">保存</u-button>
  201. </u-form>
  202. </view>
  203. <!-- 拍照定时 -->
  204. <u-modal v-model="photoTimeLayer" width="80%" :async-close="true" :show-cancel-button="true"
  205. @confirm="devicePhotoTime">
  206. <view class="slot-content">
  207. <view class="expireBox">
  208. <u-tag text="注意:00:00为不拍照" mode="dark" type="warning"/>
  209. <u-form>
  210. <u-form-item :label="`时间${index + 1}`" :label-width="180"
  211. v-for="(time, index) in photoTimeArray" :key="time.key">
  212. <text @click="time.show = true">{{time.value}}</text>
  213. <!-- <u-button size="mini" type="error" class="delBtn"
  214. @click="removeTime(index)">删除</u-button> -->
  215. <u-picker mode="time" v-model="time.show" :default-time="time.value" :params="params"
  216. @confirm="(e) => changeSnapTime(e, time.key, index)"></u-picker>
  217. </u-form-item>
  218. <!-- <u-button size="mini" type="primary" @click="addTime(photoTimeArray.length)">添加</u-button> -->
  219. </u-form>
  220. </view>
  221. </view>
  222. </u-modal>
  223. <!-- 信息素弹框 -->
  224. <u-modal v-model="expireInfoLayer" width="90%" :async-close="true" :show-cancel-button="true"
  225. @confirm="changeExpireFun">
  226. <view class="slot-content">
  227. <view class="expireBox">
  228. <u-form ref="uForm">
  229. <u-form-item label="信息素名称" :label-width="180">
  230. <u-input v-model="decoy" type="text" :border="true" placeholder="请输入信息素名称" />
  231. </u-form-item>
  232. <u-form-item label="新信息素可使用时间" :label-width="280">
  233. <u-radio-group v-model="xy_expire_time">
  234. <u-radio v-for="(item, index) in expireTimeList" :key="index" :name="item.value">
  235. {{item.label}}
  236. </u-radio>
  237. </u-radio-group>
  238. </u-form-item>
  239. </u-form>
  240. </view>
  241. </view>
  242. </u-modal>
  243. </view>
  244. </view>
  245. </template>
  246. <script>
  247. import uCharts from '../../../../components/js_sdk/u-charts/u-charts/u-charts.js';
  248. var canvaColumnA = null;
  249. export default {
  250. data() {
  251. return {
  252. myuser_type: '',
  253. equipInfoImei: '',
  254. equipInfo_d_id: '',
  255. btnList: [{
  256. text: '更换信息素',
  257. icon: 'yficonfont icon-weimingming-34',
  258. class: 'green',
  259. code: 'changeInfo'
  260. }],
  261. list: [{
  262. name: '基本信息'
  263. }],
  264. current: 0,
  265. equipInfo: {},
  266. dataList: [{
  267. text: '空气温度', // 中文
  268. unit: 'air_temp', // 对应字段
  269. data: '',
  270. icon: 'yficonfont icon-kongqiwendu', // iconclass名称
  271. },
  272. {
  273. text: '空气湿度',
  274. unit: 'air_humi',
  275. data: '',
  276. icon: 'yficonfont icon-shuizhi',
  277. },
  278. {
  279. text: '风力',
  280. unit: 'wind_force',
  281. isSmall: true,
  282. data: '',
  283. icon: 'yficonfont icon-fengli',
  284. },
  285. {
  286. text: '风向',
  287. unit: 'wind_dir',
  288. isSmall: true,
  289. data: '',
  290. icon: 'yficonfont icon-fengxiang',
  291. },
  292. {
  293. text: '害虫数量',
  294. unit: 'bugcnt',
  295. data: '',
  296. icon: 'yficonfont icon-chouchongbug',
  297. },
  298. {
  299. text: '光照强度',
  300. unit: 'light',
  301. data: '',
  302. isSmall: true,
  303. icon: 'yficonfont icon-qingtian',
  304. },
  305. {
  306. text: '降雨',
  307. unit: 'rain_status',
  308. data: '',
  309. icon: 'yficonfont icon-yu',
  310. },
  311. {
  312. text: '电池电量',
  313. unit: 'bat_level',
  314. data: '',
  315. icon: 'yficonfont icon-80dianliang',
  316. },
  317. {
  318. text: '信号强度',
  319. unit: 'gprs',
  320. data: '',
  321. icon: 'yficonfont icon-wifi',
  322. },
  323. {
  324. text: '定位信噪比',
  325. unit: 'cn0',
  326. data: '',
  327. isSmall: true,
  328. icon: 'yficonfont icon-dingwei1',
  329. },
  330. {
  331. text: '太阳能电压',
  332. unit: 'solar_voltage',
  333. data: '',
  334. icon: 'yficonfont icon-guangfuzujianshuliang',
  335. },
  336. {
  337. text: '蓄电池电压',
  338. unit: 'bat_val',
  339. data: '',
  340. icon: 'yficonfont icon-xudianchi',
  341. },
  342. ],
  343. dataLoading: true,
  344. newDataObj: {},
  345. deviceDataList: [{
  346. text: '设备名',
  347. key: 'devname',
  348. },
  349. {
  350. text: '设备版本号',
  351. key: 'version',
  352. },
  353. {
  354. text: '心跳间隔',
  355. key: 'heart_time',
  356. },
  357. {
  358. text: '太阳能电压阀值',
  359. key: 'solar_threshold',
  360. },
  361. {
  362. text: '太阳能电压最大值',
  363. key: 'solarmax',
  364. },
  365. {
  366. text: '数据上传频率',
  367. key: 'upload_time',
  368. },
  369. {
  370. text: '工作模式',
  371. key: 'dev_work_mode',
  372. },
  373. {
  374. text: '定时模式时间',
  375. key: 'dev_work_time',
  376. },
  377. {
  378. text: '高压包开关状态',
  379. key: 'dev_work_onoff',
  380. },
  381. {
  382. text: 'SIM卡号',
  383. key: 'sim',
  384. },
  385. ],
  386. deviceLoading: true,
  387. deviceObj: {},
  388. photoTimeArray: [],
  389. photoTimeLayer: false,
  390. expireInfoLayer: false,
  391. xy_expire_time: 2, // 时间
  392. decoy: '', // 诱芯名称
  393. expireTimeList: [{
  394. label: '1个月',
  395. value: 1,
  396. },
  397. {
  398. label: '2个月',
  399. value: 2,
  400. },
  401. {
  402. label: '3个月',
  403. value: 3,
  404. },
  405. {
  406. label: '4个月',
  407. value: 4,
  408. },
  409. ],
  410. params: {
  411. year: false,
  412. month: false,
  413. day: false,
  414. hour: true,
  415. minute: true,
  416. second: false
  417. },
  418. //设备控制
  419. equipContrlForm1: {
  420. devname: '',
  421. heart_time: '',
  422. solar_threshold: '',
  423. solarmax: '',
  424. upload_time: 0,
  425. dev_work_mode: '',
  426. dev_work_timeArray: '',
  427. dev_work_onoff: '',
  428. sim: '',
  429. et: '',
  430. st: '',
  431. show_st: false,
  432. show_et: false,
  433. // st: '', //时控开始时间
  434. // et: '', //时控结束时间
  435. // dat_f: null ,//数据上传时间间隔
  436. // ds:''//开关,1开机,0关机
  437. },
  438. ota_url: '',
  439. photoList: [],
  440. photoLoading: true,
  441. showRangeTime: false,
  442. photoTimeRange: '',
  443. photoTimeRangeText: '请选择日期',
  444. page: 1,
  445. total: 0,
  446. loadStatus: '',
  447. iconType: 'flower',
  448. loadText: {
  449. loadmore: '点击加载更多',
  450. loading: '努力加载中',
  451. nomore: '没有更多啦~'
  452. },
  453. cWidth: '400',
  454. cHeight: '400',
  455. pixelRatio: 1,
  456. showCanvas: false,
  457. analyInfo:{
  458. decoy:'',
  459. count:''
  460. }
  461. };
  462. },
  463. onLoad(option) {
  464. this.cWidth = uni.upx2px(650);
  465. this.cHeight = uni.upx2px(500);
  466. uni.getStorage({
  467. key: "jurisdiction",
  468. success: (res) => {
  469. let items = JSON.parse(res.data).filter((item) => {
  470. return item.pur_id == 36
  471. })
  472. var arr = items[0].children
  473. for (var i = 0; i < arr.length; i++) {
  474. switch (arr[i].pur_id) {
  475. case 338:
  476. let newChildren = arr[i].children;
  477. let hasImg = newChildren.some((item) => {
  478. return item.pur_id == 341
  479. })
  480. let hasControl = newChildren.some((item) => {
  481. return item.pur_id == 340
  482. })
  483. if (hasImg) {
  484. this.list.push({
  485. name: '数据分析'
  486. }, {
  487. name: '图片列表'
  488. })
  489. this.btnList.push({
  490. text: '拍照定时',
  491. icon: 'yficonfont icon-dingshi',
  492. class: 'blue',
  493. code: 'photoTime'
  494. }, {
  495. text: '一键拍照',
  496. icon: 'yficonfont icon-paizhao-xianxing',
  497. class: 'yellow',
  498. code: 'tackPhoto'
  499. })
  500. }
  501. if (hasControl) {
  502. this.list.push({
  503. name: '设备控制'
  504. });
  505. this.btnList.push({
  506. text: '设备清虫',
  507. icon: 'yficonfont icon-chouchongbug',
  508. class: 'danger',
  509. code: 'clear'
  510. })
  511. }
  512. break
  513. }
  514. }
  515. }
  516. })
  517. this.equipInfoImei = JSON.parse(option.detail).imei;
  518. this.equipInfo_d_id = JSON.parse(option.detail).d_id;
  519. this.getEquipInfo();
  520. // console.log(this.equipInfo);
  521. this.getData();
  522. this.getDeviceData();
  523. uni.getStorage({
  524. key: "myuser_type",
  525. success: (res) => {
  526. if (Number(res.data) == 1) {
  527. this.myuser_type = true
  528. }
  529. }
  530. })
  531. },
  532. methods: {
  533. // 害虫统计折线图
  534. showColumn(id, xtitle, xinfo) {
  535. var _self = this;
  536. canvaColumnA = new uCharts({
  537. canvasId: id,
  538. type: 'line',
  539. legend: {
  540. position: "top"
  541. },
  542. fontSize: 11,
  543. background: '#FFFFFF',
  544. pixelRatio: 1,
  545. animation: true,
  546. dataLabel: false,
  547. categories: xtitle,
  548. series: xinfo,
  549. enableScroll: true, //开启图表拖拽功能
  550. xAxis: {
  551. disableGrid: true,
  552. type: 'grid',
  553. gridType: 'dash',
  554. itemCount: 4, //x轴单屏显示数据的数量,默认为5个
  555. scrollShow: true, //新增是否显示滚动条,默认false
  556. // scrollAlign: 'left', //滚动条初始位置
  557. scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
  558. scrollColor: '#DEE7F7', //默认为 #A6A6A6
  559. },
  560. width: _self.cWidth * 1,
  561. height: _self.cHeight * 1,
  562. yAxis: {},
  563. extra: {
  564. line: {
  565. type: 'curve'
  566. }
  567. }
  568. });
  569. },
  570. touchLineA(e) {
  571. console.log(e)
  572. canvaColumnA.scrollStart(e);
  573. },
  574. moveLineA(e) {
  575. canvaColumnA.scroll(e);
  576. },
  577. touchEndLineA(e) {
  578. canvaColumnA.scrollEnd(e);
  579. //下面是toolTip事件,如果滚动后不需要显示,可不填写
  580. canvaColumnA.showToolTip(e, {
  581. format: function(item, category) {
  582. return category + ' ' + item.name + ':' + item.data
  583. }
  584. });
  585. },
  586. async lineChartPest(type) {
  587. let {
  588. photoTimeRange
  589. } = this;
  590. let res = await this.$myRequest({
  591. method: 'post',
  592. url: '/api/api_gateway?method=lpsxy.views.pest_count',
  593. data: {
  594. d_id: this.equipInfo_d_id,
  595. start: photoTimeRange ? (photoTimeRange[0] / 1000) : '',
  596. end: photoTimeRange ? (photoTimeRange[1] / 1000) : '',
  597. },
  598. })
  599. if (res.length > 0) {
  600. this.showCanvas = true;
  601. let name = [];
  602. let ydata = [];
  603. res.forEach(item => {
  604. name.push(item.date);
  605. ydata.push(item.total);
  606. });
  607. var obj = [{
  608. name: '诱虫数量',
  609. data: ydata,
  610. color: '#FF3F3F'
  611. }]
  612. if (type == 'search') {
  613. // 当前是搜索
  614. this.showColumn("canvasColumnA", name, obj)
  615. } else {
  616. this.showColumn("canvasColumnA", name, obj)
  617. }
  618. } else {
  619. this.showCanvas = false;
  620. }
  621. },
  622. examine(index) {
  623. var imgarr = []
  624. for (var i = 0; i < this.photoList.length; i++) {
  625. imgarr.push(this.photoList[i].addr)
  626. }
  627. // console.log(imgarr)
  628. uni.previewImage({
  629. urls: imgarr,
  630. current: index
  631. });
  632. },
  633. async getEquipInfo() {
  634. let res = await this.$myRequest({
  635. method: 'post',
  636. url: '/api/api_gateway?method=forecast.worm_lamp.lamp_list',
  637. data: {
  638. device_id: this.equipInfoImei,
  639. page: 1,
  640. page_size: 10,
  641. device_model: 0,
  642. device_type_id: 25
  643. },
  644. })
  645. console.log(res);
  646. // console.log(res.data.data);
  647. this.equipInfo = res.data[0];
  648. },
  649. async getAnsyInfo() {
  650. let res = await this.$myRequest({
  651. method: 'post',
  652. url: '/api/api_gateway?method=lpsxy.views.pest_info',
  653. data: {
  654. d_id: this.equipInfo_d_id,
  655. },
  656. })
  657. console.log(res);
  658. // console.log(res.data.data);
  659. this.analyInfo = res;
  660. },
  661. btnFun(code) {
  662. switch (code) {
  663. case 'clear':
  664. this.takePhoto(3);
  665. break;
  666. case 'tackPhoto':
  667. this.takePhoto(1);
  668. break;
  669. case 'photoTime':
  670. this.getPhotoTime();
  671. this.photoTimeLayer = true;
  672. break;
  673. case 'changeInfo':
  674. this.decoy = '';
  675. this.xy_expire_time = 2;
  676. this.expireInfoLayer = true;
  677. break;
  678. default:
  679. break;
  680. }
  681. // if(code == 'clear') {
  682. // this.takePhoto(3)
  683. // }
  684. },
  685. async getData() {
  686. let res = await this.$myRequest({
  687. method: 'post',
  688. url: '/api/api_gateway?method=lpsxy.views.monitor_data',
  689. data: {
  690. device_id: this.equipInfoImei,
  691. },
  692. })
  693. console.log(res);
  694. // console.log(res.data.data);
  695. this.newDataObj = res;
  696. },
  697. async getDeviceData() {
  698. let res = await this.$myRequest({
  699. method: 'post',
  700. url: '/api/api_gateway?method=lpsxy.views.device_config',
  701. data: {
  702. d_id: this.equipInfo_d_id,
  703. },
  704. })
  705. console.log(res);
  706. // console.log(res.data.data);
  707. this.deviceObj = res;
  708. },
  709. // 获取当前拍照时间控制
  710. async getPhotoTime() {
  711. this.photoTimeLayer = true;
  712. this.photoTimeArray = [];
  713. let res = await this.$myRequest({
  714. method: 'POST',
  715. url: '/api/api_gateway?method=lpsxy.views.device_config',
  716. data: {
  717. d_id: this.equipInfo_d_id,
  718. config_type: 1
  719. },
  720. })
  721. if (res && Object.keys(res).length > 0) {
  722. let data = res;
  723. for (const key in data) {
  724. if (key.includes('snaptime')) {
  725. let text = (data[key] + '').padStart(4, '0');
  726. // console.log(`${text.substring(0, 2)}${text.substring(2, 4)}`);
  727. this.photoTimeArray.push({
  728. value: `${text.substring(0, 2)}:${text.substring(2, 4)}`,
  729. key,
  730. show: false,
  731. });
  732. }
  733. }
  734. // console.log(this.photoTimeArray);
  735. }
  736. },
  737. removeTime(index) {
  738. this.photoTimeArray.splice(index, 1);
  739. },
  740. addTime(index) {
  741. this.photoTimeArray.push({
  742. value: `00:00`,
  743. key: `snaptime${index}`,
  744. show: false,
  745. });
  746. },
  747. changeSnapTime(e, key, index) {
  748. this.photoTimeArray[index].value = `${e.hour}:${e.minute}`
  749. },
  750. changeControlTime(e, type) {
  751. this.equipContrlForm1[type] = `${e.hour}:${e.minute}`
  752. },
  753. async devicePhotoTime() {
  754. // console.log(this.photoTimeArray);
  755. let obj = {};
  756. this.photoTimeArray.forEach((item, index) => {
  757. if (item.value) {
  758. obj[`snaptime${index + 1}`] = (item.value.replace(/:/g, "")) * 1;
  759. }
  760. });
  761. // console.log(obj);
  762. let res = await this.$myRequest({
  763. method: 'post',
  764. url: '/api/api_gateway?method=lpsxy.views.device_control',
  765. data: {
  766. device_id: this.equipInfoImei,
  767. ...obj,
  768. },
  769. })
  770. if (res) {
  771. uni.showToast({
  772. title: '指令下发成功',
  773. duration: 1000,
  774. icon: "none"
  775. });
  776. // this.$message.success('指令下发成功');
  777. this.photoTimeLayer = false;
  778. } else {
  779. uni.showToast({
  780. title: '指令下发失败',
  781. icon: "none",
  782. duration: 1000
  783. });
  784. // this.$message.error(res.data.message);
  785. }
  786. },
  787. async takePhoto(order_type) {
  788. let res = await this.$myRequest({
  789. method: 'post',
  790. url: '/api/api_gateway?method=lpsxy.views.send_control',
  791. data: {
  792. device_id: this.equipInfoImei,
  793. order_type,
  794. },
  795. })
  796. if (res) {
  797. uni.showToast({
  798. title: '指令下发成功',
  799. duration: 1000,
  800. icon: "none"
  801. });
  802. // this.$message.success('指令下发成功');
  803. } else {
  804. uni.showToast({
  805. title: '指令下发失败',
  806. icon: "none",
  807. duration: 1000
  808. });
  809. // this.$message.error(res.data.message);
  810. }
  811. },
  812. async changeExpireFun() {
  813. if (this.decoy == '') {
  814. uni.showToast({
  815. title: '请输入信息素名称',
  816. duration: 1000,
  817. icon: "none"
  818. });
  819. // this.$message.error('请输入信息素名称');
  820. return;
  821. }
  822. let res = await this.$myRequest({
  823. method: 'post',
  824. url: '/api/api_gateway?method=lpsxy.views.update_xy_expire_time',
  825. data: {
  826. device_id: this.equipInfoImei,
  827. xy_expire_time: this.xy_expire_time,
  828. decoy: this.decoy,
  829. },
  830. })
  831. if (res) {
  832. uni.showToast({
  833. title: '操作成功',
  834. icon: "none",
  835. duration: 1000
  836. });
  837. // this.$message.success('操作成功');
  838. this.expireInfoLayer = false;
  839. this.getEquipInfo();
  840. } else {
  841. uni.showToast({
  842. title: '操作失败',
  843. icon: "none",
  844. duration: 1000
  845. });
  846. // this.$message.error(res.data.message);
  847. }
  848. },
  849. async getPhotoList(search) {
  850. let {
  851. photoTimeRange
  852. } = this;
  853. // console.log(photoTimeRange);
  854. // if(photoTimeRange) {
  855. // this.page = 1;
  856. // }
  857. // 当筛选的时候 清空图片列表
  858. if (search) {
  859. this.page = 1;
  860. this.photoList = [];
  861. }
  862. let res = await this.$myRequest({
  863. method: 'post',
  864. url: '/api/api_gateway?method=lpsxy.views.photo_list',
  865. data: {
  866. d_id: this.equipInfo_d_id,
  867. page: this.page,
  868. start: photoTimeRange ? (photoTimeRange[0] / 1000) : '',
  869. end: photoTimeRange ? (photoTimeRange[1] / 1000) : '',
  870. },
  871. })
  872. this.photoLoading = false;
  873. if (res) {
  874. this.photoList = [...this.photoList, ...res.data];
  875. this.total = res.count;
  876. if (this.total > this.page * 10) {
  877. this.loadStatus = 'loadmore'
  878. } else if (this.total <= this.page * 10) {
  879. this.loadStatus = 'nomore'
  880. }
  881. } else {
  882. uni.showToast({
  883. title: '请求失败',
  884. icon: "none",
  885. duration: 1000
  886. });;
  887. }
  888. },
  889. changePhotoTime(dateObj, type) {
  890. console.log(dateObj);
  891. this.photoTimeRangeText = `${dateObj.startDate}~${dateObj.endDate}`;
  892. this.photoTimeRange = [new Date(dateObj.startDate).getTime(),new Date(dateObj.endDate).getTime()];
  893. if(type == 'photo') {
  894. this.getPhotoList('search')
  895. } else {
  896. this.lineChartPest('search')
  897. }
  898. },
  899. clearTimeFun(type) {
  900. this.photoTimeRangeText = '请选择日期';
  901. this.photoTimeRange = '';
  902. if(type == 'photo') {
  903. this.getPhotoList('search');
  904. } else {
  905. this.lineChartPest('search')
  906. }
  907. },
  908. loadMore() {
  909. this.page++;
  910. this.getPhotoList()
  911. },
  912. change(index) {
  913. this.current = index;
  914. if (index == 3) {
  915. this.getControlInfo();
  916. } else if (index == 2) {
  917. this.photoList = [];
  918. this.page = 1;
  919. this.photoTimeRangeText = '请选择日期';
  920. this.photoTimeRange = '';
  921. this.getPhotoList();
  922. } else if(index == 1) {
  923. this.photoTimeRangeText = '请选择日期';
  924. this.photoTimeRange = '';
  925. this.lineChartPest();
  926. this.getAnsyInfo();
  927. }
  928. },
  929. copy(item) {
  930. console.log(item)
  931. uni.setClipboardData({
  932. data: item,
  933. success: function() {
  934. console.log('success');
  935. }
  936. });
  937. },
  938. async getControlInfo() {
  939. let res = await this.$myRequest({
  940. method: "POST",
  941. url: "/api/api_gateway?method=lpsxy.views.device_config",
  942. data: {
  943. d_id: this.equipInfo_d_id,
  944. config_type: 1
  945. },
  946. })
  947. if (res && Object.keys(res).length > 0) {
  948. let data = res;
  949. console.log(data);
  950. let newObj = {
  951. ...data,
  952. show_st: false,
  953. show_et: false,
  954. };
  955. newObj.dev_work_time = data.dev_work_time + '';
  956. newObj.dev_work_time = newObj.dev_work_time.length > 7 ? newObj.dev_work_time : newObj
  957. .dev_work_time.padStart(8, '0');
  958. newObj.st = `${newObj.dev_work_time.substring(0, 2)}:${newObj.dev_work_time.substring(2, 4)}`;
  959. newObj.et = `${newObj.dev_work_time.substring(4, 6)}:${newObj.dev_work_time.substring(6, 8)}`;
  960. // console.log(newObj);
  961. this.equipContrlForm1 = newObj;
  962. }
  963. },
  964. async equipControlSubm() {
  965. let newForm = Object.assign({}, this.equipContrlForm1); //深拷贝
  966. newForm.dev_work_time = (newForm.st + newForm.et).replace(/:/g, "") * 1;
  967. console.log(newForm);
  968. // console.log(obj);
  969. let res = await this.$myRequest({
  970. method: "POST",
  971. url: "/api/api_gateway?method=lpsxy.views.device_control",
  972. data: {
  973. device_id: this.equipInfoImei,
  974. ...newForm
  975. },
  976. })
  977. if (res) {
  978. uni.showToast({
  979. title: '指令下发成功',
  980. duration: 1000,
  981. icon: "none"
  982. });
  983. // this.$message.success('指令下发成功');
  984. } else {
  985. uni.showToast({
  986. title: '指令下发失败',
  987. icon: "none",
  988. duration: 1000
  989. });
  990. // this.$message.error(res.data.message);
  991. }
  992. },
  993. async equipBtnControl(cmd) {
  994. if (this.ota_url == '') {
  995. uni.showToast({
  996. title: '请输入地址',
  997. duration: 1000,
  998. icon: "none"
  999. });
  1000. return
  1001. }
  1002. let op_type = '';
  1003. if (cmd == "reboot") {
  1004. var name = "重启";
  1005. op_type = 1;
  1006. } else if (cmd == "update") {
  1007. var name = "升级";
  1008. op_type = 2;
  1009. }
  1010. let res = await this.$myRequest({
  1011. method: "POST",
  1012. url: "/api/api_gateway?method=lpsxy.views.device_root_control",
  1013. data: {
  1014. op_type,
  1015. d_id: this.equipInfo_d_id,
  1016. ota_url: this.ota_url
  1017. },
  1018. });
  1019. if (res) {
  1020. uni.showToast({
  1021. title: '指令下发成功',
  1022. duration: 1000,
  1023. icon: "none"
  1024. });
  1025. // this.$message.success('指令下发成功');
  1026. } else {
  1027. uni.showToast({
  1028. title: '指令下发失败',
  1029. icon: "none",
  1030. duration: 1000
  1031. });
  1032. // this.$message.error(res.data.message);
  1033. }
  1034. }
  1035. }
  1036. }
  1037. </script>
  1038. <style lang="less" scoped>
  1039. /deep/ .u-calendar__action {
  1040. display: flex;
  1041. justify-content: space-between;
  1042. }
  1043. .green {
  1044. background: #14a478;
  1045. }
  1046. /deep/ .u-radio__icon-wrap__icon {
  1047. .u-icon__icon {
  1048. top: -8rpx !important;
  1049. }
  1050. }
  1051. .yellow {
  1052. background: #f4a72f;
  1053. }
  1054. .danger {
  1055. background: #ff5951;
  1056. }
  1057. .blue {
  1058. background: #1890FF;
  1059. }
  1060. .bigBox {
  1061. position: relative;
  1062. width: 100vw;
  1063. height: calc(100vh);
  1064. background: #f7f7f7;
  1065. overflow: hidden;
  1066. .timeBox {
  1067. display: flex;
  1068. justify-content: space-between;
  1069. align-items: center;
  1070. padding: 30rpx 32rpx;
  1071. border: 1rpx #E5EBE9 solid;
  1072. background: #fff;
  1073. color: #666;
  1074. font-size: 30rpx;
  1075. height: 100rpx;
  1076. box-sizing: border-box;
  1077. .iconBox {
  1078. display: flex;
  1079. align-items: center;
  1080. // margin-top: 4rpx
  1081. }
  1082. .text {
  1083. width: 80vw;
  1084. margin-left: 16rpx;
  1085. }
  1086. }
  1087. }
  1088. .currentBox {
  1089. height: 100%;
  1090. overflow: auto;
  1091. }
  1092. .info {
  1093. padding: 20rpx 40rpx;
  1094. color: #fff;
  1095. line-height: 50rpx;
  1096. font-size: 26rpx;
  1097. background-size: 100% auto;
  1098. background-repeat: no-repeat;
  1099. background-color: #0DC6B6;
  1100. background-position: top left;
  1101. box-sizing: border-box;
  1102. width: 100%;
  1103. border-radius: 5rpx;
  1104. margin: 0 auto;
  1105. p:first-child {
  1106. font-size: 32rpx;
  1107. }
  1108. .expiretishi {
  1109. font-size: 24rpx;
  1110. color: #FF0000;
  1111. }
  1112. .tishi {
  1113. width: 28rpx;
  1114. height: 28rpx;
  1115. margin: 0rpx 0 0 20rpx;
  1116. }
  1117. .fillin {
  1118. display: flex;
  1119. input {
  1120. width: 200rpx;
  1121. font-size: 24rpx;
  1122. height: 50rpx;
  1123. line-height: 50rpx;
  1124. text-indent: 1em;
  1125. }
  1126. }
  1127. }
  1128. .on {
  1129. background-image: url('http://www.hnyfwlw.com:8006/bigdata_app/image/cb/onBg.png')
  1130. }
  1131. .off {
  1132. background-image: url('http://www.hnyfwlw.com:8006/bigdata_app/image/cb/offBg.png')
  1133. }
  1134. .infoBox {
  1135. width: 100%;
  1136. padding: 10rpx 24rpx;
  1137. height: calc(100vh - 92rpx);
  1138. box-sizing: border-box;
  1139. overflow: auto;
  1140. }
  1141. .cardInfo {
  1142. margin-top: 24rpx;
  1143. .title {
  1144. font-size: 28rpx;
  1145. color: #999;
  1146. }
  1147. .controlCard {
  1148. display: flex;
  1149. align-items: center;
  1150. justify-content: space-between;
  1151. width: 100%;
  1152. margin-top: 30rpx;
  1153. background: #fff;
  1154. box-sizing: border-box;
  1155. overflow: hidden;
  1156. .preBtn {
  1157. display: flex;
  1158. align-items: center;
  1159. justify-content: space-around;
  1160. flex-direction: column;
  1161. width: 22%;
  1162. padding: 20rpx;
  1163. height: 80px;
  1164. font-size: 24rpx;
  1165. }
  1166. .btnBox {
  1167. display: flex;
  1168. align-items: center;
  1169. justify-content: center;
  1170. height: 96rpx;
  1171. width: 96rpx;
  1172. border-radius: 96rpx;
  1173. color: #fff;
  1174. text {
  1175. font-size: 20px;
  1176. }
  1177. }
  1178. .preInfo {
  1179. float: left;
  1180. display: flex;
  1181. align-items: center;
  1182. box-sizing: border-box;
  1183. padding: 32rpx !important;
  1184. background: #fff;
  1185. margin-bottom: 32rpx;
  1186. width: 49%;
  1187. margin-right: 2%;
  1188. .btnBox {
  1189. width: 72rpx;
  1190. height: 72rpx;
  1191. background: #14a478;
  1192. }
  1193. .textBox {
  1194. margin-left: 40rpx;
  1195. font-size: 32rpx;
  1196. .name {
  1197. font-size: 24rpx;
  1198. color: #999;
  1199. }
  1200. }
  1201. }
  1202. .preInfo:nth-child(2n) {
  1203. margin-right: 0;
  1204. /* 每个第 3 个元素的右边距为 0 */
  1205. }
  1206. }
  1207. .noBg {
  1208. background: none;
  1209. }
  1210. .widthSet {
  1211. width: 100%;
  1212. }
  1213. .u-border-bottom:after,
  1214. .u-border-left:after,
  1215. .u-border-right:after,
  1216. .u-border-top-bottom:after,
  1217. .u-border-top:after,
  1218. .u-border:after {
  1219. content: " ";
  1220. position: absolute;
  1221. left: 0;
  1222. top: 0;
  1223. pointer-events: none;
  1224. box-sizing: border-box;
  1225. -webkit-transform-origin: 0 0;
  1226. transform-origin: 0 0;
  1227. width: 199.8%;
  1228. height: 199.7%;
  1229. -webkit-transform: scale(.5);
  1230. transform: scale(.5);
  1231. border: .5px solid #E5EBE9;
  1232. z-index: 2;
  1233. }
  1234. }
  1235. .expireBox {
  1236. width: 80%;
  1237. margin: 0 auto;
  1238. padding: 20rpx;
  1239. box-sizing: border-box;
  1240. max-height: 60vh;
  1241. overflow: auto;
  1242. .delBtn {
  1243. margin-left: 40rpx;
  1244. }
  1245. }
  1246. .bgColor {
  1247. width: 100%;
  1248. box-sizing: border-box;
  1249. background: #fff;
  1250. padding: 0 20rpx;
  1251. overflow: auto;
  1252. /deep/ .u-form {
  1253. height: calc(100vh - 88rpx);
  1254. overflow: auto;
  1255. box-sizing: border-box;
  1256. padding: 20rpx 0;
  1257. }
  1258. .btn {
  1259. margin-left: 20rpx;
  1260. }
  1261. }
  1262. .chartBox {
  1263. min-height: 400rpx;
  1264. background: #fff;
  1265. margin: 20rpx 0;
  1266. padding: 32rpx;
  1267. box-sizing: border-box;
  1268. background: #fff;
  1269. .noEmpty{
  1270. height: 400rpx;
  1271. display: flex;
  1272. justify-content: center;
  1273. align-items: center;
  1274. }
  1275. .pestInfo {
  1276. padding: 32rpx 0;
  1277. box-sizing: border-box;
  1278. .pest {
  1279. font-size: 24rpx;
  1280. color: #666;
  1281. margin-bottom: 16rpx;
  1282. .name {
  1283. margin-left: 10rpx;
  1284. color: #333;
  1285. font-weight: 600;
  1286. }
  1287. }
  1288. }
  1289. .pestStatus {
  1290. box-sizing: border-box;
  1291. display: flex;
  1292. align-items: center;
  1293. justify-content: space-between;
  1294. background: #fff;
  1295. height: 284rpx;
  1296. .block {
  1297. display: flex;
  1298. align-items: center;
  1299. flex-direction: column;
  1300. justify-content: space-around;
  1301. width: 33%;
  1302. height: 100%;
  1303. text-align: center;
  1304. }
  1305. .active {
  1306. background: #f7f7f7;
  1307. }
  1308. .iconBox {
  1309. display: flex;
  1310. align-items: center;
  1311. justify-content: center;
  1312. width: 128rpx;
  1313. height: 128rpx;
  1314. border-radius: 128rpx;
  1315. color: #fff;
  1316. .yficonfont {
  1317. font-size: 80rpx;
  1318. }
  1319. }
  1320. .blueText {
  1321. color: #14a478;
  1322. }
  1323. .yellowText {
  1324. color: #f4a72f;
  1325. }
  1326. .redText {
  1327. color: #FF0000;
  1328. }
  1329. }
  1330. }
  1331. .imgList {
  1332. height: calc(100vh - 232rpx);
  1333. overflow: auto;
  1334. box-sizing: border-box;
  1335. padding: 20rpx 0;
  1336. .preImg {
  1337. position: relative;
  1338. float: left;
  1339. width: 49%;
  1340. margin-right: 2%;
  1341. margin-bottom: 20rpx;
  1342. .text {
  1343. position: absolute;
  1344. bottom: 0;
  1345. left: 0;
  1346. width: 100%;
  1347. height: 40rpx;
  1348. line-height: 40rpx;
  1349. text-align: center;
  1350. color: #fff;
  1351. background: rgba(0, 0, 0, .4);
  1352. font-size: 24rpx;
  1353. z-index: 2;
  1354. }
  1355. }
  1356. .preImg:nth-child(2n) {
  1357. margin-right: 0;
  1358. /* 每个第 3 个元素的右边距为 0 */
  1359. }
  1360. .loadBox {
  1361. float: left;
  1362. width: 100%;
  1363. }
  1364. /deep/ .u-calendar__action {
  1365. display: flex;
  1366. justify-content: space-between;
  1367. }
  1368. }
  1369. </style>