status.vue 37 KB

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