status.vue 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201
  1. <template>
  2. <view class="container">
  3. <view style="height: 20px;line-height:15px;padding: 2px;text-align: center;position: fixed;right: -5px;top:30px;z-index: 9999;background: rgb(243,157,116);color: white;border-radius: 5px;font-size: 10px;width: 120rpx;" @click="goBack">
  4. {{$t('charge.break')}}
  5. </view>
  6. <view v-if="locale == 'en'" style="height: 40px;line-height:15px;padding: 2px;text-align: center;position: fixed;right: -5px;top:120px;z-index: 9999;background: #1A87FF;color: white;border-radius: 5px;font-size: 10px;width: 120rpx;" @click="modifyPwd">
  7. {{$t('charge.modifypwd')}}
  8. </view>
  9. <view v-else style="height: 20px;line-height:15px;padding: 2px;text-align: center;position: fixed;right: -5px;top:120px;z-index: 9999;background: #1A87FF;color: white;border-radius: 5px;font-size: 10px;width: 120rpx;" @click="modifyPwd">
  10. {{$t('charge.modifypwd')}}
  11. </view>
  12. <view style=";position: relative;height: 250px;margin-top:2vh;">
  13. <view class="dtop">
  14. <view class="can">
  15. <view class="box">
  16. <view class="three">
  17. <view class="four"></view>
  18. <view class="five"></view>
  19. <view class="six"></view>
  20. </view>
  21. <view class="dot"></view>
  22. <view class="dot"></view>
  23. <view class="dot"></view>
  24. <view class="dot"></view>
  25. <view class="dot"></view>
  26. </view>
  27. <!-- <canvas id="c">-->
  28. <!-- </canvas>-->
  29. <view class="stip">
  30. <view class="p0" st=""></view>
  31. <view class="p1">
  32. <view v-if="portDetail.portStatus == 2">
  33. {{$t('charge.charging')}}
  34. </view>
  35. <view v-else-if="portDetail.portStatus == 6">
  36. {{$t('charge.planed')}}
  37. </view>
  38. <view v-else-if="portDetail.portStatus == 5">
  39. {{$t('charge.connected')}}
  40. </view>
  41. <view v-else>
  42. {{$t('charge.nocharge')}}
  43. </view>
  44. </view>
  45. </view>
  46. </view>
  47. </view>
  48. </view>
  49. <view class="dstatus">
  50. <view class="ditem">
  51. <image class="itemimg" src="/static/images/new/tmp.png"/>
  52. <view class="item-value">{{portDetail.dev_temper}}℃</view>
  53. <span class="item-text">{{$t('charge.devtemper')}}</span>
  54. </view>
  55. <view class="ditem">
  56. <image class="itemimg" src="/static/images/new/dianya.png"/>
  57. <view class="item-value">{{ portDetail.voltage }}V</view>
  58. <span class="item-text">{{$t('charge.voltage')}}</span>
  59. </view>
  60. <view class="ditem">
  61. <image class="itemimg" src="/static/images/new/dianliu.png"/>
  62. <view class="item-value" v-if="portDetail.voltage == 0">0A</view>
  63. <view class="item-value" v-else>{{portDetail.POWER/portDetail.voltage}}A</view>
  64. <span class="item-text">{{$t('charge.current')}}</span>
  65. </view>
  66. <view class="ditem">
  67. <image class="itemimg" src="/static/images/new/shjian.png"/>
  68. <view class="item-value">{{ portDetail.time }}{{ i18('分钟') }}</view>
  69. <span class="item-text">{{$t('charge.chargetime')}}</span>
  70. </view>
  71. <view class="ditem">
  72. <image class="itemimg" src="/static/images/new/gonglv.png"/>
  73. <view class="item-value">{{ portDetail.power }}W</view>
  74. <span class="item-text">{{$t('charge.power')}}</span>
  75. </view>
  76. <view class="ditem">
  77. <image class="itemimg" src="/static/images/new/dianliang.png"/>
  78. <view class="item-value">{{ portDetail.elec }} {{ i18('度') }}</view>
  79. <span class="item-text">{{$t('charge.elec')}}</span>
  80. </view>
  81. </view>
  82. <view class="dbtns">
  83. <view class="start" @click="toPage">
  84. <image style="width:25px;height: 25px;margin-right: 5px;" src="/static/images/new/start.png"/>
  85. <span>{{$t('charge.startcharge')}}</span>
  86. </view>
  87. <view class="get" @click="getInfo">
  88. <image style="width:25px;height: 25px;margin-right: 5px;" src="/static/images/new/get.png"/>
  89. <span>{{$t('charge.getinfo')}}</span>
  90. </view>
  91. </view>
  92. <view class="dtip">
  93. <view style="margin:10px 0px;color: #1A87FF;"><img style="width: 13px;height: 13px" src="/static/images/new/tip.png">{{i18('温馨提示')}}</view>
  94. <view>1,{{i18('桩控制最大输出电流,当功率没有达到请检查车的状态或者车的设置')}};</view>
  95. <view>2,{{i18('启动充电-&gt;设备管理->可设置设备最大输出电流')}}</view>
  96. <view>3,{{i18('为保障您远程启动正常充电,请确保枪头完全连接充电口,同时确认您的爱车处于立即充电状态下')}};</view>
  97. <view>4,{{i18('注意规范安全充电,停好车,锁好车。')}}</view>
  98. </view>
  99. <u-picker @cancel="showPort=false" @confirm="confirmPort" :show="showPort" :columns="portList" keyName="text"></u-picker>
  100. <u-picker @cancel="cancelPicker" @confirm="confirm" :show="showPlan" :columns="planCols" @change="changeHandler"></u-picker>
  101. <u-modal :show="showPwd" :confirmText="i18('确认')" :cancelText="i18('取消')" @confirm="inputPwd" @cancel="cancel" :showCancelButton="true" :title="$t('charge.modifypwd')" >
  102. <view class="slot-content">
  103. <view>
  104. <u--input
  105. type="number"
  106. :placeholder="$t('charge.oldpwd')"
  107. border="surround"
  108. v-model="oldPwd"
  109. ></u--input>
  110. </view>
  111. <view style="margin-top:5px">
  112. <u--input
  113. type="number"
  114. :placeholder="$t('charge.newpwd')"
  115. border="surround"
  116. v-model="pwd"
  117. ></u--input>
  118. </view>
  119. </view>
  120. </u-modal>
  121. <u-modal :show="showInitPwd" :confirmText="i18('确认')" :cancelText="i18('取消')" @confirm="inputPwd" @cancel="cancel" :showCancelButton="true" :title="i18('当前密码为初始密码,请修改')" >
  122. <view class="slot-content">
  123. <view style="margin-bottom:10px;">
  124. {{i18('请保存好设备序列号。可用于找回密码')}}
  125. </view>
  126. <view style="margin-bottom:10px;text-decoration: underline" @click="copyPwd">
  127. {{i18('设备序列号')}} :{{uuid}}
  128. </view>
  129. <view>
  130. <u--input
  131. type="number"
  132. :placeholder="$t('charge.oldpwd')"
  133. border="surround"
  134. v-model="oldPwd"
  135. ></u--input>
  136. </view>
  137. <view style="margin-top:5px">
  138. <u--input
  139. type="number"
  140. :placeholder="$t('charge.newpwd')"
  141. border="surround"
  142. v-model="pwd"
  143. ></u--input>
  144. </view>
  145. </view>
  146. </u-modal>
  147. </view>
  148. </template>
  149. <script>
  150. import {getDeviceInfo,getPortDetail,startCharge,stopCharge,sendPortDetailCmd,checkStatusChange,getPlanInfo,cancelPlan,parseDataObj,planCharge,getPwd,setPwd,getUUID} from "@/utils/weitiandi/device/device.js";
  151. // #ifdef APP
  152. import ecUI from '@/utils/ecUI.js'
  153. import ecBLE from '@/utils/ecBLE/ecBLE.js'
  154. // #endif
  155. // #ifdef MP
  156. const ecUI = require('@/utils/ecUI.js')
  157. const ecBLE = require('@/utils/ecBLE/ecBLE.js')
  158. // #endif
  159. import i18 from '@/utils/i18.js'
  160. let ctx
  161. let isCheckScroll = true
  162. let isCheckRevHex = false
  163. let isCheckSendHex = false
  164. let sendData = ''
  165. export default {
  166. data() {
  167. return {
  168. locale:"",
  169. oldPwd:"",
  170. pwd:"",
  171. showPwd:false,
  172. planCols:[ ],
  173. columnData:[],
  174. showPlan:false,
  175. deviceInfo:{},
  176. visitTime:"",
  177. timer:null,
  178. showPort:false,
  179. portDetail:{portStatus:0,POWER:0,voltage:0},
  180. statusTimer:"",
  181. connected:false,
  182. scriptTask:null,
  183. choosePort:1,
  184. portList:[[{port:1,text:"端口一"}]],
  185. planInfo:null,
  186. days:["","周一","周二","周三","周四","周五","周六","周日"],
  187. textRevData: '',
  188. picker:null,
  189. firstInit:false,
  190. hasRight:false,
  191. startAutoCharge:true,
  192. initPwd:"123456",
  193. showInitPwd:false,
  194. uuid:"",
  195. }
  196. },
  197. computed: {
  198. imgUrl() {
  199. return getApp().globalData.config.imgUrl;
  200. }
  201. },
  202. onLoad() {
  203. this.locale = uni.getLocale();
  204. console.log("status comeing")
  205. this.checkPassword();
  206. },
  207. onShow(){
  208. uni.setNavigationBarTitle({
  209. title: this.$t('page.detail')
  210. })
  211. this.buletooth();
  212. },
  213. onUnload (){
  214. this.closeSocket();
  215. },
  216. methods: {
  217. copyPwd(){
  218. uni.setClipboardData({
  219. data: this.uuid,
  220. success: function () {
  221. this.$modal.showToast("复制成功");
  222. }
  223. });
  224. },
  225. i18(text){
  226. return i18(text)
  227. },
  228. toPage(){
  229. uni.navigateTo({
  230. url: '/pages/weitiandi/bluetooth/index'
  231. });
  232. },
  233. cancel(){
  234. this.showPwd = false;
  235. },
  236. modifyPwd(){
  237. this.showPwd = true;
  238. },
  239. inputPwd(){
  240. let rightPwd = uni.getStorageSync("pwd");
  241. if(!this.oldPwd){
  242. this.$modal.showToast("原密码不能为空");
  243. return;
  244. }
  245. if(rightPwd != this.oldPwd){
  246. this.$modal.showToast("原密码不对");
  247. return;
  248. }
  249. if(this.pwd == "000000"){
  250. this.$modal.showToast("密码不能设置为000000");
  251. return;
  252. }
  253. if(this.pwd == "123456"){
  254. this.$modal.showToast("密码不能设置为123456");
  255. return;
  256. }
  257. if(!this.pwd){
  258. this.$modal.showToast("密码不能为空");
  259. }else {
  260. setPwd(this.pwd);
  261. this.oldPwd = this.pwd;
  262. uni.removeStorageSync("pwd");
  263. this.$modal.showToast("密码修改成功");
  264. this.showPwd = false;
  265. this.showInitPwd = false;
  266. // this.goBack();
  267. }
  268. },
  269. confirm(e) {
  270. let value = e.value;
  271. console.log('confirm', value)
  272. let day = value[0];
  273. let date = new Date();
  274. let nowDay = date.getDate();
  275. let hour = value[1]+"";
  276. hour = parseInt(hour.substr(0,hour.length-1),10);
  277. let min = value[2]+"";
  278. min = parseInt(min.substr(0,min.length-1),10);
  279. let todayTotalMin = 0;
  280. let planDate = {min:min,hour:hour};
  281. let nowHour = date.getHours();
  282. let nowMin = date.getMinutes();
  283. let nowDate ={min:nowMin,hour:nowHour};
  284. if("今日" == day){
  285. todayTotalMin = this.getGapMin(planDate,nowDate)
  286. }else {
  287. let nowHour = date.getHours();
  288. let min = date.getMinutes();
  289. let maxDate ={min:59,hour:23};
  290. todayTotalMin = this.getGapMin(maxDate,nowDate);
  291. let minDate = {min:0,hour:0};
  292. todayTotalMin +=this.getGapMin(planDate,minDate);
  293. }
  294. console.log(todayTotalMin);
  295. this.cancelPicker();
  296. if(todayTotalMin<=0 || todayTotalMin>1440){
  297. this.$modal.showToast("最大预约时间为24小时");
  298. }else{
  299. planCharge(this.choosePort,todayTotalMin).then(res=>{
  300. this.getInfo(true);
  301. });
  302. }
  303. },
  304. getGapMin(date1,date2){
  305. let min1 = date1.min;
  306. let hour1 = date1.hour;
  307. let min2 = date2.min;
  308. let hour2 = date2.hour;
  309. let total1 = min1+hour1*60;
  310. let total2 = min2+hour2*60;
  311. return total1-total2;
  312. },
  313. cancelPicker(e) {
  314. this.showPlan = false
  315. },
  316. changeHandler(e){
  317. const {
  318. columnIndex,
  319. value,
  320. values, // values为当前变化列的数组内容
  321. index,
  322. // 微信小程序无法将picker实例传出来,只能通过ref操作
  323. picker = this.$refs.uPicker
  324. } = e
  325. let day = e.value[0];
  326. // 当第一列值发生变化时,变化第二列(后一列)对应的选项
  327. this.picker = picker;
  328. if (columnIndex === 0) {
  329. // picker为选择器this实例,变化第二列对应的选项
  330. if(day == "今日"){
  331. picker.setColumnValues(1, this.columnData[1])
  332. }else{
  333. picker.setColumnValues(1, this.columnData[0])
  334. }
  335. }
  336. },
  337. checkPassword(){
  338. let rightPwd = uni.getStorageSync("pwd");
  339. if(rightPwd === this.initPwd){
  340. this.showInitPwd = true;
  341. this.$modal.loading("正在读取设备ID");
  342. this.oldPwd = rightPwd;
  343. getUUID();
  344. }
  345. },
  346. recon(){
  347. let self = this;
  348. ecUI.showLoading('设备连接中')
  349. let blueid = uni.getStorageSync('blueid');
  350. ecBLE.onBLEConnectionStateChange(res => {
  351. ecUI.hideLoading()
  352. if (res.ok) {
  353. self.buletooth();
  354. } else {
  355. uni.removeStorageSync('blueid');
  356. ecUI.showModal(
  357. '提示',
  358. '连接失败,errCode=' + res.errCode + ',errMsg=' + res.errMsg
  359. )
  360. }
  361. })
  362. ecBLE.createBLEConnection(blueid);
  363. },
  364. buletooth(){
  365. let self = this;
  366. ctx = this
  367. isCheckScroll = true
  368. isCheckRevHex = false
  369. isCheckSendHex = false
  370. sendData = ''
  371. //on disconnect
  372. ecBLE.onBLEConnectionStateChange(() => {
  373. uni.showModal({
  374. title: '提示',
  375. content: '蓝牙断开连接',
  376. confirmText:"点击重连",
  377. showCancel:false,
  378. success: function (res) {
  379. if (res.confirm) {
  380. uni.reLaunch({
  381. url: '/pages/bluetooth/index/index'
  382. });
  383. // self.recon()
  384. } else if (res.cancel) {
  385. console.log('用户点击取消');
  386. }
  387. }
  388. });
  389. })
  390. //receive data
  391. ecBLE.onBLECharacteristicValueChange((str, strHex) => {
  392. isCheckRevHex = true;
  393. let data =
  394. (isCheckRevHex ? strHex.replace(/[0-9a-fA-F]{2}/g, ' $&') : str)
  395. // console.log(data)
  396. self.$modal.closeLoading();
  397. console.log("收到消息:"+data);
  398. //AA 67 0D 05 00 00 00 00 00 00 00 00 00 25 E2 00 80
  399. data = parseDataObj(data);
  400. self.messageCallback(data);
  401. })
  402. self.getInfo();
  403. },
  404. messageCallback(data){
  405. let self = this;
  406. console.log(data);
  407. let type = data.type;
  408. let real_data = data.real_data;
  409. if(type == 103){
  410. self.portDetail = real_data
  411. self.portList = [[]];
  412. let port_first_status = self.portDetail["port_first_status"];
  413. let port_second_status = self.portDetail["port_second_status"]
  414. if(port_first_status){
  415. self.portList[0].push({port:1,text:"端口一"});
  416. }
  417. if(port_second_status){
  418. self.portList[0].push({port:2,text:"端口二"});
  419. }
  420. let choosePort = self.choosePort
  421. if(choosePort == 1){
  422. self.portDetail.portStatus = port_first_status;
  423. }else if(choosePort == 2){
  424. self.portDetail.portStatus = port_second_status;
  425. }
  426. self.$modal.closeLoading();
  427. }
  428. if(type == 116){
  429. self.$modal.closeLoading();
  430. self.getInfo();
  431. }
  432. if(type == 113){
  433. self.$modal.closeLoading();
  434. self.getInfo();
  435. }
  436. if(type == 96){
  437. }
  438. if(type == 253){
  439. self.$modal.closeLoading();
  440. self.uuid = real_data.substr(0,6);
  441. }
  442. self.$forceUpdate();
  443. console.log('收到服务器内容:' + JSON.stringify(data));
  444. if(!this.firstInit){
  445. this.firstInit = true;
  446. let autoCharge = self.getAutoChargeValue()
  447. if(self.portDetail.portStatus == 5 && autoCharge == 1){
  448. self.startCharge();
  449. }
  450. }
  451. },
  452. getAutoChargeValue(){
  453. let autoCharge = uni.getStorageSync("autoCharge");
  454. if(!autoCharge ){
  455. autoCharge = 1;
  456. }
  457. return autoCharge;
  458. },
  459. planCharge(){
  460. if(this.portDetail.portStatus == 6){
  461. this.$modal.confirm("确认取消预约?").then(res=>{
  462. this.cancelPlan();
  463. })
  464. }else{
  465. this.toPlan()
  466. }
  467. },
  468. sendBlueData(){
  469. ecBLE.writeBLECharacteristicValue(tempSendData, false)
  470. },
  471. cancelPlan(){
  472. cancelPlan(this.choosePort).then(res=>{
  473. this.$modal.msg("取消成功");
  474. this.getInfo(true);
  475. })
  476. },
  477. getPlanInfo(){
  478. getPlanInfo(this.deviceInfo.deviceId,this.choosePort).then(res=>{
  479. let data = res.data;
  480. if(data != null){
  481. let planType = data.planType;
  482. if(planType == 1){//单次预约
  483. let planInfo = {};
  484. planInfo.runTime = data.runTime;
  485. this.planInfo = planInfo;
  486. this.planInfo.id = data.id;
  487. }else{
  488. let planInfo = {};
  489. planInfo.runTime = data.runTime;
  490. let repeatDays = data.repeatDays;
  491. let days = repeatDays.split(",")
  492. let strs = "";
  493. for (let i = 0; i < days.length; i++) {
  494. if(strs.length>0){
  495. strs+=",";
  496. }
  497. strs +=this.days[days[i]];
  498. }
  499. this.planInfo = planInfo;
  500. this.planInfo.runTime = strs+" "+data.repeatTime;
  501. this.planInfo.id = data.id;
  502. }
  503. }
  504. })
  505. },
  506. confirmPort(e){
  507. let value = e.value[0]
  508. this.choosePort = value.port;
  509. this.showPort = false;
  510. this.getInfo()
  511. },
  512. initSocket(key){
  513. let self = this;
  514. },
  515. toSet(){
  516. // this.closeSocket();
  517. uni.navigateTo({
  518. url: '/pages/weitiandi/bluetooth/setting'
  519. });
  520. },
  521. toPlan(){
  522. let arr = [];
  523. let date = new Date();
  524. let min = date.getMinutes();
  525. let hour = date.getHours();
  526. let arr1 = ["今日", "明日"];
  527. let arr2 = []
  528. let arr3 = [];
  529. let arr4 = [];
  530. for (let i = 0; i < hour; i++) {
  531. arr2.push(i+"时")
  532. }
  533. this.columnData[0] = arr2;
  534. for (let i = hour+1; i < 24; i++) {
  535. arr3.push(i+"时")
  536. }
  537. this.columnData[1] = arr3;
  538. for (let i = 0; i <= 59; i++) {
  539. arr4.push(i+"分")
  540. }
  541. this.planCols = [arr1, arr3, arr4]
  542. this.showPlan = true;
  543. },
  544. trigger(){
  545. let portStatus = this.portDetail.portStatus;
  546. if(portStatus == 2){//需要停止充电
  547. this.$modal.confirm("需要停止充电么?").then(res=>{
  548. this.stopCharge();
  549. })
  550. }else{
  551. if(portStatus == 1){
  552. this.$modal.msg("请先将充电枪插入后再点击充电");
  553. }
  554. if(portStatus == 5){
  555. this.$modal.confirm("确认开始充电么?").then(res=>{
  556. this.startCharge();
  557. })
  558. }else {
  559. this.$modal.msg("端口无法开始充电");
  560. }
  561. }
  562. },
  563. getInfo(flag) {
  564. // let str = "AA 67 0D 01 00 00 00 00 00 00 00 00 00 25 E2 00 80";
  565. // let data = parseDataObj(str);
  566. // this.messageCallback(data);
  567. //
  568. //
  569. this.$modal.loading("正在获取状态,请稍等...");
  570. if(flag){
  571. setTimeout(function (){
  572. sendPortDetailCmd().then(res => {
  573. })
  574. },500)
  575. }else{
  576. sendPortDetailCmd().then(res => {
  577. })
  578. }
  579. },
  580. stopCharge(){
  581. let self = this;
  582. this.deviceInfo.port = this.choosePort;
  583. stopCharge(this.deviceInfo).then(()=>{
  584. self.$modal.loading("停止成功");
  585. setTimeout((()=>{
  586. self.getInfo();
  587. }),1000);
  588. })
  589. },
  590. startCharge(){
  591. let self = this;
  592. this.deviceInfo.port = this.choosePort;
  593. startCharge(this.deviceInfo).then(res=>{
  594. self.$modal.loading("启动成功");
  595. setTimeout((()=>{
  596. self.getInfo();
  597. }),1000);
  598. })
  599. },
  600. getPortInfo(){
  601. this.startPortDetailTimer();
  602. },
  603. startPortDetailTimer(){
  604. let self = this;
  605. this.timer = setTimeout(function (){
  606. getPortDetail(self.deviceInfo,self.visitTime).then(res=>{
  607. let data = res.data;
  608. if(data != null){
  609. self.portDetail = data;
  610. self.checkStatusCheck();
  611. self.$modal.closeLoading();
  612. }else{
  613. self.startPortDetailTimer();
  614. }
  615. });
  616. },1000);
  617. },
  618. checkStatusCheck(){
  619. this.statusChangeTimer();
  620. },
  621. checkOnPage(){
  622. var pages = getCurrentPages() // 获取栈实例
  623. let currentRoute = pages[pages.length - 1].route; // 获取当前页面路由
  624. if("pages/weitiandi/device/index" != currentRoute){
  625. return false;
  626. }
  627. return true;
  628. },
  629. goBack(){
  630. this.closeSocket();
  631. uni.navigateBack({
  632. });
  633. },
  634. closeSocket(){
  635. ecBLE.onBLEConnectionStateChange(() => {})
  636. ecBLE.onBLECharacteristicValueChange(() => {})
  637. ecBLE.closeBLEConnection()
  638. uni.removeStorageSync('blueid');
  639. },
  640. statusChangeTimer(){
  641. let self = this;
  642. this.statusTimer = setTimeout(function(){
  643. if(!this.checkOnPage()){
  644. return;
  645. }
  646. checkStatusChange(self.deviceInfo,self.visitTime).then(res=>{
  647. let data = res.data;
  648. if(data != null){
  649. self.getInfo();
  650. }else{
  651. self.statusChangeTimer();
  652. }
  653. });
  654. },3000);
  655. }
  656. }
  657. }
  658. </script>
  659. <style>
  660. .container {
  661. background: rgb(249, 252, 255);
  662. inset: 0;
  663. position: absolute;
  664. }
  665. .header {
  666. position: relative;
  667. margin-top:4vw;
  668. }
  669. .header-status-desc {
  670. position: absolute;
  671. text-align: center;
  672. width: 100%;
  673. bottom:1vh;
  674. font-size: 5vw;
  675. font-weight: bold;
  676. color: #0E9F9B;
  677. margin-bottom: 5vw;
  678. }
  679. .header-status {
  680. font-weight: bold;
  681. text-align: center;
  682. }
  683. .chong-active {
  684. color: #0E9F9B
  685. }
  686. .header-img {
  687. width: 100%;
  688. padding: 5% 10%;
  689. text-align: center;
  690. }
  691. .header-img image {
  692. width: 100%;
  693. height: 23vh;
  694. }
  695. .info-body{
  696. background: #0E9F9B;
  697. height: 20vh;
  698. margin: 0 2%;
  699. border-radius: 1vw;
  700. margin-top:2vh;
  701. color: #F8FCFF;
  702. line-height: 3vh;
  703. }
  704. .info-content{
  705. display: inline-block;
  706. width: 23%;
  707. text-align: center;
  708. margin: 1%;
  709. margin-top:2.5vh;
  710. }
  711. .info-content-value{
  712. font-weight: bold;
  713. }
  714. .info-content-text{
  715. }
  716. .info-summary{
  717. display: flex;
  718. flex-direction: row;
  719. text-align: center;
  720. margin:3vh 0;
  721. }
  722. .summary{
  723. width: 33%;
  724. line-height: 2.5vh;
  725. }
  726. .charge-num{
  727. color: #0E9F9B;
  728. font-weight: bold;
  729. font-size: 4.5vw;
  730. }
  731. .charge-title{
  732. color: #B2B2B2;
  733. font-weight: 400;
  734. }
  735. .btn-image{
  736. width: 90%;
  737. height: 100%;
  738. }
  739. .info-bottom-btn{
  740. display: flex;
  741. flex-direction: row;
  742. text-align: center;
  743. position: relative;
  744. margin-top: 10vh
  745. ;
  746. }
  747. .btn-area{
  748. width: 50%;
  749. height: 50px;
  750. }
  751. .left{
  752. position: relative;
  753. left: 10px;
  754. text-align: right;
  755. }
  756. .right{
  757. text-align: left;
  758. position: relative;
  759. right: 10px;
  760. }
  761. .info-plan{
  762. text-align: center;
  763. color: #0E9F9B;
  764. margin-top:1vh;
  765. font-weight: 400;
  766. }
  767. .setting{
  768. position: fixed;
  769. right: -1px;
  770. top: 10vh;
  771. z-index: 999;
  772. background: rgb(227,243,245);
  773. color: #0E9F9B;
  774. font-size: 10px;
  775. border-radius: 5px;
  776. padding: 3px;
  777. }
  778. .port{
  779. height: 70px;
  780. background: #F8FCFF;
  781. border: 0px solid #F8FCFF;
  782. box-shadow: 0px 0px 6px 1px rgba(101,101,101,0.29);
  783. border-radius: 4px;
  784. margin:0 10px;
  785. position: relative;
  786. margin-top:10px;
  787. }
  788. .plan{
  789. height: 70px;
  790. background: #F8FCFF;
  791. border: 0px solid #F8FCFF;
  792. box-shadow: 0px 0px 6px 1px rgba(101,101,101,0.29);
  793. border-radius: 4px;
  794. margin:0 10px;
  795. position: relative;
  796. margin-top:15px;
  797. }
  798. .port-image{
  799. height: 40px;
  800. width: 40px;
  801. position: absolute;
  802. top:15px;
  803. left:20px;
  804. }
  805. .port-text{
  806. position: absolute;
  807. top:13px;
  808. left:75px;
  809. font-weight: bold;
  810. }
  811. .port-num{
  812. position: absolute;
  813. top:38px;
  814. left:75px;
  815. color: #B2B2B2;
  816. }
  817. .port-icon{
  818. position: absolute;
  819. top:30px;
  820. right:5px;
  821. width: 10px;
  822. height: 16px;
  823. }
  824. .port-icon image{
  825. width: 90%;
  826. }
  827. .body-bottom{
  828. padding:0 22px;
  829. }
  830. .body-bottom .info-content{
  831. width: 30%;
  832. }
  833. .bottom-control{
  834. height: 22vh;
  835. margin: 0 2%;
  836. margin-top:2vh;
  837. line-height: 3vh;
  838. background: #F8FCFF;
  839. border: 0px solid #F8FCFF;
  840. box-shadow: 0px 0px 6px 1px rgba(101,101,101,0.29);
  841. border-radius: 4px;
  842. padding:3%;
  843. }
  844. .control-btn{
  845. display: inline-block;;
  846. height: 60px;
  847. width: 25%;
  848. padding:10px 20px;
  849. text-align: center;
  850. font-size: 12px;
  851. color: black;
  852. }
  853. .control-btn .btn-image{
  854. }
  855. #box {
  856. /* width: 300px; */
  857. height: 280px;
  858. position: relative;
  859. /* 背景色 */
  860. /* background: #f7f6f6; */
  861. overflow: hidden;
  862. /* padding: 50px 0; */
  863. box-sizing: border-box;
  864. ;
  865. }
  866. .box {
  867. width: 100%;
  868. height: 100%;
  869. position: absolute;
  870. display: flex;
  871. justify-content: center;
  872. /* 此处尽量不要设置背景色,可以选择在父标签上设置背景色,否则没有黏黏的效果 */
  873. filter: url("#goo");
  874. }
  875. /* 电量文字 */
  876. .text {
  877. font-weight: 200;
  878. font-size: 20px;
  879. margin-top: 5px;
  880. text-align: center;
  881. color: #ff6600;
  882. }
  883. /* 电量文字 */
  884. .text span {
  885. font-size: 15px;
  886. }
  887. .three {
  888. width: 170px;
  889. height: 170px;
  890. border-radius: 300px;
  891. opacity: 1;
  892. position: absolute;
  893. top: 20px;
  894. z-index: 10;
  895. /* 从中心向外剪切圆,相当于掏空 */
  896. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  897. background: #ffffff;
  898. /* animation: ballZhuan 9s linear infinite; */
  899. overflow: hidden;
  900. box-shadow: 0px 0px 19px 1px #2196f3;
  901. }
  902. .four {
  903. width: 200px;
  904. height: 200px;
  905. border-radius: 80px;
  906. opacity: 0.3;
  907. position: absolute;
  908. top: 10px;
  909. z-index: 10;
  910. /* 从中心向外剪切圆,相当于掏空 */
  911. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  912. background: #2196f3;
  913. animation: ballZhuan1 linear infinite;
  914. animation-duration: 11s;
  915. }
  916. .five {
  917. width: 270px;
  918. height: 270px;
  919. border-radius: 99px;
  920. opacity: 0.6;
  921. position: absolute;
  922. top: 30px;
  923. z-index: 10;
  924. /* 从中心向外剪切圆,相当于掏空 */
  925. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  926. background: #2196f3;
  927. animation: ballZhuan1 linear infinite;
  928. /* transform: rotate(120deg); */
  929. animation-duration: 9s;
  930. left: -67px;
  931. }
  932. .six {
  933. width: 270px;
  934. height: 270px;
  935. border-radius: 99px;
  936. opacity: 0.6;
  937. position: absolute;
  938. top:30px;
  939. z-index: 10;
  940. /* 从中心向外剪切圆,相当于掏空 */
  941. /* -webkit-mask: radial-gradient(transparent 95px, white 0px); */
  942. background: #2196f3;
  943. animation: ballZhuan1 7s linear infinite;
  944. /* transform: rotate(120deg); */
  945. right: -67px;
  946. }
  947. @keyframes ballZhuan {
  948. 100% {
  949. transform: rotate(360deg);
  950. }
  951. }
  952. @keyframes ballZhuan1 {
  953. 100% {
  954. transform: rotate(360deg);
  955. }
  956. }
  957. /* 底部的小球 */
  958. .dot {
  959. display: block;
  960. width: 20px;
  961. height: 20px;
  962. border-radius: 50%;
  963. background: rgba(101,192,255,0.28);
  964. position: absolute;
  965. z-index: 1000;
  966. bottom: -50px;
  967. }
  968. .dot:nth-of-type(1) {
  969. width: 40px;
  970. height: 40px;
  971. right: 116px;
  972. animation: dotMove 5s linear infinite;
  973. }
  974. .dot:nth-of-type(2) {
  975. width: 50px;
  976. height: 50px;
  977. left: 120px;
  978. animation: dotMove 4s linear infinite;
  979. }
  980. .dot:nth-of-type(3) {
  981. animation: dotMove 2s linear infinite;
  982. }
  983. .dot:nth-of-type(4) {
  984. width: 15px;
  985. height: 15px;
  986. left: 130px;
  987. animation: dotMove 2s linear infinite;
  988. }
  989. .dot:nth-of-type(5) {
  990. width: 30px;
  991. height: 30px;
  992. animation: dotMove 3s linear infinite;
  993. }
  994. @keyframes dotMove {
  995. 0% {
  996. transform: translateY(0px);
  997. opacity: 1;
  998. }
  999. 98% {
  1000. opacity: 1;
  1001. }
  1002. 100% {
  1003. transform: translateY(-260px);
  1004. opacity: 0;
  1005. }
  1006. }
  1007. .w-flex {
  1008. display: -webkit-box;
  1009. display: -webkit-flex;
  1010. display: flex;
  1011. padding: 0px 25px;
  1012. }
  1013. .w-flex__item {
  1014. -webkit-box-flex: 1;
  1015. -webkit-flex: 1;
  1016. flex: 1;
  1017. }
  1018. .w-item{
  1019. text-align: center;
  1020. padding: 5px;
  1021. }
  1022. .w-item-tit{
  1023. font-size: 14px;
  1024. color: #888;
  1025. }
  1026. .w-item-num{
  1027. font-size: 18px;
  1028. color: #111;
  1029. }
  1030. .can{
  1031. position: relative;
  1032. z-index: 0;
  1033. width: 211px;
  1034. height: 211px;
  1035. background-image: url(/static/images/new/quan.png);
  1036. background-size: cover;
  1037. display: flex;
  1038. justify-content: center;
  1039. align-items: center;
  1040. }
  1041. .dtop{
  1042. background: url(/static/images/new/box1.png);
  1043. background-size: cover;
  1044. width: 260px;
  1045. height: 236px;
  1046. display: flex;
  1047. justify-content: center;
  1048. align-items: center;
  1049. left: 15%;
  1050. position: relative;
  1051. }
  1052. .dstatus{
  1053. margin-top: 0.1rem;
  1054. display: flex;
  1055. flex-wrap: wrap;
  1056. justify-content: space-evenly;
  1057. align-content: center;
  1058. }
  1059. .ditem{
  1060. width: 30%;
  1061. display: flex;
  1062. flex-direction: column;
  1063. align-items: center;
  1064. margin-bottom: 0.3rem;
  1065. margin-top: 10px;
  1066. }
  1067. .itemimg{
  1068. width: 50px;
  1069. height: 50px;
  1070. }
  1071. .item-value{
  1072. font-weight: bold;
  1073. font-size: 19px;
  1074. margin:4px 0;
  1075. }
  1076. .item-text{
  1077. font-size: 13px;
  1078. margin:1px 0;
  1079. color: #999999;
  1080. }
  1081. .start{
  1082. background: #1A87FF;
  1083. color: #fff;
  1084. width: 45%;
  1085. height: 50px;
  1086. min-height: 40px;
  1087. border-radius: 50px;
  1088. display: flex;
  1089. justify-content: center;
  1090. align-items: center;
  1091. font-size: 20px;
  1092. font-weight: bold;
  1093. }
  1094. .dbtns{
  1095. display: flex;
  1096. margin-top:10px;
  1097. justify-content: space-between;
  1098. padding: 0 30px;
  1099. }
  1100. .get{
  1101. background: #fff;
  1102. border: 1px solid #1A87FF;
  1103. color: #1A87FF;
  1104. width: 45%;
  1105. height: 50px;
  1106. min-height: 40px;
  1107. border-radius: 50px;
  1108. display: flex;
  1109. justify-content: center;
  1110. align-items: center;
  1111. font-size: 20px;
  1112. font-weight: bold;
  1113. }
  1114. .dtip{
  1115. margin: 20px 20px;
  1116. padding: 10px;
  1117. background: rgba(127,200,251,0.1);
  1118. border: 1px solid #7FC8FB;
  1119. box-shadow: 0 2px 8px 0 rgba(0,0,0,0.19);
  1120. border-radius: 5px;
  1121. font-size: 17px;
  1122. font-weight: 400;
  1123. color: #B8B9BA;
  1124. margin-bottom: 10px;
  1125. }
  1126. .p1{
  1127. font-size: 20px;
  1128. color: white;
  1129. font-weight: bold;
  1130. margin-top:10px;
  1131. }
  1132. .stip{
  1133. text-align: center;
  1134. z-index: 9999;
  1135. }
  1136. </style>