status.vue 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576
  1. <template>
  2. <view class="container">
  3. <view style="height: 0vh;place-items: center;display: grid;">
  4. <image style="height: 3vh;width: 27vw;margin-top: 1vh;top: 3vh;"
  5. src="../../../static/images/new/starts/login/backImg2.png"></image>
  6. <text @click="clickRight()"
  7. style="font-size: 15px;margin: -5px 0 0 30vh;font-weight: bold;z-index: 9999;"><uni-icons v-show="!show" style="color: #ffffff;" size="30" type="more-filled"></uni-icons><uni-icons size="30" v-show="show" style="color: #57B03D;" type="more-filled"></uni-icons></text>
  8. <!-- <uni-drawer @change="changeDrawer" style="top:20vh;height: 100vh" ref="showRight" mode="right"
  9. :mask-click="true">
  10. </uni-drawer> -->
  11. </view>
  12. <view >
  13. <u-popup :show="show" mode="right" customStyle="top:14vh;bottom:200px;" :overlayOpacity="0" :closeOnClickOverlay="true" :zIndex="100" ref="showRight" :overlay="false" >
  14. <view style="width: 100vw;height: 100vh;">
  15. <scroll-view style="background: linear-gradient(#000000, #161615);font-size: 20px;height: 100vh;" scroll-y="true">
  16. <view class="prop-item" @click="handleLogout()">
  17. <!-- <view class="prop-item-image">
  18. <image :src="imgUrl+'/logout.png'" style="width: 30%;height:100%;" />
  19. </view> -->
  20. <view class="prop-item-right">{{i18('退出登录')}}</view>
  21. <view class="prop-item-left">
  22. <!-- <uni-icons type="forward" color="lightgray" size="16"></uni-icons> -->
  23. </view>
  24. </view>
  25. <u-divider />
  26. <view class="prop-item" @click="skipPage(3)">
  27. <!-- <view class="prop-item-image">
  28. <image :src="imgUrl+'/logout.png'" style="width: 30%;height:100%;" />
  29. </view> -->
  30. <view class="prop-item-right">{{i18('关于我们')}}</view>
  31. <view class="prop-item-left">
  32. <!-- <uni-icons type="forward" color="lightgray" size="16"></uni-icons> -->
  33. </view>
  34. </view>
  35. <u-divider />
  36. <view class="prop-item" @click="skipPage(4)">
  37. <!-- <view class="prop-item-image">
  38. <image :src="imgUrl+'/logout.png'" style="width: 30%;height:100%;" />
  39. </view> -->
  40. <view class="prop-item-right">{{i18('帮助')}}</view>
  41. <view class="prop-item-left">
  42. <!-- <uni-icons type="forward" color="lightgray" size="16"></uni-icons> -->
  43. </view>
  44. </view>
  45. <u-divider />
  46. </scroll-view>
  47. </view>
  48. </u-popup>
  49. </view>
  50. <view style=" position: relative;top: 10vh;margin-top: 4vh;text-align: center;display: flex;flex-direction: row;justify-content: center;">
  51. <view class="progress_box" style="text-align: center">
  52. <!-- <canvas class="progress_bg" canvas-id="cpbg"></canvas> -->
  53. <view >
  54. <image class="progress-barup" src="../../../static/images/new/starts/kedu.png"></image>
  55. <canvas class="progress_bar" canvas-id="cpbar"></canvas>
  56. </view>
  57. <!-- <canvas class="progress_line" canvas-id="cpline"></canvas> -->
  58. <view class="progress_txt">
  59. <view class="progress_info">
  60. <view class="p0" style="color: azure;" st="">{{ deviceInfo.qrcode}}</view>
  61. <view class="p1">
  62. <view v-if="portStatus == 2" style="position: relative;">
  63. {{$t('charge.charging')}}
  64. </view>
  65. <view v-else-if="portStatus == 6" style="position: relative;">
  66. {{$t('charge.planed')}}
  67. </view>
  68. <view v-else-if="portStatus == 5" style="position: relative;">
  69. {{$t('charge.connected')}}
  70. </view>
  71. <view v-else>
  72. {{$t('charge.nocharge')}}
  73. </view>
  74. </view>
  75. <view class="p2">
  76. <view class="item-value" v-if="portDetail.voltage == 0">0 {{ i18('度') }}</view>
  77. <view class="item-value" v-else>{{ dianliang }} {{ i18('度') }}</view>
  78. </view>
  79. </view>
  80. </view>
  81. </view>
  82. <!-- <view class="dtop">
  83. <view class="can" style="background-image: url(/static/images/new/quan.png);">
  84. <view class="box">
  85. <view class="three">
  86. <view class="four"></view>
  87. <view class="five"></view>
  88. <view class="six"></view>
  89. </view>
  90. <view class="dot"></view>
  91. <view class="dot"></view>
  92. <view class="dot"></view>
  93. <view class="dot"></view>
  94. <view class="dot"></view>
  95. </view>
  96. <view class="stip">
  97. <view class="p0" st="">{{ deviceInfo.qrcode}}</view>
  98. <view class="p1">
  99. <view v-if="portStatus == 2">
  100. {{$t('charge.charging')}}
  101. </view>
  102. <view v-else-if="portStatus == 6">
  103. {{$t('charge.planed')}}
  104. </view>
  105. <view v-else-if="portStatus == 5">
  106. {{$t('charge.connected')}}
  107. </view>
  108. <view v-else>
  109. {{$t('charge.nocharge')}}
  110. </view>
  111. </view>
  112. </view>
  113. </view>
  114. </view>-->
  115. </view>
  116. <view style="display: flex;align-items: center;flex-direction: column;color: aliceblue;margin-top: 5vh;">
  117. <view
  118. style="background-color: #494E51;justify-content: center;display: flex;justify-items: center;flex-direction: row;text-align: center;width: 75vw;;border-radius: 27px;">
  119. <view span="4" style="width: 25vw;">
  120. <view class="item-value">{{ deviceV }}V</view>
  121. <span class="item-text">{{$t('charge.voltage')}}</span>
  122. </view>
  123. <u-line direction="col" color="#6F84AC" length="50"></u-line>
  124. <view span="4" style="width: 25vw;">
  125. <view class="item-value">{{ gonglv }}W</view>
  126. <span class="item-text">{{$t('charge.power')}}</span>
  127. </view>
  128. <u-line direction="col" color="#6F84AC" length="50"></u-line>
  129. <view span="4" style="width: 25vw; margin-top: -5px;">
  130. <view class="item-value">{{deviceTemp}}℃</view>
  131. <span class="item-text">{{$t('charge.devtemper')}}</span>
  132. </view>
  133. <!-- <view span="3" style="width: 19vw;">
  134. <view class="item-value" v-if="portDetail.voltage == 0">0 {{ i18('度') }}</view>
  135. <view class="item-value" v-else>{{ dianliang }} {{ i18('度') }}</view>
  136. <span class="item-text">{{$t('charge.elec')}}</span>
  137. </view> -->
  138. </view>
  139. </view>
  140. <view style="display: flex;align-items: center;flex-direction: column;color: aliceblue;margin-top: 3vh;">
  141. <view
  142. style="position:relative;justify-content: center;display: flex;justify-items: center;flex-direction: row;text-align: center;width: 100%;height: 6vh;}">
  143. <view style="width: 27vw;left:5vw;position: absolute;font-size: 11px;">
  144. <view style="margin-left: 1vh;">
  145. <view style="font-weight: bold;"><span v-if="portDetail.portStatus == 6">{{i18('剩余时间')}}</span>
  146. <span v-else>{{$t('charge.chargetime')}}</span></view>
  147. <view class="demo-layout bg-purple"
  148. style="border-radius: 8px;background-color: aliceblue;color: #000;">
  149. <view >{{ chargeTime }}{{ i18('分钟') }}</view>
  150. </view>
  151. </view>
  152. </view>
  153. <view span="2" style=";left:34vw;position: absolute">
  154. <view v-if="portDetail.portStatus == 2"
  155. style="text-align: center;position: absolute;margin:-1vh 2vw;border: 0ch;height: 20vh;">
  156. <u-button @click="toPage()" shape="circle"
  157. style="background: #ec3e41;color:white;width: 28vw;border: 0ch;height: 6vh;">STOP</u-button>
  158. </view>
  159. <view v-if="portDetail.portStatus != 2"
  160. style="text-align: center;position: absolute;margin:-1vh 2vw;border: 0ch;height: 20vh;">
  161. <u-button @click="toPage()" shape="circle"
  162. style="background: #57B03D;color:white;width: 28vw;border: 0ch;height: 6vh;">Charge</u-button>
  163. </view>
  164. <!-- <view class="control-btn" @click="trigger()" v-if="portDetail.portStatus == 2">
  165. <image class="btn-image" src="/static/images/new/start/stop.png" >
  166. </image>
  167. <view>{{ i18('停止充电') }}</view>
  168. </view>
  169. <view class="control-btn" @click="trigger()" v-if="portDetail.portStatus != 2">
  170. <image class="btn-image" src="/static/images/new/start/using.png" >
  171. </image>
  172. <view>{{ i18('立即充电') }}</view>
  173. </view> -->
  174. </view>
  175. <view span="3" style="width: 26vw;left:65%;position: absolute">
  176. <view style="margin-left: 3vw;font-size: 11px;">
  177. <view style="font-weight: bold;"> Ampere</view>
  178. <view class="demo-layout bg-purple"
  179. style="border-radius: 8px;background-color: aliceblue;color: #000;">
  180. <view v-if="deviceV == 0">0A</view>
  181. <view v-else>{{currentValue}}A</view>
  182. </view>
  183. </view>
  184. </view>
  185. </view>
  186. </view>
  187. <view style="display: flex;align-items: center;justify-content: center;margin-top: 0vh;">
  188. <view @click="toSetting">
  189. <image src="../../../static/images/new/starts/status/Setting.png"
  190. style="width: 60px;height: 60px;margin: 2vh 2vh;"></image>
  191. </view>
  192. <!-- <view class="" @click="wifi">
  193. <image src="../../../static/images/new/starts/status/WiFi.png"
  194. style="width: 60px;height: 60px;margin: 2vh 0.2vh;"></image>
  195. </view> -->
  196. <!-- <view class="">
  197. <image src="../../../static/images/new/starts/status/Lock/Unlocked.png"
  198. style="width: 60px;height: 60px;margin: 2vh 2vh;"></image>
  199. </view> -->
  200. <view class="" @click="getInfo">
  201. <image src="../../../static/images/new/starts/status/Refresh.png"
  202. style="width: 60px;height: 60px;margin: 2vh 2vh;;"></image>
  203. </view>
  204. <!-- <view class="">
  205. <image src="../../../static/images/new/starts/status/Link.png"
  206. style="width: 60px;height: 60px;margin: 2vh 0.2vh;"></image>
  207. </view> -->
  208. </view>
  209. <view style="position:fixed;bottom:10px;display: flex;align-items: center;justify-content: center;text-align: center;left:0px;right:0px;">
  210. <view @click="skipPage(0)">
  211. <image src="../../../static/images/new/starts/tabbar/one_off.png"
  212. style="width: 60px;height: 60px;margin: 2vh 0.2vh;"></image>
  213. </view>
  214. <view @click="skipPage(1)">
  215. <image src="../../../static/images/new/starts/tabbar/two_off.png"
  216. style="width: 60px;height: 60px;margin: 2vh 0.2vh;"></image>
  217. </view>
  218. <view @click="skipPage(2)">
  219. <image src="../../../static/images/new/starts/tabbar/three_off.png"
  220. style="width: 60px;height: 60px;margin: 2vh 0.2vh;"></image>
  221. </view>
  222. </view>
  223. <!-- <view style="display: flex;flex-direction: row;margin:0 33%;" v-if="curPort.length>1">
  224. <view class="port_item" :class="item.id==choosePort?'selected_item':''" v-for="item in curPort"
  225. @click="selectPort(item.id);">{{ i18(item.text )}}</view>
  226. </view>
  227. <view class="dstatus">
  228. <view class="ditem">
  229. <image class="itemimg" src="/static/images/new/tmp.png" />
  230. <view class="item-value">{{deviceTemp}}℃</view>
  231. <span class="item-text">{{$t('charge.devtemper')}}</span>
  232. </view>
  233. <view class="ditem">
  234. <image class="itemimg" src="/static/images/new/dianya.png" />
  235. <view class="item-value">{{ deviceV }}V</view>
  236. <span class="item-text">{{$t('charge.voltage')}}</span>
  237. </view>
  238. <view class="ditem">
  239. <image class="itemimg" src="/static/images/new/dianliu.png" />
  240. <view class="item-value" v-if="deviceV == 0">0A</view>
  241. <view class="item-value" v-else>{{currentValue}}A</view>
  242. <span class="item-text">{{$t('charge.current')}}</span>
  243. </view>
  244. <view class="ditem">
  245. <image class="itemimg" src="/static/images/new/shjian.png" />
  246. <view class="item-value">{{ chargeTime }}{{ i18('分钟') }}</view>
  247. <span class="item-text" v-if="portDetail.portStatus == 6">{{i18('剩余时间')}}</span>
  248. <span class="item-text" v-else>{{$t('charge.chargetime')}}</span>
  249. </view>
  250. <view class="ditem">
  251. <image class="itemimg" src="/static/images/new/gonglv.png" />
  252. <view class="item-value">{{ gonglv }}W</view>
  253. <span class="item-text">{{$t('charge.power')}}</span>
  254. </view>
  255. <view class="ditem">
  256. <image class="itemimg" src="/static/images/new/dianliang.png" />
  257. <view class="item-value" v-if="portDetail.voltage == 0">0 {{ i18('度') }}</view>
  258. <view class="item-value" v-else>{{ dianliang }} {{ i18('度') }}</view>
  259. <span class="item-text">{{$t('charge.elec')}}</span>
  260. </view>
  261. </view>
  262. <view class="dbtns">
  263. <view class="start" @click="toPage">
  264. <image style="width:25px;height: 25px;margin-right: 5px;" src="/static/images/new/start.png" />
  265. <span>{{$t('charge.startcharge')}}</span>
  266. </view>
  267. <view class="get" @click="getInfo">
  268. <image style="width:25px;height: 25px;margin-right: 5px;" src="/static/images/new/get.png" />
  269. <span>{{$t('charge.getinfo')}}</span>
  270. </view>
  271. </view> -->
  272. <!-- <view class="dtip">
  273. <view style="margin:10px 0px;color: #1A87FF;"><img style="width: 13px;height: 13px"
  274. src="/static/images/new/tip.png">{{i18('温馨提示')}}</view>
  275. <view>1,{{i18('桩控制最大输出电流,当功率没有达到请检查车的状态或者车的设置')}};</view>
  276. <view>2,{{i18('启动充电-&gt;设备管理->可设置设备最大输出电流')}}</view>
  277. <view>3,{{i18('为保障您远程启动正常充电,请确保枪头完全连接充电口,同时确认您的爱车处于立即充电状态下')}};</view>
  278. <view>4,{{i18('注意规范安全充电,停好车,锁好车。')}}</view>
  279. </view> -->
  280. </view>
  281. </template>
  282. <script>
  283. import {
  284. getDeviceInfo,
  285. getPortDetail,
  286. startCharge,
  287. stopCharge,
  288. sendPortDetailCmd,
  289. checkStatusChange,
  290. getPlanInfo,
  291. cancelPlan
  292. } from "@/api/device/device";
  293. import websocket from '@/utils/websocket'
  294. import i18 from '@/utils/i18.js'
  295. export default {
  296. data() {
  297. return {
  298. refreshTimer: null,
  299. curPort: [],
  300. chargeTime: 0,
  301. deviceTemp: 0,
  302. deviceV: 0,
  303. currentValue: 0,
  304. gonglv: 0,
  305. dianliang: 0,
  306. portStatus: 0,
  307. deviceInfo: {},
  308. visitTime: "",
  309. timer: null,
  310. showPort: false,
  311. portDetail: {
  312. portStatus: 0,
  313. POWER: 0,
  314. voltage: 0
  315. },
  316. statusTimer: "",
  317. connected: false,
  318. scriptTask: null,
  319. choosePort: 1,
  320. portList: [
  321. [{
  322. port: 1,
  323. text: "端口一"
  324. }]
  325. ],
  326. planInfo: null,
  327. days: ["", "周一", "周二", "周三", "周四", "周五", "周六", "周日"],
  328. clickRightTag: 0,
  329. show:false,
  330. timeFlg:true
  331. }
  332. },
  333. computed: {
  334. imgUrl() {
  335. return getApp().globalData.config.imgUrl;
  336. }
  337. },
  338. onLoad(opt) {
  339. this.deviceInfo.deviceId = opt.id;
  340. this.deviceInfo.ccid = opt.ccid;
  341. this.deviceInfo.qrcode = opt.qrcode;
  342. this.startTimer();
  343. },
  344. onShow() {
  345. this.getInfo();
  346. this.getPlanInfo();
  347. },
  348. onUnload() {
  349. this.closeSocket();
  350. if (this.refreshTimer != null) {
  351. clearTimeout(this.refreshTimer)
  352. }
  353. },
  354. mounted: function() {
  355. this.drawCircle(25);
  356. this.drawProgressbg();
  357. //参数为1-100
  358. this.drawLine();
  359. },
  360. methods: {
  361. resetMainboard() {
  362. let deviceId = this.deviceId;
  363. // 恢复默认配置
  364. let self = this;
  365. this.$modal.loading("正在重置,请稍等...");
  366. reset({deviceId:deviceId,ccid:this.ccid}).then(res => {
  367. this.$modal.loading("正在重置,请稍等...");
  368. setTimeout(function(){
  369. self.sendMainboardCmd();
  370. },5000)
  371. })
  372. },
  373. skipPage(type){
  374. if(type==0){
  375. uni.navigateTo({
  376. url:'/pages/index'
  377. })
  378. }else if(type==1){
  379. uni.navigateTo({
  380. url:'/pages/weitiandi/deviceList'
  381. })
  382. }else if(type==2){
  383. uni.navigateTo({
  384. url:'/pages/mine/index'
  385. })
  386. }else{
  387. this.$modal.showToast("功能开发中..");
  388. }
  389. },
  390. handleLogout() {
  391. this.$modal.confirm('确定注销并退出系统吗?').then(() => {
  392. this.$store.dispatch('LogOut').then(() => {
  393. uni.setStorageSync("loginInfo",'');
  394. this.$tab.reLaunch('/pages/index')
  395. })
  396. })
  397. },
  398. close(){
  399. this.show=false
  400. },
  401. open(){
  402. this.show=true
  403. },
  404. // clickRight() {
  405. // this.show=true
  406. // },
  407. // changeDrawer(event) {
  408. // if (event) {
  409. // // 抽屉打开时的逻辑
  410. // this.clickRightTag = 1
  411. // } else {
  412. // // 抽屉关闭时的逻辑
  413. // this.clickRightTag = 0
  414. // }
  415. // },
  416. // //自定义头右操作函数
  417. clickRight() {
  418. //打开抽屉
  419. this.show=!this.show
  420. // if (this.clickRightTag == 0) {
  421. // this.show=true
  422. // this.clickRightTag = 1
  423. // } else {
  424. // this.show=false
  425. // this.clickRightTag = 0
  426. // }
  427. },
  428. //开始充电按钮
  429. trigger() {
  430. let portStatus = this.portDetail.portStatus;
  431. if (portStatus == 2) { //需要停止充电
  432. this.$modal.confirm("需要停止充电么?").then(res => {
  433. this.stopCharge();
  434. })
  435. } else {
  436. if (portStatus == 1) {
  437. this.$modal.msg("请先将充电枪插入后再点击充电");
  438. }
  439. if (portStatus == 5) {
  440. this.$modal.confirm("确认开始充电么?").then(res => {
  441. this.startCharge();
  442. })
  443. }
  444. }
  445. },
  446. drawProgressbg: function() {
  447. // 自定义组件实例 this ,表示在这个自定义组件下查找拥有 canvas-id 的 <canvas/>
  448. var ctx = uni.createCanvasContext('cpbg', this);
  449. ctx.setLineWidth(20); // 设置圆环的宽度
  450. ctx.setStrokeStyle('#35383A'); // 设置圆环的颜色
  451. // ctx.setLineCap('round'); // 设置圆环端点的形状
  452. ctx.setLineCap('square'); // 设置圆环端点的形状
  453. ctx.beginPath(); //开始一个新的路径
  454. ctx.arc(100, 100, 90, 0 * Math.PI, 2 * Math.PI, false);
  455. //设置一个原点(110,110),半径为100的圆的路径到当前路径
  456. ctx.stroke(); //对当前路径进行描边
  457. ctx.draw();
  458. },
  459. drawCircle: function(step) {
  460. var ctx = uni.createCanvasContext('cpbar', this);
  461. // 进度条的渐变(中心x坐标-半径-边宽,中心Y坐标,中心x坐标+半径+边宽,中心Y坐标)
  462. var gradient = ctx.createLinearGradient(0, 0, 120, 0);
  463. let increase = 0.15;
  464. let end = (150 /100) * 2 * Math.PI ; // 最后的角度
  465. let current = (50 / 100) * 2 * Math.PI-Math.PI/2 ; // 起始角度
  466. if(this.portDetail.portStatus == 2){
  467. if(this.timeFlg){
  468. this.timeFlg=false
  469. let timer = setInterval(() => {
  470. gradient.addColorStop('0', '#57B03D');
  471. gradient.addColorStop('1.0', '#57B03D');
  472. ctx.setLineWidth(10);
  473. ctx.setStrokeStyle(gradient);
  474. ctx.setLineCap('square');
  475. ctx.beginPath();
  476. // 参数step 为绘制的百分比
  477. if (current < end) {
  478. current = current + increase;
  479. }
  480. if (current >= end) {
  481. //current = end;
  482. if(this.portDetail.portStatus != 2){
  483. clearInterval(timer);
  484. this.timeFlg=true
  485. }else{
  486. end = (150 /100) * 2 * Math.PI ; // 最后的角度
  487. current = (50 / 100) * 2 * Math.PI-Math.PI/2 ; // 起始角度
  488. }
  489. }
  490. ctx.arc(100, 100, 90, (50 / 100) * 2 * Math.PI-Math.PI/2, current, false);
  491. ctx.stroke();
  492. ctx.draw();
  493. }, 20);
  494. }
  495. }
  496. },
  497. toPage() {
  498. let imei = this.deviceInfo.deviceId;
  499. let ccid = this.deviceInfo.ccid;
  500. this.closeSocket();
  501. uni.navigateTo({
  502. url: '/pages/weitiandi/device/index?id=' + imei + '&ccid=' + ccid
  503. });
  504. },
  505. toSetting(){
  506. let imei = this.deviceInfo.deviceId;
  507. let ccid = this.deviceInfo.ccid;
  508. this.closeSocket();
  509. uni.navigateTo({
  510. url: '/pages/weitiandi/device/setting?id=' + imei + '&ccid=' + ccid
  511. });
  512. },
  513. i18(text) {
  514. return i18(text)
  515. },
  516. planCharge() {
  517. if (this.planInfo != null) {
  518. this.$modal.confirm("确认取消预约?").then(res => {
  519. this.cancelPlan();
  520. })
  521. } else {
  522. this.toPlan()
  523. }
  524. },
  525. cancelPlan() {
  526. cancelPlan(this.planInfo.id).then(res => {
  527. this.$modal.msg("取消成功");
  528. this.planInfo = null;
  529. this.getPlanInfo();
  530. })
  531. },
  532. getPlanInfo() {
  533. getPlanInfo(this.deviceInfo.deviceId, this.choosePort).then(res => {
  534. let data = res.data;
  535. if (data != null) {
  536. let planType = data.planType;
  537. if (planType == 1) { //单次预约
  538. let planInfo = {};
  539. planInfo.runTime = data.runTime;
  540. this.planInfo = planInfo;
  541. this.planInfo.id = data.id;
  542. } else {
  543. let planInfo = {};
  544. planInfo.runTime = data.runTime;
  545. let repeatDays = data.repeatDays;
  546. let days = repeatDays.split(",")
  547. let strs = "";
  548. for (let i = 0; i < days.length; i++) {
  549. if (strs.length > 0) {
  550. strs += ",";
  551. }
  552. strs += this.days[days[i]];
  553. }
  554. this.planInfo = planInfo;
  555. this.planInfo.runTime = strs + " " + data.repeatTime;
  556. this.planInfo.id = data.id;
  557. }
  558. }
  559. })
  560. },
  561. startTimer() {
  562. let self = this;
  563. if (this.refreshTimer != null) {
  564. clearTimeout(this.refreshTimer);
  565. }
  566. self.refreshTimer = setTimeout(function() {
  567. self.getInfo();
  568. self.startTimer();
  569. }, 30000);
  570. },
  571. confirmPort(e) {
  572. let value = e.value[0]
  573. this.choosePort = value.port;
  574. this.showPort = false;
  575. this.getInfo()
  576. },
  577. parsePortCmd(real_data) {
  578. let self = this;
  579. self.portDetail = real_data;
  580. self.portList = [
  581. []
  582. ];
  583. self.curPort = [];
  584. let port_first_status = self.portDetail["port_first_status"];
  585. let port_second_status = self.portDetail["port_second_status"]
  586. if (port_first_status) {
  587. self.portList[0].push({
  588. port: 1,
  589. text: "端口一"
  590. });
  591. self.curPort.push({
  592. text: "端口一",
  593. status: port_first_status,
  594. id: 1,
  595. })
  596. let power = self.portDetail.power;
  597. let voltage = parseInt(self.portDetail.voltage);
  598. if (voltage > 0) {
  599. let current = power / voltage;
  600. current = current.toFixed(1);
  601. self.portDetail.currentValue = current;
  602. }
  603. }
  604. if (port_second_status) {
  605. self.portList[0].push({
  606. port: 2,
  607. text: "端口二"
  608. });
  609. self.curPort.push({
  610. text: "端口二",
  611. status: port_second_status,
  612. id: 2
  613. })
  614. let power = self.portDetail.power_1;
  615. let voltage = parseInt(self.portDetail.voltage);
  616. if (voltage > 0) {
  617. let current = power / voltage;
  618. current = current.toFixed(1);
  619. self.portDetail.currentValue_1 = current;
  620. }
  621. }
  622. let choosePort = self.choosePort
  623. /**
  624. * chargeTime:0,
  625. * deviceTemp:0,
  626. * deviceV:0,
  627. * currentValue:0,
  628. * gonglv:0,
  629. * dianliang:0,
  630. * portStatus:0,
  631. */
  632. if (choosePort == 1) {
  633. self.portDetail.portStatus = port_first_status;
  634. self.chargeTime = self.portDetail.time;
  635. self.gonglv = self.portDetail.power;
  636. self.dianliang = self.portDetail.elec / 100;
  637. self.currentValue = self.portDetail.currentValue;
  638. if (port_first_status != 2) {
  639. self.chargeTime = 0;
  640. if (port_first_status == 6) {
  641. self.chargeTime = self.portDetail.time;
  642. }
  643. self.gonglv = 0;
  644. self.dianliang = 0;
  645. self.currentValue = 0;
  646. }
  647. } else if (choosePort == 2) {
  648. self.portDetail.portStatus = port_second_status;
  649. self.chargeTime = self.portDetail.time_1;
  650. self.gonglv = self.portDetail.power_1;
  651. self.dianliang = self.portDetail.elec_1 / 100;
  652. self.currentValue = self.portDetail.currentValue_1;
  653. if (port_second_status != 2) {
  654. self.chargeTime = 0;
  655. if (port_first_status == 6) {
  656. self.chargeTime = self.portDetail.time_1;
  657. }
  658. self.gonglv = 0;
  659. self.dianliang = 0;
  660. self.currentValue = 0;
  661. }
  662. }
  663. self.portStatus = self.portDetail.portStatus;
  664. self.deviceTemp = self.portDetail.dev_temper;
  665. self.deviceV = self.portDetail.voltage;
  666. self.$modal.closeLoading();
  667. if(self.portDetail.portStatus==2){
  668. this.drawCircle(25);
  669. }
  670. },
  671. initSocket(key) {
  672. let self = this;
  673. let socketUrl = getApp().globalData.config.socketUrl
  674. this.scriptTask = websocket({
  675. url: "/" + key + "/",
  676. });
  677. let scriptTask = this.scriptTask;
  678. scriptTask.onOpen(function(res) {
  679. console.log('WebSocket连接已打开!');
  680. self.connected = true;
  681. });
  682. scriptTask.onError(function(res) {
  683. self.connected = false;
  684. console.log(res);
  685. });
  686. scriptTask.onMessage(function(res) {
  687. let data = JSON.parse(res.data);
  688. let type = data.type;
  689. let real_data = data.real_data;
  690. if (type == 103) {
  691. self.parsePortCmd(real_data);
  692. }
  693. if (type == 116) {
  694. self.$modal.closeLoading();
  695. self.getInfo();
  696. }
  697. if (type == 113) {
  698. self.$modal.closeLoading();
  699. self.getInfo();
  700. }
  701. if (type == 96) {
  702. self.mainBoardInfo = real_data;
  703. self.formatMainboardData();
  704. self.$modal.closeLoading();
  705. }
  706. self.$forceUpdate();
  707. console.log('收到服务器内容:' + JSON.stringify(data));
  708. });
  709. scriptTask.onClose(function(res) {
  710. console.log('WebSocket 已关闭!');
  711. });
  712. },
  713. toSet() {
  714. this.closeSocket();
  715. uni.navigateTo({
  716. url: '/pages/weitiandi/device/setting?id=' + this.deviceInfo.deviceId + "&ccid=" + this
  717. .deviceInfo.ccid
  718. });
  719. },
  720. toPlan() {
  721. uni.navigateTo({
  722. url: '/pages/weitiandi/device/plan?port=' + this.choosePort + '&id=' + this.deviceInfo
  723. .deviceId + "&ccid=" + this.deviceInfo.ccid
  724. });
  725. },
  726. trigger() {
  727. let portStatus = this.portDetail.portStatus;
  728. if (portStatus == 2) { //需要停止充电
  729. this.$modal.confirm("需要停止充电么?").then(res => {
  730. this.stopCharge();
  731. this.drawCircle(0);
  732. })
  733. } else {
  734. if (portStatus == 1) {
  735. this.$modal.msg("请先将充电枪插入后再点击充电");
  736. }
  737. if (portStatus == 5) {
  738. this.$modal.confirm("确认开始充电么?").then(res => {
  739. this.startCharge();
  740. this.drawCircle(50); //参数为1-100
  741. })
  742. }
  743. }
  744. },
  745. getInfo() {
  746. let self = this;
  747. this.$modal.loading("正在获取状态,请稍等...",true);
  748. sendPortDetailCmd(this.deviceInfo).then(res => {
  749. this.$modal.loading("正在获取状态,请稍等...",true);
  750. this.visitTime = res.msg;
  751. if (!this.visitTime) {
  752. this.$modal.msg("请重新进入页面");
  753. return;
  754. }
  755. if (!this.scriptTask) {
  756. this.initSocket(this.deviceInfo.deviceId);
  757. }
  758. setTimeout(function() {
  759. getPortDetail(self.deviceInfo, self.visitTime).then(res => {
  760. let data = res.data;
  761. if (data != null) {
  762. self.parsePortCmd(data);
  763. } else {}
  764. });
  765. }, 500)
  766. })
  767. this.drawCircle(25)
  768. },
  769. stopCharge() {
  770. let self = this;
  771. this.deviceInfo.port = this.choosePort;
  772. stopCharge(this.deviceInfo).then(() => {
  773. self.$modal.loading("停止成功");
  774. setTimeout((() => {
  775. self.getInfo();
  776. }), 1000);
  777. })
  778. },
  779. startCharge() {
  780. let self = this;
  781. this.deviceInfo.port = this.choosePort;
  782. startCharge(this.deviceInfo).then(res => {
  783. self.$modal.loading("启动成功");
  784. setTimeout((() => {
  785. self.getInfo();
  786. }), 1000);
  787. })
  788. },
  789. getPortInfo() {
  790. this.startPortDetailTimer();
  791. },
  792. startPortDetailTimer() {
  793. let self = this;
  794. this.timer = setTimeout(function() {
  795. getPortDetail(self.deviceInfo, self.visitTime).then(res => {
  796. let data = res.data;
  797. if (data != null) {
  798. self.portDetail = data;
  799. self.checkStatusCheck();
  800. self.$modal.closeLoading();
  801. } else {
  802. self.startPortDetailTimer();
  803. }
  804. });
  805. }, 1000);
  806. },
  807. checkStatusCheck() {
  808. this.statusChangeTimer();
  809. },
  810. checkOnPage() {
  811. var pages = getCurrentPages() // 获取栈实例
  812. let currentRoute = pages[pages.length - 1].route; // 获取当前页面路由
  813. if ("pages/weitiandi/device/index" != currentRoute) {
  814. return false;
  815. }
  816. return true;
  817. },
  818. closeSocket() {
  819. this.scriptTask.close();
  820. this.scriptTask = null;
  821. },
  822. statusChangeTimer() {
  823. let self = this;
  824. this.statusTimer = setTimeout(function() {
  825. if (!this.checkOnPage()) {
  826. return;
  827. }
  828. checkStatusChange(self.deviceInfo, self.visitTime).then(res => {
  829. let data = res.data;
  830. if (data != null) {
  831. self.getInfo();
  832. } else {
  833. self.statusChangeTimer();
  834. }
  835. });
  836. }, 3000);
  837. },
  838. wifi() {
  839. uni.navigateTo({
  840. url: '/pages/bluetooth/index/wifi'
  841. });
  842. },
  843. }
  844. }
  845. </script>
  846. <style>
  847. .container {
  848. /* //background: rgb(208, 208, 208); */
  849. background-image: url('../../../static/images/new/starts/bg1.jpg');
  850. inset: 0;
  851. position: absolute;
  852. background-size: cover;
  853. background-repeat: no-repeat;
  854. }
  855. .prop-item {
  856. position: relative;
  857. display: flex;
  858. flex-direction: row;
  859. height: 40px;
  860. line-height: 40px;
  861. margin: 0 20rpx;
  862. }
  863. .prop-item-left {
  864. color: #BCBCBF;
  865. ;
  866. width: 30%;
  867. font-size: 14px;
  868. //margin-left: 36px;
  869. }
  870. .prop-item-image {
  871. width: 15px;
  872. height: 15px;
  873. position: absolute;
  874. left: 2vw;
  875. top: 0.5vh;
  876. }
  877. .prop-item-right {
  878. position: absolute;
  879. right: 10rpx;
  880. top: 5rpx;
  881. color: #BCBCBF;
  882. }
  883. .progress_box {
  884. /* position: relative; */
  885. width: 52vw;
  886. height: 35vh;
  887. /* background-color: red; */
  888. display: flex;
  889. text-align: center;
  890. flex-direction: row;
  891. }
  892. .pcds {
  893. margin-top: 90rpx;
  894. color: black;
  895. }
  896. .progress_bg {
  897. position: absolute;
  898. width: 60vw;
  899. height: 50vh;
  900. }
  901. .progress_txt {
  902. position: absolute;
  903. z-index: 99;
  904. width: 55vw;
  905. /* text-align: center;
  906. font-size: 28upx;
  907. margin: 16vw;
  908. /* margin-top: 54px;
  909. margin-left: 74px;
  910. color: #999999; */
  911. }
  912. .progress_bar {
  913. position: absolute;
  914. width: 60vw;
  915. margin: 2px;
  916. height: 50vh;
  917. }
  918. .progress-barup{
  919. position: absolute;
  920. width: 200px;
  921. margin: 2px;
  922. height: 196px;
  923. z-index: 1;
  924. }
  925. .progress_line {
  926. position: absolute;
  927. width: 60vw;
  928. height: 50vh;
  929. }
  930. .progress_info {
  931. display: flex;
  932. font-size: 10px;
  933. margin: 70px 30px;
  934. align-items: center;
  935. flex-direction: column;
  936. /* height: 14vh; */
  937. width: 35vw;
  938. }
  939. .header {
  940. position: relative;
  941. margin-top: 4vw;
  942. }
  943. .header-status-desc {
  944. position: absolute;
  945. text-align: center;
  946. width: 100%;
  947. bottom: 1vh;
  948. font-size: 5vw;
  949. font-weight: bold;
  950. color: #0E9F9B;
  951. margin-bottom: 5vw;
  952. }
  953. .header-status {
  954. font-weight: bold;
  955. text-align: center;
  956. }
  957. .chong-active {
  958. color: #0E9F9B
  959. }
  960. .header-img {
  961. width: 100%;
  962. padding: 5% 10%;
  963. text-align: center;
  964. }
  965. .header-img image {
  966. width: 100%;
  967. height: 23vh;
  968. }
  969. .info-body {
  970. background: #0E9F9B;
  971. height: 20vh;
  972. margin: 0 2%;
  973. border-radius: 1vw;
  974. margin-top: 2vh;
  975. color: #F8FCFF;
  976. line-height: 3vh;
  977. }
  978. .info-content {
  979. display: inline-block;
  980. width: 23%;
  981. text-align: center;
  982. margin: 1%;
  983. margin-top: 2.5vh;
  984. }
  985. .info-content-value {
  986. font-weight: bold;
  987. }
  988. .info-content-text {}
  989. .info-summary {
  990. display: flex;
  991. flex-direction: row;
  992. text-align: center;
  993. margin: 3vh 0;
  994. }
  995. .summary {
  996. width: 33%;
  997. line-height: 2.5vh;
  998. }
  999. .charge-num {
  1000. color: #0E9F9B;
  1001. font-weight: bold;
  1002. font-size: 4.5vw;
  1003. }
  1004. .charge-title {
  1005. color: #B2B2B2;
  1006. font-weight: 400;
  1007. }
  1008. .btn-image {
  1009. width: 90%;
  1010. height: 100%;
  1011. }
  1012. .info-bottom-btn {
  1013. display: flex;
  1014. flex-direction: row;
  1015. text-align: center;
  1016. position: relative;
  1017. margin-top: 10vh;
  1018. }
  1019. .btn-area {
  1020. width: 50%;
  1021. height: 50px;
  1022. }
  1023. .left {
  1024. position: relative;
  1025. left: 10px;
  1026. text-align: right;
  1027. }
  1028. .right {
  1029. text-align: left;
  1030. position: relative;
  1031. right: 10px;
  1032. }
  1033. .info-plan {
  1034. text-align: center;
  1035. color: #0E9F9B;
  1036. margin-top: 1vh;
  1037. font-weight: 400;
  1038. }
  1039. .setting {
  1040. position: fixed;
  1041. right: -1px;
  1042. top: 10vh;
  1043. z-index: 999;
  1044. background: rgb(227, 243, 245);
  1045. color: #0E9F9B;
  1046. font-size: 10px;
  1047. border-radius: 5px;
  1048. padding: 3px;
  1049. }
  1050. .port {
  1051. height: 70px;
  1052. background: #F8FCFF;
  1053. border: 0px solid #F8FCFF;
  1054. box-shadow: 0px 0px 6px 1px rgba(101, 101, 101, 0.29);
  1055. border-radius: 4px;
  1056. margin: 0 10px;
  1057. position: relative;
  1058. margin-top: 10px;
  1059. }
  1060. .plan {
  1061. height: 70px;
  1062. background: #F8FCFF;
  1063. border: 0px solid #F8FCFF;
  1064. box-shadow: 0px 0px 6px 1px rgba(101, 101, 101, 0.29);
  1065. border-radius: 4px;
  1066. margin: 0 10px;
  1067. position: relative;
  1068. margin-top: 15px;
  1069. }
  1070. .port-image {
  1071. height: 40px;
  1072. width: 40px;
  1073. position: absolute;
  1074. top: 15px;
  1075. left: 20px;
  1076. }
  1077. .port-text {
  1078. position: absolute;
  1079. top: 13px;
  1080. left: 75px;
  1081. font-weight: bold;
  1082. }
  1083. .port-num {
  1084. position: absolute;
  1085. top: 38px;
  1086. left: 75px;
  1087. color: #B2B2B2;
  1088. }
  1089. .port-icon {
  1090. position: absolute;
  1091. top: 30px;
  1092. right: 5px;
  1093. width: 10px;
  1094. height: 16px;
  1095. }
  1096. .port-icon image {
  1097. width: 90%;
  1098. }
  1099. .body-bottom {
  1100. padding: 0 22px;
  1101. }
  1102. .body-bottom .info-content {
  1103. width: 30%;
  1104. }
  1105. .bottom-control {
  1106. height: 22vh;
  1107. margin: 0 2%;
  1108. margin-top: 2vh;
  1109. line-height: 3vh;
  1110. background: #F8FCFF;
  1111. border: 0px solid #F8FCFF;
  1112. box-shadow: 0px 0px 6px 1px rgba(101, 101, 101, 0.29);
  1113. border-radius: 4px;
  1114. padding: 3%;
  1115. }
  1116. .control-btn {
  1117. display: inline-block;
  1118. ;
  1119. height: 60px;
  1120. width: 25%;
  1121. padding: 10px 20px;
  1122. text-align: center;
  1123. font-size: 12px;
  1124. color: black;
  1125. }
  1126. .control-btn .btn-image {}
  1127. #box {
  1128. /* width: 300px; */
  1129. height: 280px;
  1130. position: relative;
  1131. /* 背景色 */
  1132. /* background: #f7f6f6; */
  1133. overflow: hidden;
  1134. /* padding: 50px 0; */
  1135. box-sizing: border-box;
  1136. ;
  1137. }
  1138. .box {
  1139. width: 100%;
  1140. height: 100%;
  1141. position: absolute;
  1142. display: flex;
  1143. justify-content: center;
  1144. /* 此处尽量不要设置背景色,可以选择在父标签上设置背景色,否则没有黏黏的效果 */
  1145. filter: url("#goo");
  1146. }
  1147. /* 电量文字 */
  1148. .text {
  1149. font-weight: 200;
  1150. font-size: 20px;
  1151. margin-top: 5px;
  1152. text-align: center;
  1153. color: #ff6600;
  1154. }
  1155. /* 电量文字 */
  1156. .text span {
  1157. font-size: 15px;
  1158. }
  1159. /* 顶部的两个旋转小球 */
  1160. .top_ball {
  1161. width: 200px;
  1162. height: 200px;
  1163. border-radius: 35%;
  1164. opacity: 0.5;
  1165. position: absolute;
  1166. top: 20px;
  1167. z-index: 10;
  1168. /* 从中心向外剪切圆,相当于掏空 */
  1169. -webkit-mask: radial-gradient(transparent 95px, white 0px);
  1170. }
  1171. /* 顶部的两个旋转小球 */
  1172. .top_ball.one {
  1173. background: var(--c);
  1174. animation: ballZhuan 5s linear infinite;
  1175. }
  1176. /* 顶部的两个旋转小球 */
  1177. .top_ball.two {
  1178. background: var(--c);
  1179. animation: ballZhuan 8s linear infinite;
  1180. }
  1181. .three {
  1182. width: 170px;
  1183. height: 170px;
  1184. border-radius: 300px;
  1185. opacity: 1;
  1186. position: absolute;
  1187. top: 20px;
  1188. z-index: 10;
  1189. /* 从中心向外剪切圆,相当于掏空 */
  1190. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  1191. background: #ffffff;
  1192. /* animation: ballZhuan 9s linear infinite; */
  1193. overflow: hidden;
  1194. box-shadow: 0px 0px 19px 1px #2196f3;
  1195. }
  1196. .four {
  1197. width: 200px;
  1198. height: 200px;
  1199. border-radius: 80px;
  1200. opacity: 0.3;
  1201. position: absolute;
  1202. top: 10px;
  1203. z-index: 10;
  1204. /* 从中心向外剪切圆,相当于掏空 */
  1205. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  1206. background: #2196f3;
  1207. animation: ballZhuan1 linear infinite;
  1208. animation-duration: 11s;
  1209. }
  1210. .five {
  1211. width: 270px;
  1212. height: 270px;
  1213. border-radius: 99px;
  1214. opacity: 0.6;
  1215. position: absolute;
  1216. top: 30px;
  1217. z-index: 10;
  1218. /* 从中心向外剪切圆,相当于掏空 */
  1219. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  1220. background: #2196f3;
  1221. animation: ballZhuan1 linear infinite;
  1222. /* transform: rotate(120deg); */
  1223. animation-duration: 9s;
  1224. left: -67px;
  1225. }
  1226. .six {
  1227. width: 270px;
  1228. height: 270px;
  1229. border-radius: 99px;
  1230. opacity: 0.6;
  1231. position: absolute;
  1232. top: 30px;
  1233. z-index: 10;
  1234. /* 从中心向外剪切圆,相当于掏空 */
  1235. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  1236. background: #2196f3;
  1237. animation: ballZhuan1 7s linear infinite;
  1238. /* transform: rotate(120deg); */
  1239. right: -67px;
  1240. }
  1241. @keyframes ballZhuan {
  1242. 100% {
  1243. transform: rotate(360deg);
  1244. }
  1245. }
  1246. @keyframes ballZhuan1 {
  1247. 100% {
  1248. transform: rotate(360deg);
  1249. }
  1250. }
  1251. /* 底部的小球 */
  1252. .dot {
  1253. display: block;
  1254. width: 20px;
  1255. height: 20px;
  1256. border-radius: 50%;
  1257. background: rgba(101, 192, 255, 0.28);
  1258. position: absolute;
  1259. z-index: 1000;
  1260. bottom: -50px;
  1261. }
  1262. .dot:nth-of-type(1) {
  1263. width: 40px;
  1264. height: 40px;
  1265. right: 116px;
  1266. animation: dotMove 5s linear infinite;
  1267. }
  1268. .dot:nth-of-type(2) {
  1269. width: 50px;
  1270. height: 50px;
  1271. left: 120px;
  1272. animation: dotMove 4s linear infinite;
  1273. }
  1274. .dot:nth-of-type(3) {
  1275. animation: dotMove 2s linear infinite;
  1276. }
  1277. .dot:nth-of-type(4) {
  1278. width: 15px;
  1279. height: 15px;
  1280. left: 130px;
  1281. animation: dotMove 2s linear infinite;
  1282. }
  1283. .dot:nth-of-type(5) {
  1284. width: 30px;
  1285. height: 30px;
  1286. animation: dotMove 3s linear infinite;
  1287. }
  1288. @keyframes dotMove {
  1289. 0% {
  1290. transform: translateY(0px);
  1291. opacity: 1;
  1292. }
  1293. 98% {
  1294. opacity: 1;
  1295. }
  1296. 100% {
  1297. transform: translateY(-260px);
  1298. opacity: 0;
  1299. }
  1300. }
  1301. .w-flex {
  1302. display: -webkit-box;
  1303. display: -webkit-flex;
  1304. display: flex;
  1305. padding: 0px 25px;
  1306. }
  1307. .w-flex__item {
  1308. -webkit-box-flex: 1;
  1309. -webkit-flex: 1;
  1310. flex: 1;
  1311. }
  1312. .w-item {
  1313. text-align: center;
  1314. padding: 5px;
  1315. }
  1316. .w-item-tit {
  1317. font-size: 14px;
  1318. color: #888;
  1319. }
  1320. .w-item-num {
  1321. font-size: 18px;
  1322. color: #111;
  1323. }
  1324. .can {
  1325. position: relative;
  1326. z-index: 0;
  1327. width: 211px;
  1328. height: 211px;
  1329. background-size: cover;
  1330. display: flex;
  1331. justify-content: center;
  1332. align-items: center;
  1333. }
  1334. .dtop {
  1335. background: url(/static/images/new/box1.png);
  1336. background-size: cover;
  1337. width: 260px;
  1338. height: 236px;
  1339. display: flex;
  1340. justify-content: center;
  1341. align-items: center;
  1342. left: 15%;
  1343. position: relative;
  1344. }
  1345. .dstatus {
  1346. margin-top: 0.1rem;
  1347. display: flex;
  1348. flex-wrap: wrap;
  1349. justify-content: space-evenly;
  1350. align-content: center;
  1351. }
  1352. .ditem {
  1353. width: 30%;
  1354. display: flex;
  1355. flex-direction: column;
  1356. align-items: center;
  1357. margin-bottom: 0.3rem;
  1358. margin-top: 10px;
  1359. }
  1360. .itemimg {
  1361. width: 50px;
  1362. height: 50px;
  1363. }
  1364. .item-value {
  1365. font-weight: bold;
  1366. font-size: 15px;
  1367. margin:8px 0 0 0;
  1368. }
  1369. .item-text {
  1370. font-size: 11px;
  1371. margin: 0px 0;
  1372. color: aliceblue;
  1373. }
  1374. .start {
  1375. background: #1A87FF;
  1376. color: #fff;
  1377. width: 45%;
  1378. height: 50px;
  1379. min-height: 40px;
  1380. border-radius: 50px;
  1381. display: flex;
  1382. justify-content: center;
  1383. align-items: center;
  1384. font-size: 20px;
  1385. font-weight: bold;
  1386. }
  1387. .dbtns {
  1388. display: flex;
  1389. margin-top: 10px;
  1390. justify-content: space-between;
  1391. padding: 0 30px;
  1392. }
  1393. .get {
  1394. background: #fff;
  1395. border: 1px solid #1A87FF;
  1396. color: #1A87FF;
  1397. width: 45%;
  1398. height: 50px;
  1399. min-height: 40px;
  1400. border-radius: 50px;
  1401. display: flex;
  1402. justify-content: center;
  1403. align-items: center;
  1404. font-size: 20px;
  1405. font-weight: bold;
  1406. }
  1407. .dtip {
  1408. margin: 20px 20px;
  1409. padding: 10px;
  1410. background: rgba(127, 200, 251, 0.1);
  1411. border: 1px solid #7FC8FB;
  1412. box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.19);
  1413. border-radius: 5px;
  1414. font-size: 17px;
  1415. font-weight: 400;
  1416. color: #B8B9BA;
  1417. margin-bottom: 10px;
  1418. }
  1419. .p1 {
  1420. font-size: 20px;
  1421. color: white;
  1422. font-weight: bold;
  1423. margin-top: 10px;
  1424. /* margin-left: -1vh;; */
  1425. }
  1426. .p2{
  1427. color: #888;
  1428. font-size: 20px;
  1429. font-weight: bold;
  1430. }
  1431. .stip {
  1432. text-align: center;
  1433. z-index: 9999;
  1434. }
  1435. </style>