detail.vue 40 KB

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