scanBtn.vue 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061
  1. <template>
  2. <view class="container-view">
  3. <view v-if="is_battery&&battery_info===null"></view>
  4. <view v-else>
  5. <block v-if="JSON.stringify(packInfo) !== '{}' && (packInfo.packType === 1 || packInfo.packType === 0) ||is_battery">
  6. <view class="no-height"></view>
  7. <view class="cabinet-bottom">
  8. <view @tap="navToGuild" class="guide-view flex-row">
  9. <img class="battery-img" src="https://qiniu.bms16.com/FkJlBRAxbGzR85wOO8WB_bAUTp-i" alt="">
  10. <view class="guide-text">{{is_battery?'电池归还操作指南':'电池换电指南'}}</view>
  11. <img class="arrow-img" src="https://qiniu.bms16.com/FtC9Hb8y1QEOidsI2UySz85iUQHy" alt="">
  12. </view>
  13. <block v-if="packInfo.packType === 0">
  14. <view class="scan-btn-view flex-row">
  15. <view @tap="sacnBtn" class="refund-btn"><text>扫码换电</text></view>
  16. <view v-if="showScanBtn" @tap="tapReservation" class="scan-btn">预约换电</view>
  17. </view>
  18. <!-- <view class="scan-btn-view1">
  19. <view @tap="sacnBtn" class="scan-btn1"><text>扫码换电</text></view>
  20. </view>
  21. <view class="appoint-btn-view1">
  22. <view @click="tapReservation" class="phone-view">预约换电</view>
  23. </view> -->
  24. </block>
  25. <block v-else>
  26. <block v-if="!is_battery&&((isShowAppoint && reservation_info.length === 0) || reservation_info.length !== 0)">
  27. <view :class="showScanBtn?'scan':'show_scan'">
  28. <view class="scan-btn-view1">
  29. <view @tap="sacnBtn" class="scan-btn1"><text>扫码换电</text></view>
  30. </view>
  31. <view class="appoint-btn-view1">
  32. <view v-if="(isShowAppoint && reservation_info.length === 0) &&showScanBtn" @click="tapReservation"
  33. class="phone-view">
  34. {{reservation_info.length === 0?'预约换电':'取消预约'}}
  35. </view>
  36. <view v-if="reservation_info.length !== 0&&showScanBtn"
  37. @click="cancelReservation(reservation_info[0].reservation_order_sn)" class="phone-view">
  38. {{'取消预约'}}
  39. </view>
  40. <view
  41. v-if="reservation_info.length !== 0 && (countdownTimer.hours != 0 || countdownTimer.minutes != 0 || countdownTimer.secs != 0)"
  42. class="cancel_subscribe_mark">
  43. <!-- {{countdownTimer}} -->
  44. <text class="time_num" v-if="countdownTimer.hours != 0">{{countdownTimer.hours}}</text>
  45. <text class="time_mark" v-if="countdownTimer.hours != 0">时</text>
  46. <text class="time_num">{{countdownTimer.minutes}}</text>
  47. <text class="time_mark">分</text>
  48. <text class="time_num">{{countdownTimer.secs}}</text>
  49. <text class="time_mark">秒</text>
  50. <text class="time_mark">自动取消</text>
  51. </view>
  52. </view>
  53. </view>
  54. </block>
  55. <block v-else>
  56. <view class="scan-btn-view">
  57. <view @tap="sacnBtnReturn" class="refund-btn"><text>还电</text></view>
  58. <view @tap="sacnBtn" class="scan-btn"><text>{{is_battery?'换电':'扫码换电'}}</text></view>
  59. </view>
  60. </block>
  61. </block>
  62. </view>
  63. <!-- 购买换电次数弹窗 -->
  64. <view v-if="isShowToBuy" class="modal-group">
  65. <view class="fee-rules-main">
  66. <view class="fee-rules-top flex-row">
  67. <view @tap="claseShowToBuy" class="fee-rules-close">
  68. <img class="close-icon" src="https://qiniu.bms16.com/FtoTEHOJiUf_gjPCJGGHMsAtHI5M" alt="">
  69. </view>
  70. <view class="pay-moneu-view">
  71. <view class="pay-money-text">付款金额/¥</view>
  72. <view class="pay-money">{{free_price}}</view>
  73. </view>
  74. </view>
  75. <view class="fee-rules-view">
  76. <view class="fee-rules flex-row flex-between">
  77. <view class="fee-rules-title flex-row">
  78. <img class="fee-rules-icon" src="https://qiniu.bms16.com/FjJ70vT8ydLEGfeABSFYWFe-zosV"
  79. alt="">
  80. <text style="margin-left:16rpx;">换电收费规则</text>
  81. </view>
  82. <view class="fee-rules-money-view">
  83. <text class="fee-rules-money">¥{{free_price}}</text>
  84. <text>/1次</text>
  85. </view>
  86. </view>
  87. <view class="open-result-tip">您的免费换电次数已用完,后续换电需要支付</view>
  88. </view>
  89. <view class="pay-type-view">
  90. <!-- #ifdef MP-WEIXIN -->
  91. <view @tap="changePayType" :data-type="0" class="pay-view flex-row">
  92. <img class="pay-icon" src="https://qiniu.bms16.com/FkmtlfJrmGfAh9n1138KC1WloQkZ" alt="">
  93. <view class="pay-view-text">微信支付</view>
  94. <img class="wx-pay-icon"
  95. :src="payType==0?'https://qiniu.bms16.com/FhWimtmWybKlYMB6mgIReVWArbfq':'https://qiniu.bms16.com/FkmDjxBNZhFGFU5inza2usdtDlX8'"
  96. alt="">
  97. </view>
  98. <!-- #endif -->
  99. <!-- #ifdef MP-ALIPAY-->
  100. <view @tap="changePayType" :data-type="2" class="pay-view flex-row">
  101. <img class="pay-icon" src="https://qiniu.bms16.com/Fk4YmG_RbdH0LNo1s8qHKDtpCTXl" alt="">
  102. <view class="pay-view-text">支付宝支付</view>
  103. <img class="wx-pay-icon"
  104. :src="payType==2?'https://qiniu.bms16.com/FhWimtmWybKlYMB6mgIReVWArbfq':'https://qiniu.bms16.com/FkmDjxBNZhFGFU5inza2usdtDlX8'"
  105. alt="">
  106. </view>
  107. <!-- #endif -->
  108. <view @tap="changePayType" :data-type="9" class="pay-view flex-row">
  109. <img class="pay-icon" src="https://qiniu.bms16.com/FiGNLQ5lqhEK5im_mUVgRrE8PJMB" alt="">
  110. <view class="pay-view-text">钱包余额支付(¥{{wallet_money}})</view>
  111. <img class="wx-pay-icon"
  112. :src="payType==9?'https://qiniu.bms16.com/FhWimtmWybKlYMB6mgIReVWArbfq':'https://qiniu.bms16.com/FkmDjxBNZhFGFU5inza2usdtDlX8'"
  113. alt="">
  114. </view>
  115. </view>
  116. <view class="over-btn-view">
  117. <view class="over-btn flex-row" @tap="toPayOrFreeExchange">立即支付</view>
  118. </view>
  119. </view>
  120. </view>
  121. <!-- 打开蓝牙连接弹窗 -->
  122. <view v-if="isOpenBluetooth" class="modal-group">
  123. <view class="def-alert-bluetooth">
  124. <view class="close-view flex-row"><img @tap="close" class="close-icon"
  125. src="https://qiniu.bms16.com/FtoTEHOJiUf_gjPCJGGHMsAtHI5M" alt=""></view>
  126. <view class="bluetooth-view flex-row"><img class="bluetooth-icon"
  127. src="https://qiniu.bms16.com/FjWK8ZBtxCmspiOtHJWrNEoPRA0M" alt=""></view>
  128. <view class="need-bluetooth-text">本次{{is_retuen_battery?'还':'换'}}电需要连接蓝牙</view>
  129. <view class="need-bluetooth-tip">请开启手机蓝牙,点击 (蓝牙{{is_retuen_battery?'还':'换'}}电) 按钮</view>
  130. <view class="bluetooth-connect-view">
  131. <view class="bluetooth-connect-btn" @tap="tapOpenBluetooth">蓝牙{{is_retuen_battery?'还':'换'}}电
  132. </view>
  133. </view>
  134. </view>
  135. </view>
  136. </block>
  137. </view>
  138. </view>
  139. </template>
  140. <script>
  141. var http = require('../../common/http.js');
  142. var config = require('../../common/config.js');
  143. var common = require('../../common/common.js');
  144. var storage = require('../../common/storage.js')
  145. var user = require('../../common/user.js');
  146. var bluetooth = require('../../common/bluetooth.js');
  147. // var IndexImpl = require('../../pages/index/model/indexImpl.js');
  148. const DF_CAB_INFO_DONE = 10000; //机柜信息传输完成
  149. var subscribeTimer = null;
  150. var app = getApp();
  151. export default {
  152. props: {
  153. cab_info: {
  154. type: null,
  155. validator: val => typeof val === 'object' || val === null,
  156. required: true
  157. },
  158. dev_id: {
  159. type: String,
  160. required: true
  161. },
  162. is_my: {
  163. type: Boolean,
  164. required: false
  165. }
  166. },
  167. data() {
  168. return {
  169. is_battery: false,
  170. free_price: 0,
  171. battery_info: {},
  172. packInfo: {},
  173. reservation_info: [],
  174. myPackageInfo: {},
  175. countdownTimer: {},
  176. blueInfo: {}, //连接蓝牙需要数据
  177. isBluetooth: false, //缓存蓝牙连接状态
  178. cabinetInfo: {}, //机柜信息
  179. num: 0, //免费换电次数
  180. payType: 0, //支付方式
  181. scan_dev_id: '', //扫码机柜编号
  182. online_status: '', //机柜在线状态
  183. isOpenBluetooth: false,
  184. license_plate_number: '',
  185. isShowToBuy: false,
  186. isShowAppoint: false,
  187. wallet_money: 0,
  188. payResp: {},
  189. myLocation: {},
  190. orderInfo: {},
  191. carInfo: {},
  192. is_retuen_battery: false, //判断按钮点击还电还是换电操作
  193. orderStatusTimer: null, //定时查询还电状态
  194. showScanBtn: false,
  195. }
  196. }
  197. /**
  198. * 生命周期函数--监听页面加载
  199. */
  200. ,
  201. watch: {
  202. cab_info: {
  203. handler: function(newVal) {
  204. if (newVal) {
  205. console.log(newVal, "newVal")
  206. this.setData({
  207. reservation_info: JSON.stringify(newVal) == '{}' ? [] : newVal
  208. .reservation_info
  209. });
  210. this.updateCountdown();
  211. }
  212. },
  213. immediate: true
  214. }
  215. },
  216. mounted: function(options) {
  217. this.loadMyPackageInfo()
  218. const car_list = uni.getStorageSync('user_car_list') || null
  219. const storedLocation = uni.getStorageSync('user_current_location');
  220. if (car_list) {
  221. // this.license_plate_number = car_list.plate_number
  222. this.carInfo = car_list
  223. }
  224. if (app.globalData.showScanBtn) {
  225. this.showScanBtn = true
  226. } else {
  227. this.showScanBtn = false
  228. }
  229. if (storedLocation && storedLocation.longitude && storedLocation.latitude) {
  230. // 如果本地有存储的定位信息,则直接使用
  231. this.setData({
  232. myLocation: storedLocation,
  233. // license_plate_number: car_list.plate_number
  234. });
  235. }
  236. //#ifdef MP-ALIPAY
  237. this.payType = 2
  238. //#endif
  239. //#ifdef MP-WEIXIN
  240. this.payType = 0
  241. //#endif
  242. bluetooth.initBluetooth()
  243. this.bluetoothClose()
  244. this.loadBatteryInfo()
  245. //this.loadExchangeInfo()
  246. },
  247. /**
  248. * 生命周期函数--监听页面显示
  249. */
  250. onShow: function() {
  251. },
  252. methods: {
  253. // 更新倒计时
  254. updateCountdown() {
  255. if (this.reservation_info.length > 0) {
  256. console.log(this.reservation_info[0])
  257. const remainingTime = common.calculateRemainingTime(this.reservation_info[0]
  258. .lock_expire_time);
  259. if (remainingTime >= 0) {
  260. this.setData({
  261. countdownTimer: common.formatTimeScan(remainingTime)
  262. })
  263. }
  264. if (remainingTime > 0) {
  265. subscribeTimer = setTimeout(() => this.updateCountdown(), 1000); // 每秒更新一次
  266. }
  267. }
  268. },
  269. loadMyPackageInfo() {
  270. // IndexImpl.loadMyPackageInfo(
  271. // (resp) => {
  272. // this.setData({
  273. // isShowAppoint: resp.isShowAppoint,
  274. // myPackageInfo: resp.myPackageInfo,
  275. // packInfo: resp.packInfo
  276. // })
  277. // this.$emit(
  278. // 'popPackageModel', this.packInfo
  279. // );
  280. // },
  281. // (failMsg) => {
  282. // //common.simpleToast(failMsg)
  283. // }
  284. // )
  285. },
  286. navToGuild() {
  287. const url = this.is_battery ? '/pages/my/leadReturnBattery/leadReturnBattery' :
  288. '/pages/exchangeGuide/exchangeGuide'
  289. console.log(url);
  290. uni.navigateTo({
  291. url: url
  292. });
  293. },
  294. sacnBtn() {
  295. const me = this
  296. this.is_retuen_battery = false
  297. if (this.packInfo.packType === 0||this.packInfo.packType === 2) {
  298. const notShow = 1
  299. this.$emit(
  300. 'popPackageModel', this.packInfo,notShow
  301. );
  302. } else{
  303. uni.scanCode({
  304. onlyFromCamera: true,
  305. scanType: [],
  306. success: function(res) {
  307. var cabinet_dev_id = '';
  308. me.loadGeneralQRData(res)
  309. if ('path' in res && res.path) {
  310. if (res.path.split('%26devid%3D').length > 1) {
  311. cabinet_dev_id = res.path.split('%26devid%3D')[1].split('%26')[0];
  312. } else if (res.path.split('&devid=').length > 1) {
  313. cabinet_dev_id = res.path.split('&devid=')[1].split('&')[0];
  314. }
  315. }
  316. if (cabinet_dev_id != '') {
  317. me.scan_dev_id = cabinet_dev_id
  318. me.loadNowCabinetDetail(cabinet_dev_id)
  319. } else {
  320. //common.simpleToast("未找到相应的机柜")
  321. }
  322. },
  323. fail: function(res) {},
  324. complete: function(res) {}
  325. });
  326. }
  327. },
  328. sacnBtnReturn() {
  329. const me = this
  330. uni.showModal({
  331. cancelText: '取消',
  332. confirmText: '确定',
  333. content: '您确定要归还电池吗?',
  334. showCancel: true,
  335. title: '提示',
  336. success: (result) => {
  337. if (result.confirm) {
  338. me.is_retuen_battery = true
  339. uni.scanCode({
  340. onlyFromCamera: true,
  341. scanType: [],
  342. success: function(res) {
  343. var cabinet_dev_id = '';
  344. me.loadGeneralQRData(res)
  345. if ('path' in res && res.path) {
  346. if (res.path.split('%26devid%3D').length > 1) {
  347. cabinet_dev_id = res.path.split('%26devid%3D')[1]
  348. .split('%26')[0];
  349. } else if (res.path.split('&devid=').length > 1) {
  350. cabinet_dev_id = res.path.split('&devid=')[1].split(
  351. '&')[0];
  352. }
  353. }
  354. if (cabinet_dev_id != '') {
  355. me.scan_dev_id = cabinet_dev_id
  356. me.loadNowCabinetDetail(cabinet_dev_id)
  357. } else {
  358. //common.simpleToast("未找到相应的机柜")
  359. }
  360. },
  361. fail: function(res) {},
  362. complete: function(res) {}
  363. });
  364. }
  365. },
  366. })
  367. },
  368. loadGeneralQRData(options, stash_sn) {
  369. let qrCode = getApp().globalData.qrCode;
  370. var url = ''
  371. if (qrCode.indexOf("https://zx.uwenya.cc/xcx/s") != -1) {
  372. getApp().globalData.qrCode = ''
  373. url = qrCode
  374. }
  375. if (('result' in options) && options.result.indexOf("https://zx.uwenya.cc/xcx/s") != -1) {
  376. url = decodeURIComponent(options.result);
  377. }
  378. if (url == '') return
  379. var obj = this.getUrlParams(url)
  380. if (('t' in obj) && ('d' in obj)) {
  381. if (obj.t == 1) {
  382. this.scan_dev_id = obj.d
  383. this.loadNowCabinetDetail(obj.d)
  384. return
  385. }
  386. }
  387. },
  388. getUrlParams(url) {
  389. // 通过 ? 分割获取后面的参数字符串
  390. let urlStr = url.split('?')[1]
  391. // 创建空对象存储参数
  392. let obj = {};
  393. // 再通过 & 将每一个参数单独分割出来
  394. let paramsArr = urlStr.split('&')
  395. for (let i = 0, len = paramsArr.length; i < len; i++) {
  396. // 再通过 = 将每一个参数分割为 key:value 的形式
  397. let arr = paramsArr[i].split('=')
  398. obj[arr[0]] = arr[1];
  399. }
  400. return obj
  401. },
  402. cancelReservation(reservation_order_sn) {
  403. const pData = {
  404. order_sn: reservation_order_sn
  405. }
  406. http.postApi(config.API_DAYHIRE_RESERVATION_CANCEL, pData, (resp) => {
  407. if (resp.data.code === 200) {
  408. common.simpleToast("取消预约成功")
  409. this.$emit(
  410. 'refreshCabinet'
  411. );
  412. // this.loadCabinetDetail()
  413. } else {
  414. common.simpleToast(resp.data.msg)
  415. }
  416. })
  417. },
  418. tapReservation() {
  419. // 预约换电
  420. if (this.packInfo.packType === 0||this.packInfo.packType === 2) {
  421. const notShow = 1
  422. this.$emit(
  423. 'popPackageModel', this.packInfo,notShow
  424. );
  425. return
  426. }
  427. if (this.myPackageInfo.effective.list.length === 0) {
  428. common.simpleToast("暂无可预约的电池")
  429. return
  430. }
  431. const pData = {
  432. dev_id: this.dev_id,
  433. battery_sn: this.myPackageInfo.effective.list[0].current_battery_sn
  434. }
  435. if (this.packInfo.packType === 0||this.packInfo.packType === 2) {
  436. const notShow = 1
  437. this.$emit(
  438. 'popPackageModel', this.packInfo,notShow
  439. );
  440. } else{
  441. http.postApi(config.API_DAYHIRE_CABINET_EXCHANGE_RESERVATION, pData, (resp) => {
  442. if (resp.data.code === 200) {
  443. common.simpleToast("预约成功")
  444. this.$emit(
  445. 'refreshCabinet'
  446. );
  447. } else if (resp.data.code === 181102) {
  448. const me = this
  449. uni.showModal({
  450. cancelText: '关闭',
  451. confirmText: '取消预约',
  452. content: '您当前已存在预约其它机柜,是否要取消之前的预约操作?',
  453. showCancel: true,
  454. title: '提示',
  455. success: (result) => {
  456. if (result.confirm) {
  457. me.cancelReservation(resp.data.data.order_sn)
  458. }
  459. },
  460. })
  461. } else {
  462. common.simpleToast(resp.data.msg)
  463. }
  464. })
  465. }
  466. },
  467. loadNowCabinetDetail(dev_id) {
  468. const timeNow = Date.now()
  469. this.scan_dev_id = dev_id
  470. //扫码机柜信息
  471. const me = this
  472. const pData = {
  473. longitude: this.myLocation.longitude,
  474. latitude: this.myLocation.latitude,
  475. dev_id: dev_id || '',
  476. service: "reservation",
  477. time: timeNow
  478. }
  479. http.postApi(config.API_DAYHIRE_CABINRT_CABINRT_INFO, pData, (resp) => {
  480. if (resp.data.code === 200) {
  481. this.online_status = resp.data.data.cabinetInfo.online_status
  482. const device = {
  483. device_type: "LSCabinet",
  484. bt_type: "",
  485. mac_id: resp.data.data.cabinetInfo.bt_mac,
  486. btid: resp.data.data.cabinetInfo.bt_mac,
  487. dev_id: resp.data.data.cabinetInfo.dev_id,
  488. key: me.decodeKey(resp.data.data.cabinetInfo.bt_sec),
  489. btkey: resp.data.data.cabinetInfo.bt_mac,
  490. bt_sec: me.decodeKey(resp.data.data.cabinetInfo.bt_sec),
  491. bt_mac: resp.data.data.cabinetInfo.bt_mac
  492. }
  493. me.setData({
  494. blueInfo: device,
  495. cabinetInfo: resp.data.data.cabinetInfo
  496. })
  497. me.updateCountdown()
  498. me.bluetoothClose()
  499. if (me.online_status == 1) {
  500. if (me.is_retuen_battery) {
  501. //机柜还电流程
  502. me.noBluetoothBack()
  503. } else {
  504. if (me.packInfo.last_num == 0&&me.packInfo.num != 0) {
  505. if (me.free_price != 0) {
  506. me.setData({
  507. isShowToBuy: true
  508. })
  509. me.walletInfo()
  510. } else{
  511. const pData = {
  512. from: from,
  513. battery_sn: this.is_battery ? this.battery_info.battery_sn : this.packInfo.current_battery_sn,
  514. dev_id: this.scan_dev_id,
  515. pay_type: 9
  516. }
  517. const me = this
  518. //#ifdef MP-ALIPAY
  519. const from = 'ali'
  520. //#endif
  521. //#ifdef MP-WEIXIN
  522. const from = 'wx'
  523. //#endif
  524. http.postApi(config.API_CABINET_CHANGE_BATTERY2, pData, (resp) => {
  525. if (resp.data.code === 200) {
  526. // 钱包支付不需要支付直接换电 有换电次数可以直接换电
  527. if (!resp.data.data.need_pay) {
  528. me.orderInfo = {
  529. order_sn: resp.data.data.order_sn,
  530. empty_door_id: resp.data.data.empty_door_id,
  531. full_door_id: resp.data.data.full_door_id,
  532. cabbatterysn: resp.data.data.rtn_battery_sn || ''
  533. };
  534. me.navOpenCabinet(me.orderInfo)
  535. } else {
  536. me.setData({
  537. isShowToBuy: false
  538. })
  539. me.wxPayPrice = resp.data.data.price
  540. me.payResp = resp
  541. me.doPayBattery({})
  542. }
  543. } else {
  544. common.simpleToast(resp.data.msg)
  545. }
  546. })
  547. }
  548. } else {
  549. me.toPayOrFreeExchange()
  550. }
  551. }
  552. } else {
  553. me.setData({
  554. isOpenBluetooth: true
  555. })
  556. }
  557. } else {
  558. common.simpleToast(resp.data.msg)
  559. }
  560. })
  561. },
  562. walletInfo() {
  563. const me = this
  564. http.postApi(config.API_DAYHIRE_USER_WALLET_INFO, {}, function(resp) {
  565. if (resp.data.code === 200) {
  566. me.wallet_money = (resp.data.data.balance / 100).toFixed(2)
  567. } else {
  568. common.simpleToast(resp.data.msg)
  569. }
  570. })
  571. },
  572. toPayOrFreeExchange() {
  573. //购买单次换电次数进行换电或者有免费次数直接换电
  574. const me = this
  575. //#ifdef MP-ALIPAY
  576. const from = 'ali'
  577. //#endif
  578. //#ifdef MP-WEIXIN
  579. const from = 'wx'
  580. //#endif
  581. const pData = {
  582. from: from,
  583. battery_sn: this.is_battery ? this.battery_info.battery_sn : this.packInfo.current_battery_sn,
  584. dev_id: this.scan_dev_id,
  585. pay_type: this.payType
  586. }
  587. //如果在线用机柜换电 不在线用蓝牙换电
  588. http.postApi(config.API_CABINET_CHANGE_BATTERY2, pData, (resp) => {
  589. if (resp.data.code === 200) {
  590. // 钱包支付不需要支付直接换电 有换电次数可以直接换电
  591. if (!resp.data.data.need_pay) {
  592. me.orderInfo = {
  593. order_sn: resp.data.data.order_sn,
  594. empty_door_id: resp.data.data.empty_door_id,
  595. full_door_id: resp.data.data.full_door_id,
  596. cabbatterysn: resp.data.data.rtn_battery_sn || ''
  597. };
  598. me.navOpenCabinet(me.orderInfo)
  599. } else {
  600. me.setData({
  601. isShowToBuy: false
  602. })
  603. me.wxPayPrice = resp.data.data.price
  604. me.payResp = resp
  605. me.doPayBattery({})
  606. }
  607. } else {
  608. common.simpleToast(resp.data.msg)
  609. }
  610. })
  611. },
  612. loadBatteryInfo() {
  613. console.log("加载电池信息")
  614. const me = this
  615. console.log(2222);
  616. http.postApi(config.API_HIREEXCHANGE_INDEX_BATTERY, {}, function(resp) {
  617. if (resp.data.code === 200) {
  618. if (resp.data.data !== null) {
  619. me.setData({
  620. battery_info: resp.data.data,
  621. free_price: resp.data.data.exchange_money / 100,
  622. is_battery: me.is_my
  623. })
  624. me.$emit(
  625. 'updateBatteryInfo', resp.data.data
  626. );
  627. } else {
  628. me.setData({
  629. battery_info: resp.data.data,
  630. is_battery: me.is_my
  631. })
  632. }
  633. } else {
  634. common.simpleToast(resp.data.msg)
  635. }
  636. })
  637. },
  638. doPayBattery: function(pData) {
  639. const me = this
  640. //#ifdef MP-WEIXIN
  641. var payParams = JSON.parse(this.payResp.data.data.payParams);
  642. var order_sn = this.payResp.data.data.order_sn;
  643. user.wxPay(order_sn, payParams, function(isSuccess) {
  644. if (isSuccess) {
  645. common.simpleToast('支付成功')
  646. //跳转换电流程页面
  647. me.orderInfo = {
  648. order_sn: me.payResp.data.data.order_sn,
  649. empty_door_id: me.payResp.data.data.empty_door_id,
  650. full_door_id: me.payResp.data.data.full_door_id,
  651. cabbatterysn: me.payResp.data.data.rtn_battery_sn || ''
  652. };
  653. me.navOpenCabinet(me.orderInfo)
  654. } else {
  655. user.cancelCabExPay(order_sn)
  656. // 取消支付
  657. }
  658. });
  659. //#endif
  660. //#ifdef MP-ALIPAY
  661. my.tradePay({
  662. tradeNO: me.payResp.data.data.trade_no,
  663. success: function(res) {
  664. if (res.resultCode == 9000) {
  665. common.simpleToast('支付成功')
  666. me.orderInfo = {
  667. order_sn: me.payResp.data.data.order_sn,
  668. empty_door_id: me.payResp.data.data.empty_door_id,
  669. full_door_id: me.payResp.data.data.full_door_id,
  670. cabbatterysn: me.payResp.data.data.rtn_battery_sn || ''
  671. };
  672. me.navOpenCabinet(me.orderInfo)
  673. } else {
  674. user.cancelCabExPay(order_sn)
  675. }
  676. },
  677. });
  678. //#endif
  679. },
  680. tapOpenBluetooth(time = null) {
  681. const me = this
  682. const device = me.blueInfo
  683. // 蓝牙换电按钮 加载蓝牙
  684. console.log(111111111);
  685. this.loadBluetooth()
  686. },
  687. loadBluetooth() {
  688. const me = this;
  689. console.log(this.blueInfo,'this.blueInfo');
  690. const device = this.blueInfo;
  691. if (bluetooth.acceptDevice(device)) {
  692. // 打开蓝牙连接
  693. bluetooth.openBluetoothAdapter((res) => {
  694. common.loading()
  695. bluetooth.connectDevice(device, () => {
  696. bluetooth.onCharacteristicStateChange(device.mac_id, 'index', (data) => {
  697. if (JSON.stringify(data) != '{}') {
  698. if (data.state === DF_CAB_INFO_DONE) {
  699. me.reportCabintInfo(me.cabinetInfo.dev_id, data
  700. .commandList);
  701. uni.hideLoading();
  702. common.simpleToast('蓝牙连接成功')
  703. me.setData({
  704. isOpenBluetooth: false,
  705. isBluetooth: true
  706. });
  707. me.bindReturnOrExchange() //还电or换电
  708. }
  709. }
  710. });
  711. bluetooth.onConnectionStateChange(device.mac_id, 'index', (res) => {
  712. uni.hideLoading();
  713. if (!res.connected) {
  714. // 蓝牙未连接
  715. // common.simpleToast('蓝牙连接断开',2000)
  716. me.setData({
  717. isOpenBluetooth: true,
  718. isBluetooth: false
  719. });
  720. } else {
  721. common.simpleToast('蓝牙连接成功', 2000)
  722. // 蓝牙已连接
  723. me.setData({
  724. isOpenBluetooth: false,
  725. isBluetooth: true
  726. });
  727. me.bindReturnOrExchange() //还电or换电
  728. }
  729. });
  730. bluetooth.sendGetCabinetInfoCommand(
  731. device.mac_id,
  732. device,
  733. (res) => {
  734. common.loading();
  735. },
  736. (res) => {
  737. console.log(res,"蓝牙连接1")
  738. me.setData({
  739. isOpenBluetooth: false
  740. });
  741. uni.showModal({
  742. title: '提示',
  743. confirmText: '重新连接',
  744. content: '连接失败,请尝试重新连接',
  745. success: function(res) {
  746. if (res.confirm) {
  747. me.loadBluetooth();
  748. } else {
  749. // uni.navigateBack({
  750. // delta: 1
  751. // });
  752. }
  753. }
  754. });
  755. }
  756. );
  757. },
  758. (res) => {
  759. uni.hideLoading();
  760. var showContent = ""
  761. var text;
  762. //#ifdef MP-ALIPAY
  763. text = '支付宝'
  764. //#endif
  765. //#ifdef MP-WEIXIN
  766. text = '微信'
  767. //#endif
  768. if (res && ("errCode" in res)) {
  769. if (res.errCode == 9000001) {
  770. var showContent= "观察周围是否有其他骑手连接,请等待对方完成 或 "+ text +"是否开启了蓝牙权限!!"
  771. } else {
  772. console.log(res,"蓝牙连接2")
  773. var showContent = "连接失败,请尝试重新连接"
  774. }
  775. } else {
  776. console.log(res,"蓝牙连接3")
  777. var showContent = "连接失败,请尝试重新连接"
  778. }
  779. me.setData({
  780. isOpenBluetooth: false,
  781. isBluetooth: false
  782. });
  783. uni.showModal({
  784. title: '提示',
  785. confirmText: '重新连接',
  786. content: showContent,
  787. success: function(res) {
  788. if (res.confirm) {
  789. me.loadBluetooth();
  790. } else {
  791. // uni.navigateBack({
  792. // delta: 1
  793. // });
  794. }
  795. }
  796. });
  797. }, (res) => {
  798. uni.hideLoading();
  799. me.setData({
  800. isOpenBluetooth: false
  801. });
  802. uni.showModal({
  803. title: '提示',
  804. confirmText: '我知道了',
  805. content: '蓝牙未打开或请在右上角设置授权小程序使用蓝牙',
  806. success: function(res) {
  807. if (res.confirm) {
  808. me.loadBluetooth();
  809. } else {
  810. // uni.navigateBack({
  811. // delta: 1
  812. // });
  813. }
  814. }
  815. });
  816. }
  817. );
  818. }, );
  819. } else {
  820. //蓝牙连接未成功
  821. uni.hideLoading();
  822. uni.showModal({
  823. confirmText: '我知道了',
  824. content: '当前机柜未找到符合的蓝牙类型',
  825. showCancel: false,
  826. title: '提示',
  827. complete: (res) => {
  828. // uni.navigateBack({
  829. // delta: 1
  830. // });
  831. }
  832. });
  833. }
  834. },
  835. reportCabintInfo(dev_id, list) {
  836. var pushList = []
  837. for (var i = 0; list.length > i; i++) {
  838. var sublist = []
  839. for (var j = 0; list[i].length > j; j++) {
  840. sublist.push(parseInt(list[i][j]))
  841. }
  842. pushList.push(sublist)
  843. }
  844. const pData = {
  845. dev_id: dev_id,
  846. data: JSON.stringify(pushList)
  847. }
  848. const me = this
  849. http.postApi(config.API_CABINET_BLUETOOTH_INFO, pData, function(response) {
  850. if (response.data.code === 200) {
  851. // me.setData({
  852. // cabinetInfo: response.data.data.cabinetInfo
  853. // })
  854. } else {
  855. simpleToast(response.data.msg)
  856. }
  857. })
  858. },
  859. navOpenCabinet(pdata, battery_type) {
  860. const me = this
  861. const paramsString = JSON.stringify(pdata)
  862. const cabinetInfoString = JSON.stringify(me.cabinetInfo)
  863. // 跳转机柜换电页面-展示换电流程和结果
  864. uni.navigateTo({
  865. url: '/pages/openCabinetBind/openCabinetBindSn?pdata=' + encodeURIComponent(paramsString) +
  866. '&cabinet_info=' + encodeURIComponent(cabinetInfoString) + '&battery_type=' + battery_type,
  867. success: function(res) {},
  868. fail: function(res) {},
  869. complete: function(res) {},
  870. })
  871. },
  872. // loadExchangeInfo() {
  873. // // 查询免费换电次数/换电价格
  874. // const pData = {
  875. // license_plate_number: this.license_plate_number
  876. // }
  877. // http.postApi(config.API_DAYHIRE_CABINRT_BATTERY_EXCHANGE_INFO, pData, (resp) => {
  878. // if (resp.data.code === 200) {
  879. // this.setData({
  880. // num: resp.data.data.last_free_number,
  881. // free_price: (resp.data.data.price / 100).toFixed(2),
  882. // })
  883. // } else {
  884. // common.simpleToast(resp.data.msg)
  885. // }
  886. // })
  887. // },
  888. bluetoothClose: function() {
  889. bluetooth.closeBluetoothAdapter();
  890. bluetooth.closeDevice(
  891. this.cabinetInfo.bt_mac,
  892. () => {
  893. // this.setData({
  894. // bt_loading: false
  895. // });
  896. },
  897. () => {}
  898. );
  899. bluetooth.offCharacteristicStateChange(this.cabinetInfo.bt_mac, 'home');
  900. bluetooth.offConnectionStateChange(this.cabinetInfo.bt_mac, 'home');
  901. },
  902. changePayType(e) {
  903. const type = e.currentTarget.dataset.type
  904. if (this.wallet_money < this.free_price) {
  905. common.simpleToast('钱包余额不足')
  906. return
  907. }
  908. this.setData({
  909. payType: type
  910. })
  911. console.log(this.free_price, 'free_price');
  912. },
  913. close() {
  914. this.setData({
  915. isOpenBluetooth: false
  916. })
  917. },
  918. claseShowToBuy() {
  919. this.setData({
  920. isShowToBuy: false
  921. })
  922. },
  923. decodeKey(str) {
  924. var val = []
  925. for (var i = 0; i < str.length / 2; i++) {
  926. val.push(parseInt(str.substring(0 + i * 2, 2 + i * 2), 16))
  927. }
  928. var str = ""
  929. for (var i = 0; val.length > i; i++) {
  930. str += String.fromCharCode(~val[i] & 0xff)
  931. }
  932. return str
  933. },
  934. noBluetoothBack() {
  935. common.loading();
  936. const me = this
  937. const pData = {
  938. battery_sn: this.battery_info.battery_sn,
  939. dev_id: this.scan_dev_id
  940. }
  941. http.postApi(config.API_CABINET_RETURN_HIRE_BATTERYI, pData, resp => {
  942. uni.hideLoading()
  943. if (resp.data.code === 200) {
  944. const pData = {
  945. order_sn: resp.data.data.order_sn,
  946. battery_sn: me.battery_info.battery_sn,
  947. }
  948. me.navOpenCabinet(pData, 1)
  949. } else {
  950. common.alert('提示', resp.data.msg);
  951. }
  952. })
  953. },
  954. bindReturnOrExchange() {
  955. const me = this
  956. console.log(me.is_retuen_batterym, 'is_retuen_battery');
  957. if (me.is_retuen_battery) {
  958. common.loading();
  959. const me = this
  960. const pdata = {
  961. battery_sn: this.battery_info.battery_sn,
  962. dev_id: this.scan_dev_id
  963. }
  964. console.log(pdata, 'pdatapdata');
  965. http.postApi(config.API_CABINET_BLUETOOTH_RETURN, pdata, resp => {
  966. wx.hideLoading()
  967. console.log(resp.data, 'resp.data');
  968. if (resp.data.code === 200) {
  969. console.log(resp.data.data, '1314');
  970. const pData = {
  971. order_sn: resp.data.data.order_sn,
  972. empty_door_id: resp.data.data.empty_door_id,
  973. rtn_battery_ca: resp.data.data.rtn_battery_ca || ''
  974. }
  975. //还电
  976. me.navOpenCabinet(pData, 1)
  977. } else {
  978. common.alert('提示', resp.data.msg);
  979. }
  980. })
  981. } else {
  982. //换电
  983. if (me.packInfo.last_num == 0&&me.packInfo.num != 0) {
  984. if (me.free_price != 0) {
  985. me.setData({
  986. isShowToBuy: true
  987. })
  988. me.walletInfo()
  989. } else{
  990. const pData = {
  991. from: from,
  992. battery_sn: this.is_battery ? this.battery_info.battery_sn : this.packInfo.current_battery_sn,
  993. dev_id: this.scan_dev_id,
  994. pay_type: 9
  995. }
  996. const me = this
  997. //#ifdef MP-ALIPAY
  998. const from = 'ali'
  999. //#endif
  1000. //#ifdef MP-WEIXIN
  1001. const from = 'wx'
  1002. //#endif
  1003. http.postApi(config.API_CABINET_CHANGE_BATTERY2, pData, (resp) => {
  1004. if (resp.data.code === 200) {
  1005. // 钱包支付不需要支付直接换电 有换电次数可以直接换电
  1006. if (!resp.data.data.need_pay) {
  1007. me.orderInfo = {
  1008. order_sn: resp.data.data.order_sn,
  1009. empty_door_id: resp.data.data.empty_door_id,
  1010. full_door_id: resp.data.data.full_door_id,
  1011. cabbatterysn: resp.data.data.rtn_battery_sn || ''
  1012. };
  1013. me.navOpenCabinet(me.orderInfo)
  1014. } else {
  1015. me.setData({
  1016. isShowToBuy: false
  1017. })
  1018. me.wxPayPrice = resp.data.data.price
  1019. me.payResp = resp
  1020. me.doPayBattery({})
  1021. }
  1022. } else {
  1023. common.simpleToast(resp.data.msg)
  1024. }
  1025. })
  1026. }
  1027. } else {
  1028. me.toPayOrFreeExchange()
  1029. }
  1030. }
  1031. },
  1032. }
  1033. };
  1034. </script>
  1035. <style>
  1036. @import './scanBtn.css';
  1037. </style>