details.vue 40 KB

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