status.vue 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. <template>
  2. <view class="container">
  3. <view style=";position: relative;height: 250px;margin-top:2vh;">
  4. <view class="dtop">
  5. <view class="can" style="background-image: url(/static/images/new/quan.png);">
  6. <view class="box">
  7. <!--view class="top_ball one"></view-->
  8. <!--view class="top_ball two"></view-->
  9. <view class="three">
  10. <view class="four"></view>
  11. <view class="five"></view>
  12. <view class="six"></view>
  13. </view>
  14. <view class="dot"></view>
  15. <view class="dot"></view>
  16. <view class="dot"></view>
  17. <view class="dot"></view>
  18. <view class="dot"></view>
  19. </view>
  20. <!-- <canvas id="c">-->
  21. <!-- </canvas>-->
  22. <view class="stip">
  23. <view class="p0" st="">{{ deviceInfo.qrcode}}</view>
  24. <view class="p1">
  25. <view v-if="portStatus == 2">
  26. {{$t('charge.charging')}}
  27. </view>
  28. <view v-else-if="portStatus == 6">
  29. {{$t('charge.planed')}}
  30. </view>
  31. <view v-else-if="portStatus == 5">
  32. {{$t('charge.connected')}}
  33. </view>
  34. <view v-else>
  35. {{$t('charge.nocharge')}}
  36. </view>
  37. </view>
  38. </view>
  39. </view>
  40. </view>
  41. </view>
  42. <view style="display: flex;flex-direction: row;margin:0 33%;" v-if="curPort.length>1">
  43. <view class="port_item" :class="item.id==choosePort?'selected_item':''" v-for="item in curPort" @click="selectPort(item.id);">{{ i18(item.text )}}</view>
  44. </view>
  45. <view class="dstatus">
  46. <view class="ditem">
  47. <image class="itemimg" src="/static/images/new/tmp.png"/>
  48. <view class="item-value">{{deviceTemp}}℃</view>
  49. <span class="item-text">{{$t('charge.devtemper')}}</span>
  50. </view>
  51. <view class="ditem">
  52. <image class="itemimg" src="/static/images/new/dianya.png"/>
  53. <view class="item-value">{{ deviceV }}V</view>
  54. <span class="item-text">{{$t('charge.voltage')}}</span>
  55. </view>
  56. <view class="ditem">
  57. <image class="itemimg" src="/static/images/new/dianliu.png"/>
  58. <view class="item-value" v-if="deviceV == 0">0A</view>
  59. <view class="item-value" v-else>{{currentValue}}A</view>
  60. <span class="item-text">{{$t('charge.current')}}</span>
  61. </view>
  62. <view class="ditem">
  63. <image class="itemimg" src="/static/images/new/shjian.png"/>
  64. <view class="item-value">{{ chargeTime }}{{ i18('分钟') }}</view>
  65. <span class="item-text" v-if="portDetail.portStatus == 6">{{i18('剩余时间')}}</span>
  66. <span class="item-text" v-else>{{$t('charge.chargetime')}}</span>
  67. </view>
  68. <view class="ditem">
  69. <image class="itemimg" src="/static/images/new/gonglv.png"/>
  70. <view class="item-value">{{ gonglv }}W</view>
  71. <span class="item-text">{{$t('charge.power')}}</span>
  72. </view>
  73. <view class="ditem">
  74. <image class="itemimg" src="/static/images/new/dianliang.png"/>
  75. <view class="item-value" v-if="portDetail.voltage == 0">0 {{ i18('度') }}</view>
  76. <view class="item-value" v-else>{{ dianliang }} {{ i18('度') }}</view>
  77. <span class="item-text">{{$t('charge.elec')}}</span>
  78. </view>
  79. </view>
  80. <view class="dbtns">
  81. <view class="start" @click="toPage">
  82. <image style="width:25px;height: 25px;margin-right: 5px;" src="/static/images/new/start.png"/>
  83. <span>{{$t('charge.startcharge')}}</span>
  84. </view>
  85. <view class="get" @click="getInfo">
  86. <image style="width:25px;height: 25px;margin-right: 5px;" src="/static/images/new/get.png"/>
  87. <span>{{$t('charge.getinfo')}}</span>
  88. </view>
  89. </view>
  90. <view class="dtip">
  91. <view style="margin:10px 0px;color: #1A87FF;"><img style="width: 13px;height: 13px" src="/static/images/new/tip.png">{{i18('温馨提示')}}</view>
  92. <view>1,{{i18('桩控制最大输出电流,当功率没有达到请检查车的状态或者车的设置')}};</view>
  93. <view>2,{{i18('启动充电-&gt;设备管理->可设置设备最大输出电流')}}</view>
  94. <view>3,{{i18('为保障您远程启动正常充电,请确保枪头完全连接充电口,同时确认您的爱车处于立即充电状态下')}};</view>
  95. <view>4,{{i18('注意规范安全充电,停好车,锁好车。')}}</view>
  96. </view>
  97. </view>
  98. </template>
  99. <script>
  100. import {getDeviceInfo,getPortDetail,startCharge,stopCharge,sendPortDetailCmd,checkStatusChange,getPlanInfo,cancelPlan} from "@/api/device/device";
  101. import websocket from '@/utils/websocket'
  102. import i18 from '@/utils/i18.js'
  103. export default {
  104. data() {
  105. return {
  106. refreshTimer:null,
  107. curPort:[],
  108. chargeTime:0,
  109. deviceTemp:0,
  110. deviceV:0,
  111. currentValue:0,
  112. gonglv:0,
  113. dianliang:0,
  114. portStatus:0,
  115. deviceInfo:{},
  116. visitTime:"",
  117. timer:null,
  118. showPort:false,
  119. portDetail:{portStatus:0,POWER:0,voltage:0},
  120. statusTimer:"",
  121. connected:false,
  122. scriptTask:null,
  123. choosePort:1,
  124. portList:[[{port:1,text:"端口一"}]],
  125. planInfo:null,
  126. days:["","周一","周二","周三","周四","周五","周六","周日"]
  127. }
  128. },
  129. computed: {
  130. imgUrl() {
  131. return getApp().globalData.config.imgUrl;
  132. }
  133. },
  134. onLoad(opt) {
  135. this.deviceInfo.deviceId = opt.id;
  136. this.deviceInfo.ccid = opt.ccid;
  137. this.deviceInfo.qrcode = opt.qrcode;
  138. this.startTimer();
  139. },
  140. onShow(){
  141. this.getInfo();
  142. this.getPlanInfo();
  143. },
  144. onUnload (){
  145. this.closeSocket();
  146. if(this.refreshTimer != null){
  147. clearTimeout(this.refreshTimer)
  148. }
  149. },
  150. methods: {
  151. toPage(){
  152. let imei = this.deviceInfo.deviceId;
  153. let ccid = this.deviceInfo.ccid;
  154. this.closeSocket();
  155. uni.navigateTo({
  156. url: '/pages/weitiandi/device/index?id='+imei+'&ccid='+ccid
  157. });
  158. },
  159. i18(text){
  160. return i18(text)
  161. },
  162. planCharge(){
  163. if(this.planInfo != null){
  164. this.$modal.confirm("确认取消预约?").then(res=>{
  165. this.cancelPlan();
  166. })
  167. }else{
  168. this.toPlan()
  169. }
  170. },
  171. cancelPlan(){
  172. cancelPlan(this.planInfo.id).then(res=>{
  173. this.$modal.msg("取消成功");
  174. this.planInfo = null;
  175. this.getPlanInfo();
  176. })
  177. },
  178. getPlanInfo(){
  179. getPlanInfo(this.deviceInfo.deviceId,this.choosePort).then(res=>{
  180. let data = res.data;
  181. if(data != null){
  182. let planType = data.planType;
  183. if(planType == 1){//单次预约
  184. let planInfo = {};
  185. planInfo.runTime = data.runTime;
  186. this.planInfo = planInfo;
  187. this.planInfo.id = data.id;
  188. }else{
  189. let planInfo = {};
  190. planInfo.runTime = data.runTime;
  191. let repeatDays = data.repeatDays;
  192. let days = repeatDays.split(",")
  193. let strs = "";
  194. for (let i = 0; i < days.length; i++) {
  195. if(strs.length>0){
  196. strs+=",";
  197. }
  198. strs +=this.days[days[i]];
  199. }
  200. this.planInfo = planInfo;
  201. this.planInfo.runTime = strs+" "+data.repeatTime;
  202. this.planInfo.id = data.id;
  203. }
  204. }
  205. })
  206. },
  207. startTimer(){
  208. let self = this;
  209. if(this.refreshTimer != null){
  210. clearTimeout(this.refreshTimer);
  211. }
  212. self.refreshTimer = setTimeout(function(){
  213. self.getInfo();
  214. self.startTimer();
  215. },30000);
  216. },
  217. confirmPort(e){
  218. let value = e.value[0]
  219. this.choosePort = value.port;
  220. this.showPort = false;
  221. this.getInfo()
  222. },
  223. parsePortCmd(real_data) {
  224. let self = this;
  225. self.portDetail = real_data;
  226. self.portList = [[]];
  227. self.curPort = [];
  228. let port_first_status = self.portDetail["port_first_status"];
  229. let port_second_status = self.portDetail["port_second_status"]
  230. if(port_first_status){
  231. self.portList[0].push({port:1,text:"端口一"});
  232. self.curPort.push({
  233. text:"端口一",
  234. status:port_first_status,
  235. id:1,
  236. })
  237. let power = self.portDetail.power;
  238. let voltage = parseInt(self.portDetail.voltage);
  239. if(voltage >0){
  240. let current = power/voltage;
  241. current = current.toFixed(1);
  242. self.portDetail.currentValue = current;
  243. }
  244. }
  245. if(port_second_status){
  246. self.portList[0].push({port:2,text:"端口二"});
  247. self.curPort.push({
  248. text:"端口二",
  249. status:port_second_status,
  250. id:2
  251. })
  252. let power = self.portDetail.power_1;
  253. let voltage = parseInt(self.portDetail.voltage);
  254. if(voltage >0){
  255. let current = power/voltage;
  256. current = current.toFixed(1);
  257. self.portDetail.currentValue_1 = current;
  258. }
  259. }
  260. let choosePort = self.choosePort
  261. /**
  262. * chargeTime:0,
  263. * deviceTemp:0,
  264. * deviceV:0,
  265. * currentValue:0,
  266. * gonglv:0,
  267. * dianliang:0,
  268. * portStatus:0,
  269. */
  270. if(choosePort == 1){
  271. self.portDetail.portStatus = port_first_status;
  272. self.chargeTime = self.portDetail.time;
  273. self.gonglv = self.portDetail.power;
  274. self.dianliang = self.portDetail.elec/100;
  275. self.currentValue = self.portDetail.currentValue;
  276. if(port_first_status != 2){
  277. self.chargeTime = 0;
  278. if(port_first_status == 6){
  279. self.chargeTime = self.portDetail.time;
  280. }
  281. self.gonglv = 0;
  282. self.dianliang = 0;
  283. self.currentValue = 0;
  284. }
  285. }else if(choosePort == 2){
  286. self.portDetail.portStatus = port_second_status;
  287. self.chargeTime = self.portDetail.time_1;
  288. self.gonglv = self.portDetail.power_1;
  289. self.dianliang = self.portDetail.elec_1/100;
  290. self.currentValue = self.portDetail.currentValue_1;
  291. if(port_second_status != 2){
  292. self.chargeTime = 0;
  293. if(port_first_status == 6){
  294. self.chargeTime = self.portDetail.time_1;
  295. }
  296. self.gonglv = 0;
  297. self.dianliang = 0;
  298. self.currentValue = 0;
  299. }
  300. }
  301. self.portStatus = self.portDetail.portStatus;
  302. self.deviceTemp = self.portDetail.dev_temper;
  303. self.deviceV = self.portDetail.voltage;
  304. self.$modal.closeLoading();
  305. },
  306. initSocket(key){
  307. let self = this;
  308. let socketUrl = getApp().globalData.config.socketUrl
  309. this.scriptTask = websocket({
  310. url:"/"+key+"/",
  311. });
  312. let scriptTask = this.scriptTask;
  313. scriptTask.onOpen(function (res) {
  314. console.log('WebSocket连接已打开!');
  315. self.connected = true;
  316. });
  317. scriptTask.onError(function (res) {
  318. self.connected = false;
  319. console.log(res);
  320. });
  321. scriptTask.onMessage(function (res) {
  322. let data = JSON.parse(res.data);
  323. let type = data.type;
  324. let real_data = data.real_data;
  325. if(type == 103){
  326. self.parsePortCmd(real_data);
  327. }
  328. if(type == 116){
  329. self.$modal.closeLoading();
  330. self.getInfo();
  331. }
  332. if(type == 113){
  333. self.$modal.closeLoading();
  334. self.getInfo();
  335. }
  336. if(type == 96){
  337. self.mainBoardInfo = real_data;
  338. self.formatMainboardData();
  339. self.$modal.closeLoading();
  340. }
  341. self.$forceUpdate();
  342. console.log('收到服务器内容:' + JSON.stringify(data));
  343. });
  344. scriptTask.onClose(function (res) {
  345. console.log('WebSocket 已关闭!');
  346. });
  347. },
  348. toSet(){
  349. this.closeSocket();
  350. uni.navigateTo({
  351. url: '/pages/weitiandi/device/setting?id='+this.deviceInfo.deviceId+"&ccid="+this.deviceInfo.ccid
  352. });
  353. },
  354. toPlan(){
  355. uni.navigateTo({
  356. url: '/pages/weitiandi/device/plan?port='+this.choosePort+'&id='+this.deviceInfo.deviceId+"&ccid="+this.deviceInfo.ccid
  357. });
  358. },
  359. trigger(){
  360. let portStatus = this.portDetail.portStatus;
  361. if(portStatus == 2){//需要停止充电
  362. this.$modal.confirm("需要停止充电么?").then(res=>{
  363. this.stopCharge();
  364. })
  365. }else{
  366. if(portStatus == 1){
  367. this.$modal.msg("请先将充电枪插入后再点击充电");
  368. }
  369. if(portStatus == 5){
  370. this.$modal.confirm("确认开始充电么?").then(res=>{
  371. this.startCharge();
  372. })
  373. }
  374. }
  375. },
  376. getInfo() {
  377. let self= this;
  378. this.$modal.loading("正在获取状态,请稍等...");
  379. sendPortDetailCmd(this.deviceInfo).then(res => {
  380. this.$modal.loading("正在获取状态,请稍等...");
  381. this.visitTime = res.msg;
  382. if(!this.visitTime){
  383. this.$modal.msg("请重新进入页面");
  384. return;
  385. }
  386. if(!this.scriptTask){
  387. this.initSocket(this.deviceInfo.deviceId);
  388. }
  389. setTimeout(function (){
  390. getPortDetail(self.deviceInfo,self.visitTime).then(res=>{
  391. let data = res.data;
  392. if(data != null){
  393. self.parsePortCmd(data);
  394. }else{
  395. }
  396. });
  397. },500)
  398. })
  399. },
  400. stopCharge(){
  401. let self = this;
  402. this.deviceInfo.port = this.choosePort;
  403. stopCharge(this.deviceInfo).then(()=>{
  404. self.$modal.loading("停止成功");
  405. setTimeout((()=>{
  406. self.getInfo();
  407. }),1000);
  408. })
  409. },
  410. startCharge(){
  411. let self = this;
  412. this.deviceInfo.port = this.choosePort;
  413. startCharge(this.deviceInfo).then(res=>{
  414. self.$modal.loading("启动成功");
  415. setTimeout((()=>{
  416. self.getInfo();
  417. }),1000);
  418. })
  419. },
  420. getPortInfo(){
  421. this.startPortDetailTimer();
  422. },
  423. startPortDetailTimer(){
  424. let self = this;
  425. this.timer = setTimeout(function (){
  426. getPortDetail(self.deviceInfo,self.visitTime).then(res=>{
  427. let data = res.data;
  428. if(data != null){
  429. self.portDetail = data;
  430. self.checkStatusCheck();
  431. self.$modal.closeLoading();
  432. }else{
  433. self.startPortDetailTimer();
  434. }
  435. });
  436. },1000);
  437. },
  438. checkStatusCheck(){
  439. this.statusChangeTimer();
  440. },
  441. checkOnPage(){
  442. var pages = getCurrentPages() // 获取栈实例
  443. let currentRoute = pages[pages.length - 1].route; // 获取当前页面路由
  444. if("pages/weitiandi/device/index" != currentRoute){
  445. return false;
  446. }
  447. return true;
  448. },
  449. closeSocket(){
  450. this.scriptTask.close();
  451. this.scriptTask = null;
  452. },
  453. statusChangeTimer(){
  454. let self = this;
  455. this.statusTimer = setTimeout(function(){
  456. if(!this.checkOnPage()){
  457. return;
  458. }
  459. checkStatusChange(self.deviceInfo,self.visitTime).then(res=>{
  460. let data = res.data;
  461. if(data != null){
  462. self.getInfo();
  463. }else{
  464. self.statusChangeTimer();
  465. }
  466. });
  467. },3000);
  468. }
  469. }
  470. }
  471. </script>
  472. <style>
  473. .container {
  474. background: rgb(249, 252, 255);
  475. inset: 0;
  476. position: absolute;
  477. }
  478. .header {
  479. position: relative;
  480. margin-top:4vw;
  481. }
  482. .header-status-desc {
  483. position: absolute;
  484. text-align: center;
  485. width: 100%;
  486. bottom:1vh;
  487. font-size: 5vw;
  488. font-weight: bold;
  489. color: #0E9F9B;
  490. margin-bottom: 5vw;
  491. }
  492. .header-status {
  493. font-weight: bold;
  494. text-align: center;
  495. }
  496. .chong-active {
  497. color: #0E9F9B
  498. }
  499. .header-img {
  500. width: 100%;
  501. padding: 5% 10%;
  502. text-align: center;
  503. }
  504. .header-img image {
  505. width: 100%;
  506. height: 23vh;
  507. }
  508. .info-body{
  509. background: #0E9F9B;
  510. height: 20vh;
  511. margin: 0 2%;
  512. border-radius: 1vw;
  513. margin-top:2vh;
  514. color: #F8FCFF;
  515. line-height: 3vh;
  516. }
  517. .info-content{
  518. display: inline-block;
  519. width: 23%;
  520. text-align: center;
  521. margin: 1%;
  522. margin-top:2.5vh;
  523. }
  524. .info-content-value{
  525. font-weight: bold;
  526. }
  527. .info-content-text{
  528. }
  529. .info-summary{
  530. display: flex;
  531. flex-direction: row;
  532. text-align: center;
  533. margin:3vh 0;
  534. }
  535. .summary{
  536. width: 33%;
  537. line-height: 2.5vh;
  538. }
  539. .charge-num{
  540. color: #0E9F9B;
  541. font-weight: bold;
  542. font-size: 4.5vw;
  543. }
  544. .charge-title{
  545. color: #B2B2B2;
  546. font-weight: 400;
  547. }
  548. .btn-image{
  549. width: 90%;
  550. height: 100%;
  551. }
  552. .info-bottom-btn{
  553. display: flex;
  554. flex-direction: row;
  555. text-align: center;
  556. position: relative;
  557. margin-top: 10vh
  558. ;
  559. }
  560. .btn-area{
  561. width: 50%;
  562. height: 50px;
  563. }
  564. .left{
  565. position: relative;
  566. left: 10px;
  567. text-align: right;
  568. }
  569. .right{
  570. text-align: left;
  571. position: relative;
  572. right: 10px;
  573. }
  574. .info-plan{
  575. text-align: center;
  576. color: #0E9F9B;
  577. margin-top:1vh;
  578. font-weight: 400;
  579. }
  580. .setting{
  581. position: fixed;
  582. right: -1px;
  583. top: 10vh;
  584. z-index: 999;
  585. background: rgb(227,243,245);
  586. color: #0E9F9B;
  587. font-size: 10px;
  588. border-radius: 5px;
  589. padding: 3px;
  590. }
  591. .port{
  592. height: 70px;
  593. background: #F8FCFF;
  594. border: 0px solid #F8FCFF;
  595. box-shadow: 0px 0px 6px 1px rgba(101,101,101,0.29);
  596. border-radius: 4px;
  597. margin:0 10px;
  598. position: relative;
  599. margin-top:10px;
  600. }
  601. .plan{
  602. height: 70px;
  603. background: #F8FCFF;
  604. border: 0px solid #F8FCFF;
  605. box-shadow: 0px 0px 6px 1px rgba(101,101,101,0.29);
  606. border-radius: 4px;
  607. margin:0 10px;
  608. position: relative;
  609. margin-top:15px;
  610. }
  611. .port-image{
  612. height: 40px;
  613. width: 40px;
  614. position: absolute;
  615. top:15px;
  616. left:20px;
  617. }
  618. .port-text{
  619. position: absolute;
  620. top:13px;
  621. left:75px;
  622. font-weight: bold;
  623. }
  624. .port-num{
  625. position: absolute;
  626. top:38px;
  627. left:75px;
  628. color: #B2B2B2;
  629. }
  630. .port-icon{
  631. position: absolute;
  632. top:30px;
  633. right:5px;
  634. width: 10px;
  635. height: 16px;
  636. }
  637. .port-icon image{
  638. width: 90%;
  639. }
  640. .body-bottom{
  641. padding:0 22px;
  642. }
  643. .body-bottom .info-content{
  644. width: 30%;
  645. }
  646. .bottom-control{
  647. height: 22vh;
  648. margin: 0 2%;
  649. margin-top:2vh;
  650. line-height: 3vh;
  651. background: #F8FCFF;
  652. border: 0px solid #F8FCFF;
  653. box-shadow: 0px 0px 6px 1px rgba(101,101,101,0.29);
  654. border-radius: 4px;
  655. padding:3%;
  656. }
  657. .control-btn{
  658. display: inline-block;;
  659. height: 60px;
  660. width: 25%;
  661. padding:10px 20px;
  662. text-align: center;
  663. font-size: 12px;
  664. color: black;
  665. }
  666. .control-btn .btn-image{
  667. }
  668. #box {
  669. /* width: 300px; */
  670. height: 280px;
  671. position: relative;
  672. /* 背景色 */
  673. /* background: #f7f6f6; */
  674. overflow: hidden;
  675. /* padding: 50px 0; */
  676. box-sizing: border-box;
  677. ;
  678. }
  679. .box {
  680. width: 100%;
  681. height: 100%;
  682. position: absolute;
  683. display: flex;
  684. justify-content: center;
  685. /* 此处尽量不要设置背景色,可以选择在父标签上设置背景色,否则没有黏黏的效果 */
  686. filter: url("#goo");
  687. }
  688. /* 电量文字 */
  689. .text {
  690. font-weight: 200;
  691. font-size: 20px;
  692. margin-top: 5px;
  693. text-align: center;
  694. color: #ff6600;
  695. }
  696. /* 电量文字 */
  697. .text span {
  698. font-size: 15px;
  699. }
  700. /* 顶部的两个旋转小球 */
  701. .top_ball {
  702. width: 200px;
  703. height: 200px;
  704. border-radius: 35%;
  705. opacity: 0.5;
  706. position: absolute;
  707. top: 20px;
  708. z-index: 10;
  709. /* 从中心向外剪切圆,相当于掏空 */
  710. -webkit-mask: radial-gradient(transparent 95px, white 0px);
  711. }
  712. /* 顶部的两个旋转小球 */
  713. .top_ball.one {
  714. background: var(--c);
  715. animation: ballZhuan 5s linear infinite;
  716. }
  717. /* 顶部的两个旋转小球 */
  718. .top_ball.two {
  719. background: var(--c);
  720. animation: ballZhuan 8s linear infinite;
  721. }
  722. .three {
  723. width: 170px;
  724. height: 170px;
  725. border-radius: 300px;
  726. opacity: 1;
  727. position: absolute;
  728. top: 20px;
  729. z-index: 10;
  730. /* 从中心向外剪切圆,相当于掏空 */
  731. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  732. background: #ffffff;
  733. /* animation: ballZhuan 9s linear infinite; */
  734. overflow: hidden;
  735. box-shadow: 0px 0px 19px 1px #2196f3;
  736. }
  737. .four {
  738. width: 200px;
  739. height: 200px;
  740. border-radius: 80px;
  741. opacity: 0.3;
  742. position: absolute;
  743. top: 10px;
  744. z-index: 10;
  745. /* 从中心向外剪切圆,相当于掏空 */
  746. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  747. background: #2196f3;
  748. animation: ballZhuan1 linear infinite;
  749. animation-duration: 11s;
  750. }
  751. .five {
  752. width: 270px;
  753. height: 270px;
  754. border-radius: 99px;
  755. opacity: 0.6;
  756. position: absolute;
  757. top: 30px;
  758. z-index: 10;
  759. /* 从中心向外剪切圆,相当于掏空 */
  760. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  761. background: #2196f3;
  762. animation: ballZhuan1 linear infinite;
  763. /* transform: rotate(120deg); */
  764. animation-duration: 9s;
  765. left: -67px;
  766. }
  767. .six {
  768. width: 270px;
  769. height: 270px;
  770. border-radius: 99px;
  771. opacity: 0.6;
  772. position: absolute;
  773. top:30px;
  774. z-index: 10;
  775. /* 从中心向外剪切圆,相当于掏空 */
  776. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  777. background: #2196f3;
  778. animation: ballZhuan1 7s linear infinite;
  779. /* transform: rotate(120deg); */
  780. right: -67px;
  781. }
  782. @keyframes ballZhuan {
  783. 100% {
  784. transform: rotate(360deg);
  785. }
  786. }
  787. @keyframes ballZhuan1 {
  788. 100% {
  789. transform: rotate(360deg);
  790. }
  791. }
  792. /* 底部的小球 */
  793. .dot {
  794. display: block;
  795. width: 20px;
  796. height: 20px;
  797. border-radius: 50%;
  798. background: rgba(101,192,255,0.28);
  799. position: absolute;
  800. z-index: 1000;
  801. bottom: -50px;
  802. }
  803. .dot:nth-of-type(1) {
  804. width: 40px;
  805. height: 40px;
  806. right: 116px;
  807. animation: dotMove 5s linear infinite;
  808. }
  809. .dot:nth-of-type(2) {
  810. width: 50px;
  811. height: 50px;
  812. left: 120px;
  813. animation: dotMove 4s linear infinite;
  814. }
  815. .dot:nth-of-type(3) {
  816. animation: dotMove 2s linear infinite;
  817. }
  818. .dot:nth-of-type(4) {
  819. width: 15px;
  820. height: 15px;
  821. left: 130px;
  822. animation: dotMove 2s linear infinite;
  823. }
  824. .dot:nth-of-type(5) {
  825. width: 30px;
  826. height: 30px;
  827. animation: dotMove 3s linear infinite;
  828. }
  829. @keyframes dotMove {
  830. 0% {
  831. transform: translateY(0px);
  832. opacity: 1;
  833. }
  834. 98% {
  835. opacity: 1;
  836. }
  837. 100% {
  838. transform: translateY(-260px);
  839. opacity: 0;
  840. }
  841. }
  842. .w-flex {
  843. display: -webkit-box;
  844. display: -webkit-flex;
  845. display: flex;
  846. padding: 0px 25px;
  847. }
  848. .w-flex__item {
  849. -webkit-box-flex: 1;
  850. -webkit-flex: 1;
  851. flex: 1;
  852. }
  853. .w-item{
  854. text-align: center;
  855. padding: 5px;
  856. }
  857. .w-item-tit{
  858. font-size: 14px;
  859. color: #888;
  860. }
  861. .w-item-num{
  862. font-size: 18px;
  863. color: #111;
  864. }
  865. .can{
  866. position: relative;
  867. z-index: 0;
  868. width: 211px;
  869. height: 211px;
  870. background-size: cover;
  871. display: flex;
  872. justify-content: center;
  873. align-items: center;
  874. }
  875. .dtop{
  876. background: url(/static/images/new/box1.png);
  877. background-size: cover;
  878. width: 260px;
  879. height: 236px;
  880. display: flex;
  881. justify-content: center;
  882. align-items: center;
  883. left: 15%;
  884. position: relative;
  885. }
  886. .dstatus{
  887. margin-top: 0.1rem;
  888. display: flex;
  889. flex-wrap: wrap;
  890. justify-content: space-evenly;
  891. align-content: center;
  892. }
  893. .ditem{
  894. width: 30%;
  895. display: flex;
  896. flex-direction: column;
  897. align-items: center;
  898. margin-bottom: 0.3rem;
  899. margin-top: 10px;
  900. }
  901. .itemimg{
  902. width: 50px;
  903. height: 50px;
  904. }
  905. .item-value{
  906. font-weight: bold;
  907. font-size: 19px;
  908. margin:4px 0;
  909. }
  910. .item-text{
  911. font-size: 13px;
  912. margin:1px 0;
  913. color: #999999;
  914. }
  915. .start{
  916. background: #1A87FF;
  917. color: #fff;
  918. width: 45%;
  919. height: 50px;
  920. min-height: 40px;
  921. border-radius: 50px;
  922. display: flex;
  923. justify-content: center;
  924. align-items: center;
  925. font-size: 20px;
  926. font-weight: bold;
  927. }
  928. .dbtns{
  929. display: flex;
  930. margin-top:10px;
  931. justify-content: space-between;
  932. padding: 0 30px;
  933. }
  934. .get{
  935. background: #fff;
  936. border: 1px solid #1A87FF;
  937. color: #1A87FF;
  938. width: 45%;
  939. height: 50px;
  940. min-height: 40px;
  941. border-radius: 50px;
  942. display: flex;
  943. justify-content: center;
  944. align-items: center;
  945. font-size: 20px;
  946. font-weight: bold;
  947. }
  948. .dtip{
  949. margin: 20px 20px;
  950. padding: 10px;
  951. background: rgba(127,200,251,0.1);
  952. border: 1px solid #7FC8FB;
  953. box-shadow: 0 2px 8px 0 rgba(0,0,0,0.19);
  954. border-radius: 5px;
  955. font-size: 17px;
  956. font-weight: 400;
  957. color: #B8B9BA;
  958. margin-bottom: 10px;
  959. }
  960. .p1{
  961. font-size: 20px;
  962. color: white;
  963. font-weight: bold;
  964. margin-top:10px;
  965. }
  966. .stip{
  967. text-align: center;
  968. z-index: 9999;
  969. }
  970. </style>