reshui.vue 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795
  1. <template>
  2. <view class="content">
  3. <view class="container">
  4. <view class="header">
  5. <view class="scan" @tap="scan()" hover-class="scan_hover">
  6. <!-- <text class="iconfont icon-saoma"></text> -->
  7. <image :src="require('./images/icon-saoma.png')" style="width: 118rpx;" mode="aspectFit"></image>
  8. <text>扫码连接</text>
  9. </view>
  10. <view class="qinshihao">
  11. <!-- <text class="iconfont icon-zhuye"></text> -->
  12. <image :src="require('./images/icon-zhuye.png')" style="width: 28rpx; margin-right: 8rpx;"
  13. mode="aspectFit"></image>
  14. <text class="dormtxt">{{dorm_number || '宿舍未知'}}</text>
  15. </view>
  16. </view>
  17. <view class="start_text">
  18. <view class="start_top">
  19. <view class="item_left">
  20. <text class="iconfont icon-shuibiao"></text>
  21. <text>开启设备</text>
  22. </view>
  23. <view>
  24. <switch :color="colorPrimary" :checked="isChecked" @change="switchChange" />
  25. </view>
  26. </view>
  27. <view class="start_mid">
  28. <view class="item_left">
  29. <text class="iconfont icon-qian"></text>
  30. <!-- <navigator url="/pagesWater/reshuiDetails/reshuiDetails" open-type="navigate"
  31. class="start_mid_txt">¥{{amount}}</navigator> -->
  32. <navigator url="" open-type="navigate" class="start_mid_txt">¥{{amount}}</navigator>
  33. </view>
  34. <view class="start_payamount" @tap="chongzhi_yemian()" hover-class="scan_hover">
  35. <text>点击充值</text>
  36. <image :src="require('./images/icon-dayuhao.png')"
  37. style="width: 26rpx; margin-left: 10rpx; padding-top: 3rpx; opacity: 0.6;" mode="aspectFit">
  38. </image>
  39. <!-- <text class="iconfont icon-dayuhao"></text> -->
  40. </view>
  41. </view>
  42. <view class="start_bot">
  43. <button class="kongzhonglianjie" @click="open">空中连接</button>
  44. <text class="start_bot_txt">当前结算消费:¥{{use_amount}}</text>
  45. </view>
  46. </view>
  47. <view v-if="showRoom" style="width: 100%; height: 100%; ">
  48. <view style="display: flex; flex-wrap: wrap;">
  49. <button v-for="item in rooms" :key="item.id" @tap="clickRoom(item.id)"
  50. class="btn_room">{{item.room}}</button>
  51. </view>
  52. </view>
  53. <view class="start_up_process">
  54. <uni-steps :options="list1" :active-color="colorPrimary" :active="active" />
  55. </view>
  56. <!-- <view class="ad">
  57. <image src="../../static/images/ad_reshui.jpg" mode="aspectFill" class="ad_img" @tap="ad_redirect">
  58. </image>
  59. </view> -->
  60. <view class="title">
  61. 消费记录
  62. </view>
  63. <view class="record-item">
  64. <view class="uni-list-cell-db">
  65. <picker mode="date" :value="date" fields="month" :start="startDate" :end="endDate"
  66. @change="bindDateChange">
  67. <view class="uni-input">
  68. <text>{{date}}</text>
  69. <!-- <text class="iconfont icon-arrow-down"></text> -->
  70. <image :src="require('./images/icon-arrow-down.png')" style="width: 26rpx;"
  71. mode="aspectFit">
  72. </image>
  73. </view>
  74. </picker>
  75. </view>
  76. <view class="item-list" v-for="(item, i) in xiaofei_items" :key="i">
  77. <text class="item-list-txt"><text class="iconfont icon-shijian"></text>{{item.begin_time}}</text>
  78. <text class="item-list-txt"><text
  79. class="iconfont icon-shuidi"></text>{{numFilter(item.use_size)}}t</text>
  80. <text class="item-list-txt">{{numFilter(item.use_amount)}}</text>
  81. </view>
  82. </view>
  83. </view>
  84. <instructions v-if="flag" @parent_cancel="cancel" @parent_noshow='noshow'></instructions>
  85. </view>
  86. </template>
  87. <script>
  88. import instructions from '../../components/instructions.vue'
  89. export default {
  90. /**
  91. * 声明组件
  92. */
  93. components: {
  94. instructions
  95. },
  96. data() {
  97. return {
  98. colorPrimary: getApp().globalData.primaryColor,
  99. date: this.$getDate({
  100. format: true
  101. }),
  102. startDate: this.$getDate('start_date'),
  103. endDate: this.$getDate('end_date'),
  104. flag: false, // 控制说明弹窗
  105. showRoom: false,
  106. isUserClose: false, // 是否是用户自己关闭
  107. isChecked: false,
  108. isConnected: false, // 是否连接上
  109. isScan: false,
  110. active: -1,
  111. list1: [{
  112. title: '连接设备'
  113. }, {
  114. title: '连设备服务'
  115. }, {
  116. title: '数据通讯'
  117. }, {
  118. title: '启动'
  119. }],
  120. devices: [], // 保存设备
  121. rooms: [], // 保存水表id及对应的宿舍号
  122. device_code: '', // 设备编号
  123. deviceId: '',
  124. serviceId: '',
  125. characteristicIdForWrite: '',
  126. characteristicIdForNotity: '',
  127. deviceIsNotify: false,
  128. deviceIsWrite: false,
  129. byte35: '', // 70 个字符
  130. byte35_tmp: '', // 70 个字符 临时变量
  131. start_code: '',
  132. // start_code: '3459A8C660F1C284E41003E80000120000',
  133. xiaofei_items: [], // 消费记录
  134. use_amount: 0.0.toFixed(2), // 结算金额
  135. amount: 0.0.toFixed(2), // 余额
  136. dorm_number: '', // 宿舍号
  137. stu_number: '', // 学号
  138. user_name: '',
  139. // compus: '', // 校区
  140. ceshi: 'code',
  141. changeDate: false, // 是否是手动选择日期
  142. get_Bluetooth_Bevice: false, // 自动获取蓝牙设备,并列表
  143. timer: -1,
  144. test: this.$store.state.test
  145. }
  146. },
  147. onLoad(options) {
  148. // console.log(options);
  149. // 系统正在维护...
  150. if (this.test == 'weihuzhong') {
  151. uni.redirectTo({
  152. url: '../../pages/index/index'
  153. })
  154. return;
  155. }
  156. // 向用户发起授权请求
  157. uni.authorize({
  158. scope: 'scope.userLocation',
  159. success(res) {
  160. uni.getLocation({
  161. success: (loc) => {
  162. // console.log(loc);
  163. // uni.showToast({
  164. // icon: 'none',
  165. // title: '纬度:' + loc.latitude + '\n' + '经度:' + loc
  166. // .longitude,
  167. // duration: 2000
  168. // })
  169. uni.showToast({
  170. icon: 'success',
  171. title: '已获定位信息'
  172. })
  173. },
  174. fail: (err) => {
  175. uni.showToast({
  176. icon: 'none',
  177. title: '获取定位失败,请手动开启定位!'
  178. })
  179. }
  180. })
  181. },
  182. fail: (err) => {
  183. // console.log(err);
  184. uni.showToast({
  185. icon: 'none',
  186. title: '请手动设置定位授权!'
  187. })
  188. }
  189. })
  190. if (typeof(options) != 'undefined' && typeof(options) != '' && JSON.stringify(options) == '{}') {
  191. // 获取基本信息
  192. this.get_base_info(options, 'onLoad')
  193. } else if (typeof(options.from) != 'undefined' && options.from != 0) {
  194. // 获取基本信息
  195. this.get_base_info(options, 'onLoad')
  196. // 获取设备码
  197. this.device_code = decodeURIComponent(options.q).split('=')[1]
  198. }
  199. const value = uni.getStorageSync('instruction_noshow');
  200. if (!(value == true)) {
  201. this.flag = true
  202. }
  203. },
  204. onShow() {
  205. let _this = this;
  206. // 充值后更新金额
  207. this.amount = this.$store.state.reshui_amount
  208. // 刷新充值后的金额
  209. uni.$once('update_reshui_amount', (data) => {
  210. this.get_base_info('options', 'onShow');
  211. });
  212. if (this.timer > -1) {
  213. clearInterval(this.timer)
  214. }
  215. this.timer = setInterval(() => {
  216. uni.openBluetoothAdapter({
  217. success: (res) => { // 已打开
  218. uni.getBluetoothAdapterState({ // 蓝牙的匹配状态
  219. success: (res1) => {
  220. // console.log(res1);
  221. },
  222. fail: (error) => {
  223. // console.log(error)
  224. uni.showToast({
  225. title: '请开启手机蓝牙!',
  226. icon: 'none',
  227. duration: 2000
  228. });
  229. }
  230. });
  231. },
  232. fail: (err) => { // 未打开
  233. // console.log(err)
  234. if (err.errCode == 10001) {
  235. uni.showToast({
  236. title: '请开启手机蓝牙 或 授权蓝牙权限!',
  237. icon: 'none',
  238. duration: 2000
  239. });
  240. setTimeout(() => {
  241. _this.myInit();
  242. }, 100);
  243. } else {
  244. uni.showToast({
  245. icon: 'none',
  246. title: err.errMsg,
  247. duration: 2000
  248. });
  249. }
  250. }
  251. });
  252. }, 3000);
  253. },
  254. onHide() {
  255. clearInterval(this.timer)
  256. },
  257. onUnload() {
  258. clearInterval(this.timer)
  259. },
  260. methods: {
  261. /**
  262. * 单击连接热水表
  263. */
  264. clickRoom(e) {
  265. try {
  266. if (this.judgeBalance('clickRoom') === false) {
  267. return
  268. } else {
  269. this.device_code = 'K' + e
  270. for (var i = 0, len = this.devices.length; i < len; i++) {
  271. if (this.devices[i].dname == e) {
  272. this.deviceId = this.devices[i].did
  273. break
  274. }
  275. }
  276. // 开始连接匹配的蓝牙设备
  277. this.createBLEConnection();
  278. }
  279. } catch (e) {
  280. console.log('单击连接热水表:' + e.message);
  281. }
  282. },
  283. /**
  284. * 空中连接热水表
  285. */
  286. open() {
  287. if (this.judgeBalance('clickRoom') === false) {
  288. return
  289. } else {
  290. this.setInit()
  291. uni.showLoading({
  292. title: '水表搜索中…',
  293. mask: true,
  294. success: (res) => {
  295. // 获取蓝牙设备,并列表
  296. this.openBluetoothAdapter();
  297. this.showRoom = true
  298. }
  299. })
  300. setTimeout(function() {
  301. uni.hideLoading();
  302. }, 3000);
  303. }
  304. },
  305. /**
  306. * 跳转到广告ad页
  307. */
  308. ad_redirect() {
  309. // uni.navigateTo({
  310. // url: 'ad_reshui'
  311. // })
  312. },
  313. /**
  314. * 保留小数点数值后两位,尾数四舍五入
  315. * @param {Object} value
  316. */
  317. numFilter(value) {
  318. // 截取当前数据到小数点后两位
  319. let realVal = parseFloat(value).toFixed(2)
  320. return realVal
  321. },
  322. /**
  323. * 获取基本信息
  324. */
  325. get_base_info(options, param) {
  326. // console.log(options);
  327. try {
  328. // 获取学号
  329. this.stu_number = this.$store.state.userInfo.card_number
  330. if (this.stu_number == '' || typeof(this.stu_number) == 'undefined') {
  331. const userinfo = uni.getStorageSync('userinfo_storage_key')
  332. if (userinfo) {
  333. this.stu_number = userinfo.card_number
  334. } else {
  335. uni.navigateTo({
  336. url: '../index/index?from=' + options.from
  337. })
  338. uni.showToast({
  339. icon: 'none',
  340. title: '学号为空,请进行授权',
  341. duration: 3000
  342. });
  343. return;
  344. }
  345. }
  346. } catch (e) {
  347. console.log('获取基本信息:' + e.message);
  348. }
  349. if (param == 'onShow') {
  350. if (this.$store.state.payInfo.from == 'reshui_pay') {
  351. uni.showToast({
  352. title: this.$store.state.payInfo.resultMsg,
  353. icon: 'success',
  354. success: () => {
  355. this.$store.state.payInfo.resultMsg = ''
  356. this.$store.state.payInfo.from = ''
  357. }
  358. })
  359. }
  360. }
  361. // 获取code
  362. this.getCode(options, param);
  363. },
  364. /**
  365. * 获得code
  366. */
  367. getCode(options, param) {
  368. uni.login({
  369. success: (res) => {
  370. // console.log('getCode', res);
  371. if (res.code) {
  372. // 请求服务器,获得openid
  373. this.getOpenId(options, res.code, param)
  374. } else {
  375. uni.showToast({
  376. title: res.errMsg,
  377. icon: 'none'
  378. });
  379. }
  380. }
  381. })
  382. },
  383. /**
  384. * 请求服务器,获得openid
  385. */
  386. async getOpenId(options, param_code, param) {
  387. const res = await this.$myRequest({
  388. host: this.ceshi,
  389. url: '/HotWaters/wpget_stu.action',
  390. method: 'POST',
  391. header: {
  392. 'content-type': 'application/x-www-form-urlencoded'
  393. },
  394. data: {
  395. code: param_code
  396. }
  397. })
  398. // console.log(res);
  399. if (res.data.mess == '返回成功') {
  400. // stu_number是否存在
  401. let cardNumber = res.data.info[0].card_number
  402. if (typeof(cardNumber) != 'undefined' && cardNumber != '' && JSON.stringify(cardNumber) != '{}') {
  403. // 学号 和 姓名
  404. this.stu_number = res.data.info[0].stu_number
  405. this.user_name = res.data.info[0].user_name
  406. // 剩余金额
  407. this.amount = res.data.info[0].balance.toFixed(2)
  408. // if (this.amount > 0)
  409. this.$store.state.reshui_amount = this.amount
  410. // 组合楼栋宿舍号
  411. this.dorm_number = res.data.info[0].build + res.data.info[0].dom
  412. // 校区
  413. // this.compus = res.data.info[0].campus
  414. if (param == 'onLoad' && typeof(options.from) != 'undefined' && options.from != 0) {
  415. // 初始化蓝牙
  416. this.openBluetoothAdapter()
  417. }
  418. // 请求选定的月份消费记录
  419. this.request_consumption_records()
  420. } else {
  421. uni.showToast({
  422. title: '未获取到学号!',
  423. icon: 'success'
  424. });
  425. uni.navigateTo({
  426. url: '../index/index?from=' + options.from
  427. })
  428. }
  429. } else if (res.data.mess == '未查询到用户信息') {
  430. // 数据库中 未查询到用户信息,就清除本地存储
  431. uni.removeStorageSync('userinfo_storage_key');
  432. uni.showToast({
  433. title: '获取用户信息失败!'
  434. })
  435. if (options && typeof(options.from) != 'undefined' && typeof(options.from) != '') {
  436. uni.navigateTo({
  437. url: '../index/index?from=' + options.from
  438. })
  439. } else {
  440. uni.redirectTo({
  441. url: '../index/index?from=0'
  442. });
  443. }
  444. }
  445. },
  446. /**
  447. * 选择消费年月
  448. */
  449. bindDateChange(e) {
  450. this.date = e.detail.value
  451. this.changeDate = true
  452. // 请求选定的月份消费记录
  453. this.request_consumption_records()
  454. },
  455. /**
  456. * 使用说明组件取消
  457. */
  458. cancel(param) {
  459. this.flag = param
  460. },
  461. /**
  462. * 使用说明组件不再出现
  463. */
  464. noshow(param) {
  465. try {
  466. if (param) {
  467. uni.setStorageSync("instruction_noshow", true)
  468. } else {
  469. uni.removeStorageSync("instruction_noshow")
  470. }
  471. } catch (e) {
  472. console.log('使用说明组件不再出现:' + e.message);
  473. }
  474. },
  475. /**
  476. * 请求选定的月份消费记录
  477. */
  478. async request_consumption_records() {
  479. try {
  480. if (this.stu_number != '' && typeof(this.stu_number) != 'undefined') {
  481. const res = await this.$myRequest({
  482. host: this.ceshi,
  483. url: '/HotWaters/wpqueryConsume.action',
  484. method: 'POST',
  485. header: {
  486. 'content-type': 'application/x-www-form-urlencoded'
  487. },
  488. data: {
  489. stu_number: this.stu_number,
  490. begin_time: this.date
  491. }
  492. });
  493. // console.log(res);
  494. if (res.data.mess == '返回成功') {
  495. this.xiaofei_items = []
  496. // 消费记录
  497. let items = res.data.data
  498. for (var i = 0; i < items.length; i++) {
  499. this.xiaofei_items.push(items[i])
  500. }
  501. } else {
  502. if (this.changeDate) {
  503. uni.showToast({
  504. icon: 'success',
  505. title: res.data.mess,
  506. success: () => {
  507. this.changeDate = false
  508. }
  509. })
  510. if (res.data.mess == '本月无消费记录') {
  511. this.xiaofei_items = []
  512. }
  513. }
  514. }
  515. } else {
  516. uni.showToast({
  517. icon: 'success',
  518. title: '未获得学号'
  519. })
  520. }
  521. } catch (e) {
  522. console.log('请求选定的月份消费记录:' + e.message);
  523. }
  524. },
  525. /**
  526. * 控制进度条显示
  527. * @param {Object} active_value
  528. */
  529. process_control(active_value) {
  530. try {
  531. if (active_value <= this.list1.length - 1) {
  532. this.active = active_value
  533. }
  534. } catch (e) {
  535. console.log('控制进度条显示:' + e.message);
  536. }
  537. },
  538. /**
  539. * 开始或停止用水
  540. */
  541. switchChange(e) {
  542. let _this = this;
  543. this.isChecked = e.target.value
  544. if (this.isChecked) {
  545. if (this.deviceId && this.serviceId && this.devices.length != 0) {
  546. uni.showModal({
  547. title: '提示',
  548. content: '确定要启动设备?',
  549. success: (res) => {
  550. if (res.confirm) {
  551. this.isChecked = true;
  552. // 开始连接匹配的蓝牙设备
  553. setTimeout(async () => {
  554. // 请求获取设备启动码
  555. _this.request_device_start_code()
  556. }, 200);
  557. } else if (res.cancel) {
  558. setTimeout(() => {
  559. _this.isChecked = false;
  560. }, 100);
  561. }
  562. }
  563. })
  564. } else {
  565. setTimeout(() => {
  566. this.isChecked = false
  567. }, 200)
  568. uni.showToast({
  569. icon: 'none',
  570. title: '先【扫码连接】,后【开启设备】',
  571. duration: 1500
  572. })
  573. }
  574. } else {
  575. if (!(this.deviceId && this.serviceId)) {
  576. uni.showToast({
  577. icon: 'none',
  578. title: '与设备连接中断!请在设备上手动停止即可!',
  579. duration: 3000
  580. })
  581. setTimeout(() => {
  582. this.setInit()
  583. }, 300)
  584. return
  585. }
  586. uni.showModal({
  587. title: '提示',
  588. content: '确定要关闭设备?',
  589. success: (res) => {
  590. if (res.confirm) {
  591. if (this.deviceId && this.serviceId) {
  592. this.isChecked = false
  593. this.send('stop')
  594. } else {
  595. uni.showToast({
  596. icon: 'none',
  597. title: '与设备连接中断!请在设备上手动停止即可!',
  598. duration: 3000
  599. })
  600. setTimeout(() => {
  601. // this.isChecked = true;
  602. this.setInit()
  603. }, 300)
  604. }
  605. } else if (res.cancel) {
  606. setTimeout(() => {
  607. this.isChecked = true
  608. }, 300)
  609. }
  610. }
  611. })
  612. }
  613. },
  614. /**
  615. * 跳转到充值页面
  616. */
  617. chongzhi_yemian() {
  618. //在起始页面跳转到recharge.vue页面并传递参数
  619. uni.navigateTo({
  620. url: '../recharge/recharge'
  621. });
  622. },
  623. /**
  624. * 判断余额是否充足
  625. */
  626. judgeBalance(param) {
  627. var limit_amount = parseFloat(this.$store.state.amount)
  628. var amount = parseFloat(this.amount);
  629. // 启动最低金额限制
  630. if (amount < limit_amount) {
  631. uni.showModal({
  632. title: '提示',
  633. content: '当前余额不足¥' + limit_amount + '元',
  634. cancelText: '我知道了',
  635. confirmText: '我要充值',
  636. success: (res) => {
  637. if (res.confirm) {
  638. // 跳转充值页面
  639. this.chongzhi_yemian()
  640. // return false
  641. // } else if (res.cancel) {
  642. // return false
  643. }
  644. }
  645. })
  646. return false
  647. }
  648. // 已经启动扫描连接设备中
  649. if (this.isScan) {
  650. uni.showToast({
  651. icon: 'none',
  652. title: '正在扫描,请耐心等待',
  653. })
  654. return false
  655. }
  656. // 已经启动设备,不启动扫描
  657. if (this.isChecked) {
  658. let info_str = ''
  659. if (param == 'scan') {
  660. info_str = '设备已启动,无需重新扫码'
  661. } else {
  662. info_str = '设备已启动,无需重新启动'
  663. }
  664. uni.showToast({
  665. icon: 'none',
  666. title: info_str,
  667. })
  668. return false
  669. }
  670. // console.log(this.deviceId);
  671. // 设备已连接
  672. if (this.deviceId) {
  673. uni.showModal({
  674. title: '提示',
  675. content: '设备已经连接,需要重新连接吗?',
  676. success: res => {
  677. if (res.confirm) {
  678. // 关闭连接
  679. this.closeBLEConnection()
  680. if (param == 'scan') {
  681. // 扫描
  682. this.scan_qr()
  683. } else {
  684. // cancel
  685. }
  686. }
  687. }
  688. })
  689. return false
  690. }
  691. },
  692. /**
  693. * 111111111111111111111111111111
  694. * 扫码连接设备
  695. */
  696. scan() {
  697. if (this.judgeBalance('scan') == false) {
  698. return;
  699. }
  700. this.scan_qr();
  701. },
  702. /**
  703. * 启动摄像头,扫描二维码
  704. */
  705. scan_qr() {
  706. this.get_Bluetooth_Bevice = true
  707. uni.scanCode({
  708. onlyFromCamera: true,
  709. success: (res) => {
  710. this.isScan = true
  711. // console.log(res)
  712. // charSet: "utf-8"
  713. // codeVersion: 3
  714. // errMsg: "scanCode:ok"
  715. // rawData: "aHR0cDovL3Rvb2xzLjlrYnMuY29tLz93eG1pbmljb2RlPUtCNTgwMDAyNjUy"
  716. // result: "http://tools.9kbs.com/?wxminicode=KB580002652"
  717. // scanType: "QR_CODE"
  718. this.device_code = res.result.split('=')[1]
  719. this.isScan = false;
  720. if (this.device_code === '') {
  721. uni.showToast({
  722. icon: 'success',
  723. title: '获取设备码失败',
  724. duration: 3000
  725. });
  726. } else {
  727. // 初始化蓝牙
  728. this.openBluetoothAdapter()
  729. }
  730. }
  731. })
  732. },
  733. /**
  734. * 22222222222222222222222222222
  735. * 初始化蓝牙
  736. */
  737. openBluetoothAdapter() {
  738. let _this = this;
  739. uni.openBluetoothAdapter({
  740. success: (res) => { // 已打开
  741. uni.getBluetoothAdapterState({ // 蓝牙的匹配状态
  742. success: (res1) => {
  743. // console.log(res1, '“本机设备的蓝牙已打开”');
  744. // 本机设备的蓝牙已打开
  745. // 开始搜索蓝牙设备
  746. if (this.deviceId == '' && this.serviceId == '')
  747. this.startBluetoothDeviceDiscovery()
  748. },
  749. fail: (error) => {
  750. // console.log(error)
  751. uni.showModal({
  752. content: '请开启手机蓝牙!',
  753. showCancel: false
  754. });
  755. this.isScan = false;
  756. }
  757. });
  758. },
  759. fail: (err) => { // 未打开
  760. // console.log(err)
  761. this.isScan = false;
  762. if (err.errCode == 10001) {
  763. uni.showModal({
  764. content: '请授权手机蓝牙!',
  765. showCancel: false
  766. });
  767. } else {
  768. uni.showToast({
  769. icon: 'none',
  770. title: err.errMsg,
  771. duration: 2000
  772. })
  773. }
  774. }
  775. });
  776. },
  777. /**
  778. * 333333333333333333333333333
  779. * 开始搜索蓝牙设备
  780. */
  781. startBluetoothDeviceDiscovery() {
  782. uni.startBluetoothDevicesDiscovery({ // 开始搜寻附近的蓝牙外围设备
  783. // services: ['FEE7'], // 要搜索但蓝牙设备主 service 的 uuid 列表
  784. allowDuplicatesKey: true,
  785. success: (res) => {
  786. if (this.get_Bluetooth_Bevice == true)
  787. this.process_control(0)
  788. this.onBluetoothDeviceFound() // 监听搜索到新设备 同时进行
  789. setTimeout(() => {
  790. if (this.isScan) {
  791. uni.showModal({
  792. title: '温馨提示',
  793. content: '请确认已开启【蓝牙授权】或【定位授权】!',
  794. confirmText: '我已开启',
  795. cancelText: '取消',
  796. success: (res) => {
  797. // console.log(res);
  798. if (res.confirm) {
  799. } else if (res.cancel) {
  800. switch (uni.getSystemInfoSync().platform) {
  801. case 'android':
  802. // 打开设置
  803. break;
  804. case 'ios':
  805. // 打开设置
  806. break;
  807. default:
  808. // console.log('运行在开发者工具上')
  809. break;
  810. }
  811. }
  812. }
  813. })
  814. }
  815. }, 6000)
  816. },
  817. fail: err => {
  818. // console.log(err, '错误信息');
  819. uni.showToast({
  820. icon: 'none',
  821. title: err.errMsg,
  822. duration: 2000
  823. })
  824. this.isScan = false
  825. }
  826. })
  827. },
  828. stopBluetoothDevicesDiscovery() { //停止搜索
  829. uni.stopBluetoothDevicesDiscovery({
  830. success: (res) => {
  831. // console.log(res, '停止蓝牙搜索')
  832. // uni.showToast({
  833. // title: '停止蓝牙搜索',
  834. // duration: 2000
  835. // })
  836. if (this.get_Bluetooth_Bevice == true || this.device_code) {
  837. this.createBLEConnection()
  838. } else {
  839. this.get_room()
  840. setTimeout(() => {
  841. this.get_Bluetooth_Bevice = true
  842. }, 2000)
  843. }
  844. },
  845. fail: err => {
  846. // console.log('停止搜索蓝牙设备失败,错误码:' + err.errCode);
  847. this.isScan = false
  848. uni.showToast({
  849. title: err.errCode,
  850. duration: 2000
  851. })
  852. }
  853. })
  854. },
  855. /**
  856. * 444444444444444444444444444444444
  857. * 发现外围设备
  858. */
  859. onBluetoothDeviceFound() {
  860. uni.onBluetoothDeviceFound((res) => {
  861. let dname = ''
  862. res.devices.forEach(device => { // 筛选找到的蓝牙中对名称匹配
  863. try {
  864. // 过滤掉没有名字的设备
  865. if (!device.name && !device.localName) {
  866. return
  867. }
  868. // 把搜索到的设备存储起来,如有需要可以在页面上展示
  869. dname = device.name.substr(1)
  870. let d = {
  871. did: device.deviceId,
  872. dname: dname
  873. }
  874. if (dname.length == 10 && JSON.stringify(this.devices).indexOf(JSON.stringify(
  875. d)) === -1) {
  876. this.devices.push(d)
  877. }
  878. if (device.name == this.device_code) {
  879. this.process_control(0);
  880. //data里面建立一个deviceId、device_code,存储起来
  881. // this.device_code = device.name;
  882. this.deviceId = device.deviceId
  883. // 放此位置,苹果手机兼容
  884. this.stopBluetoothDevicesDiscovery()
  885. return
  886. }
  887. setTimeout(() => {
  888. this.stopBluetoothDevicesDiscovery()
  889. }, 2000)
  890. } catch (e) {
  891. // console.log('发现外围设备:' + e.message);
  892. }
  893. })
  894. });
  895. },
  896. // 获取水表对应的宿舍号
  897. async get_room() {
  898. try {
  899. if (this.devices.length > 0) {
  900. let devices_str = []
  901. for (var i = 0, len = this.devices.length; i < len; i++) {
  902. devices_str.push(this.devices[i].dname)
  903. }
  904. const res = await this.$myRequest({
  905. host: this.ceshi,
  906. url: '/HotWaters/waterqueryDom.action',
  907. method: 'POST',
  908. header: {
  909. 'content-type': 'application/x-www-form-urlencoded'
  910. },
  911. data: {
  912. user_id: devices_str.join(',')
  913. }
  914. });
  915. if (res.data.msg == '获取成功') {
  916. // 消费记录
  917. let items = res.data.data
  918. if (typeof items === 'undefined') {
  919. uni.showToast({
  920. title: '获取宿舍号为空',
  921. duration: 2000
  922. })
  923. return
  924. }
  925. for (var i = 0; i < items.length; i++) {
  926. let item = {
  927. id: items[i].user_id,
  928. room: items[i].dom
  929. }
  930. if (JSON.stringify(this.rooms).indexOf(JSON.stringify(item)) === -1) {
  931. this.rooms.push(item); // 进行动态的操作
  932. }
  933. }
  934. } else {
  935. if (this.changeDate) {
  936. uni.showToast({
  937. icon: 'success',
  938. title: res.data.mess,
  939. success: () => {
  940. this.changeDate = false
  941. }
  942. })
  943. if (res.data.mess == '本月无消费记录') {
  944. this.xiaofei_items = []
  945. }
  946. }
  947. }
  948. }
  949. } catch (e) {
  950. console.log('获取水表对应的宿舍号:' + e.message);
  951. }
  952. },
  953. /**
  954. * 555555555555555555555555555555555
  955. * 连接蓝牙设备
  956. */
  957. createBLEConnection() {
  958. //连接蓝牙
  959. uni.createBLEConnection({
  960. deviceId: this.deviceId,
  961. timeout: 6000,
  962. success: (res) => {
  963. // console.log(res)
  964. this.connect_BLE()
  965. },
  966. fail: (err) => {
  967. // console.log(err)
  968. this.isScan = false
  969. if (err.errMsg.indexOf('already connect') != -1) {
  970. this.connect_BLE()
  971. } else {
  972. uni.showToast({
  973. title: '水表蓝牙连接被占用!',
  974. icon: 'none',
  975. duration: 3000,
  976. success: (res1) => {
  977. this.setInit()
  978. }
  979. })
  980. }
  981. }
  982. })
  983. },
  984. connect_BLE() {
  985. if (this.isConnected === false) {
  986. this.isConnected = true
  987. // 获取蓝牙设备所有服务(service)
  988. this.getBLEDeviceServices()
  989. }
  990. },
  991. /**
  992. * 6666666666666666666666666666666666
  993. * 获取蓝牙的所有服务
  994. */
  995. getBLEDeviceServices() {
  996. uni.getBLEDeviceServices({
  997. deviceId: this.deviceId,
  998. success: (res) => {
  999. // console.log(res)
  1000. // res1.services.forEach((item) => {
  1001. // this.getBLEDeviceCharacteristics()
  1002. // })
  1003. this.serviceId = res.services[1].uuid
  1004. this.process_control(1);
  1005. this.getBLEDeviceCharacteristics()
  1006. },
  1007. fail: (err) => {
  1008. // console.log(err)
  1009. this.isScan = false
  1010. uni.showToast({
  1011. title: '获取服务失败',
  1012. icon: 'none',
  1013. duration: 3000
  1014. });
  1015. this.setInit();
  1016. return;
  1017. }
  1018. });
  1019. },
  1020. /**
  1021. * 777777777777777777777777777777777
  1022. * 获取蓝牙特征
  1023. */
  1024. getBLEDeviceCharacteristics() {
  1025. // 获取蓝牙设备某个服务中所有特征值(characteristic)
  1026. uni.getBLEDeviceCharacteristics({
  1027. deviceId: this.deviceId,
  1028. // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
  1029. serviceId: this.serviceId,
  1030. success: (res) => {
  1031. // console.log(res)
  1032. this.characteristicIdForWrite = res.characteristics[0].uuid
  1033. this.characteristicIdForNotity = res.characteristics[1].uuid
  1034. this.deviceIsWrite = res.characteristics[0].properties.write
  1035. this.deviceIsNotify = res.characteristics[1].properties.notify
  1036. // console.log(this.characteristicIdForWrite, this.characteristicIdForNotity)
  1037. // 确保对应服务id下的特征值id具备监听数据变化的特性
  1038. if (res.characteristics[1].properties.notify) {
  1039. this.notifyBLECharacteristicValueChange()
  1040. }
  1041. },
  1042. fail: (err) => {
  1043. this.isScan = false
  1044. // console.error('获取蓝牙设备特征值失败(getBLEDeviceCharacteristics)', err)
  1045. }
  1046. });
  1047. },
  1048. /**
  1049. * 888888888888888888888888888888888888
  1050. * 启用 notify 功能
  1051. */
  1052. notifyBLECharacteristicValueChange() {
  1053. uni.notifyBLECharacteristicValueChange({
  1054. state: true, // 启用 notify 功能
  1055. deviceId: this.deviceId,
  1056. // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
  1057. serviceId: this.serviceId,
  1058. // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
  1059. characteristicId: this.characteristicIdForNotity,
  1060. success: (res) => {
  1061. this.process_control(2)
  1062. uni.showToast({
  1063. icon: 'none',
  1064. title: '要启动水表,请手动点击【开启设备】右侧开关!',
  1065. duration: 5000
  1066. })
  1067. // uni.showModal({
  1068. // title: '提示',
  1069. // content: '要启动水表,请手动点击【开启设备】右侧开关!',
  1070. // showCancel: false,
  1071. // confirmText: '好,知道'
  1072. // })
  1073. this.isScan = false
  1074. // console.log('通知启用(notifyBLECharacteristicValueChange)',res);
  1075. this.onBLECharacteristicValueChange()
  1076. setTimeout(() => {
  1077. // 发送 AAABAC,采集数据(会返回 35字节 的数据)
  1078. this.send('')
  1079. }, 800)
  1080. // // 请求设备信息
  1081. // this.request_device_info()
  1082. // // 显示设备启动授权金额
  1083. // this.display_device_startup_amount()
  1084. },
  1085. fail: (err) => {
  1086. // console.log(err)
  1087. this.isScan = false
  1088. uni.showModal({
  1089. content: err.errMsg,
  1090. showCancel: false
  1091. })
  1092. // 初始化
  1093. this.setInit()
  1094. }
  1095. })
  1096. },
  1097. /**
  1098. * 999999999999999999999999999999999
  1099. * 监听低功耗蓝牙设备的特征值变化
  1100. */
  1101. onBLECharacteristicValueChange() {
  1102. uni.onBLECharacteristicValueChange((characteristic) => {
  1103. let condition = this.ab2hex(characteristic.value)
  1104. // console.log(condition)
  1105. if (condition.length > 2) {
  1106. this.byte35_tmp += condition
  1107. if (this.byte35_tmp.length > 40) {
  1108. this.byte35 = this.byte35_tmp
  1109. this.byte35_tmp = ''
  1110. if (this.byte35.startsWith('ad')) {
  1111. // console.log(this.byte35, '结束用水成功')
  1112. // 关闭蓝牙连接
  1113. this.closeBLEConnection()
  1114. // 请求结算
  1115. this.request_pay()
  1116. } else {
  1117. // 发送 AAABAC,采集数据(会返回 35字节 的数据)
  1118. // b58000265243eb3dd4bb3c5a2ab9042efcf0d2a30a000000000000000014392a0103bc
  1119. // uni.showToast({
  1120. // icon: 'success',
  1121. // title: '采集数据成功!',
  1122. // duration: 2000
  1123. // })
  1124. // console.log(this.byte35, '采集上一条消费数据')
  1125. }
  1126. }
  1127. }
  1128. switch (condition) {
  1129. case 'bb':
  1130. // uni.showToast({
  1131. // title: '设备启动成功',
  1132. // duration: 3000,
  1133. // icon: 'none'
  1134. // })
  1135. this.isChecked = true
  1136. break
  1137. case 'bc':
  1138. uni.showToast({
  1139. title: '启动失败,设备检验启动代码不通过',
  1140. duration: 3000,
  1141. icon: 'none'
  1142. })
  1143. break
  1144. case 'aa':
  1145. uni.showToast({
  1146. title: '设备正在使用',
  1147. duration: 3000,
  1148. icon: 'none'
  1149. })
  1150. break
  1151. case 'ab':
  1152. uni.showToast({
  1153. title: '结束失败,设备对结束代码检验失败',
  1154. duration: 3000,
  1155. icon: 'none'
  1156. })
  1157. break
  1158. default:
  1159. break
  1160. }
  1161. })
  1162. },
  1163. /**
  1164. * 关闭连接
  1165. */
  1166. closeBLEConnection() {
  1167. if (this.deviceId) {
  1168. uni.closeBLEConnection({
  1169. deviceId: this.deviceId,
  1170. success: () => {
  1171. // 关闭蓝牙模块
  1172. this.closeBluetoothAdapter()
  1173. },
  1174. fail: (err) => {
  1175. // this.setInit()
  1176. // uni.showToast({
  1177. // icon: 'none',
  1178. // title: err.errMsg,
  1179. // duration: 3000,
  1180. // success: (res1) => {
  1181. // this.setInit()
  1182. // }
  1183. // })
  1184. }
  1185. });
  1186. } else {
  1187. // 关闭蓝牙模块
  1188. this.closeBluetoothAdapter()
  1189. }
  1190. },
  1191. closeBluetoothAdapter() {
  1192. // 关闭蓝牙模块
  1193. uni.closeBluetoothAdapter({
  1194. success: () => {
  1195. this.myInit();
  1196. if (this.isUserClose == false) { // 设备端结束用水
  1197. if (this.isChecked) {
  1198. // console.log('设备端已结束用水,蓝牙断开成功')
  1199. uni.showToast({
  1200. icon: 'none',
  1201. title: '设备端已结束用水,蓝牙断开成功',
  1202. duration: 3000
  1203. });
  1204. } else {
  1205. // console.log('用户重启扫描,蓝牙断开成功')
  1206. uni.showToast({
  1207. icon: 'none',
  1208. title: '用户重启扫描,蓝牙断开成功',
  1209. duration: 3000
  1210. });
  1211. }
  1212. } else { // 手机移动端结束用水
  1213. // console.log('APP端已结束用水,蓝牙断开成功')
  1214. uni.showToast({
  1215. icon: 'none',
  1216. title: 'APP端已结束用水,蓝牙断开成功',
  1217. duration: 3000
  1218. });
  1219. }
  1220. }
  1221. })
  1222. },
  1223. setInit() {
  1224. this.closeBLEConnection();
  1225. this.myInit();
  1226. },
  1227. myInit() {
  1228. setTimeout(() => {
  1229. this.isUserClose = false;
  1230. this.isChecked = false;
  1231. this.isConnected = false;
  1232. this.isScan = false;
  1233. this.active = -1;
  1234. this.device_code = ''; // 设备编号
  1235. this.devices = []; // 保存设备, 加了【空中连接】,不需要置为空。
  1236. this.deviceId = ''; // 加了【空中连接】,不需要置为空。
  1237. this.serviceId = '';
  1238. this.characteristicIdForWrite = '';
  1239. this.characteristicIdForNotity = '';
  1240. this.deviceIsNotify = false;
  1241. this.deviceIsWrite = false;
  1242. this.byte35 = ''; // 70 个字符
  1243. this.byte35_tmp = ''; // 70 个字符 临时变量
  1244. this.get_Bluetooth_Bevice = false;
  1245. this.rooms = []; // 宿舍号,蓝牙连接具有时效性,断开连接后清空
  1246. this.start_code = '';
  1247. }, 300);
  1248. },
  1249. /**
  1250. * 10===========10==================10
  1251. * 发送数据到设备
  1252. */
  1253. send(val) {
  1254. let buffer
  1255. let dataView
  1256. let newArr
  1257. if (val == 'start') { // 启动设备
  1258. this.isUserClose = false
  1259. // 发送 17字节 启动代码(会返回 35字节 的数据)
  1260. // b58000265243eb3dd4bb3c5a2ab9042efcf0d2a30a000000000000000014392a0103bc
  1261. newArr = this.str2StrArray(this.start_code)
  1262. } else if (val == 'stop') { // 结束当前使用,设备成功返回:AD+35字节 消费结算代码
  1263. this.isUserClose = true
  1264. // 发送 AAABAD+17字节 启动代码(会返回 ad+35字节 的数据)
  1265. // adb58000265243eb3dd4bb3c5a2ab9042efcf0d2a30a000000000000000014392a0104bc
  1266. newArr = ['AA', 'AB', 'AD'].concat(this.str2StrArray(this.start_code))
  1267. } else {
  1268. // 发送 AAABAC 采集数据(会返回 35字节 的数据)
  1269. // b58000265243eb3dd4bb3c5a2ab9042efcf0d2a30a000000000000000014392a0103bc
  1270. newArr = ['AA', 'AB', 'AC']
  1271. }
  1272. buffer = new ArrayBuffer(newArr.length)
  1273. dataView = new DataView(buffer)
  1274. newArr.forEach((item, i) => {
  1275. dataView.setUint8(i, this.sixteen_to_ten(item))
  1276. })
  1277. // 写特征值数据到设备
  1278. if (this.deviceIsWrite) {
  1279. // 写数据到设备
  1280. this.writeBLECharacteristicValue(val, buffer)
  1281. } else {
  1282. uni.showToast({
  1283. title: '设备不可写',
  1284. duration: 3000
  1285. })
  1286. }
  1287. },
  1288. /**
  1289. * 11====================11=====================11
  1290. * 写数据到设备
  1291. */
  1292. writeBLECharacteristicValue(val, buffer) {
  1293. uni.writeBLECharacteristicValue({
  1294. deviceId: this.deviceId,
  1295. // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
  1296. serviceId: this.serviceId,
  1297. // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
  1298. characteristicId: this.characteristicIdForWrite,
  1299. // 这里的value是ArrayBuffer类型
  1300. value: buffer,
  1301. success: (res) => {
  1302. // console.log(res)
  1303. if (val == 'start') {
  1304. setTimeout(() => {
  1305. this.isChecked = true;
  1306. this.isConnected = true;
  1307. this.byte35 = '';
  1308. }, 300)
  1309. this.process_control(3)
  1310. } else if (val == 'stop') {
  1311. setTimeout(() => {
  1312. this.isChecked = false;
  1313. }, 300)
  1314. }
  1315. },
  1316. fail: (err) => {
  1317. // console.log(err)
  1318. if (err.errCode !== 0) {
  1319. setTimeout(() => {
  1320. this.setInit()
  1321. }, 300)
  1322. if (this.isConnected) {
  1323. uni.showToast({
  1324. title: '设备连接已断开!请在水表上手动停止!',
  1325. icon: 'none',
  1326. duration: 5000
  1327. })
  1328. } else {
  1329. uni.showToast({
  1330. title: '设备连接失败!请重试扫描连接!',
  1331. icon: 'none',
  1332. duration: 5000
  1333. })
  1334. }
  1335. }
  1336. }
  1337. })
  1338. },
  1339. /**
  1340. * 请求获取设备启动码
  1341. */
  1342. async request_device_start_code() {
  1343. if (this.byte35 != '' && this.stu_number != '') {
  1344. const res = await this.$myRequest({
  1345. host: this.ceshi,
  1346. url: '/HotWaters/wpstart.action',
  1347. data: {
  1348. collect_code: this.byte35,
  1349. stu_number: this.stu_number
  1350. }
  1351. })
  1352. // console.log(res)
  1353. let sc = res.data.start_code
  1354. if (typeof(sc) != 'undefined' && sc != '') {
  1355. this.start_code = sc
  1356. setTimeout(() => {
  1357. this.send('start')
  1358. }, 100)
  1359. // 刷新选定的月份消费记录
  1360. this.request_consumption_records()
  1361. } else {
  1362. this.isChecked = false
  1363. uni.showToast({
  1364. icon: 'none',
  1365. title: res.data.mess,
  1366. duration: 3000,
  1367. })
  1368. }
  1369. } else {
  1370. if (typeof this.byte35 == 'undefined' || this.byte35 == '') {
  1371. uni.showToast({
  1372. icon: 'none',
  1373. title: '获取字节码空!'
  1374. });
  1375. }
  1376. if (typeof this.stu_number == 'undefined' || this.stu_number == '') {
  1377. uni.showToast({
  1378. icon: 'none',
  1379. title: '学号为空!'
  1380. });
  1381. }
  1382. // 初始化
  1383. this.setInit()
  1384. }
  1385. },
  1386. /**
  1387. * 请求结算
  1388. */
  1389. async request_pay() {
  1390. if (this.byte35 != '') {
  1391. const res = await this.$myRequest({
  1392. host: this.ceshi,
  1393. url: '/HotWaters/wpconsume.action',
  1394. data: {
  1395. stu_number: this.stu_number,
  1396. user_name: this.user_name,
  1397. collect_code: this.byte35.substring(2)
  1398. }
  1399. })
  1400. // console.log(res)
  1401. if (res.data.mess == "支付成功") {
  1402. uni.showToast({
  1403. icon: 'success',
  1404. title: '结算成功!',
  1405. success: (res1) => {
  1406. this.use_amount = res.data.use_amount.toFixed(2)
  1407. this.amount = (this.amount - this.use_amount).toFixed(2)
  1408. this.$store.state.reshui_amount = this.amount
  1409. setTimeout(() => {
  1410. // 刷新选定的月份消费记录
  1411. this.request_consumption_records()
  1412. }, 1000)
  1413. }
  1414. })
  1415. } else {
  1416. uni.showToast({
  1417. icon: 'none',
  1418. title: res.data.mess,
  1419. duration: 3000
  1420. })
  1421. }
  1422. } else {
  1423. uni.showToast({
  1424. icon: 'success',
  1425. title: '结算字节码空!'
  1426. });
  1427. // 初始化
  1428. this.setInit()
  1429. }
  1430. },
  1431. /**
  1432. * 返回字符处理
  1433. */
  1434. str2StrArray(start_code) {
  1435. if (typeof(start_code) == 'undefined' || start_code == '') {
  1436. uni.showToast({
  1437. icon: 'none',
  1438. title: '设备码获取失败'
  1439. })
  1440. this.setInit()
  1441. return
  1442. }
  1443. if (start_code.length != 34) {
  1444. // console.log('启动码长度错误')
  1445. throw new Error("启动码长度错误");
  1446. return
  1447. }
  1448. var resultArray = new Array()
  1449. for (var i = 0; i < start_code.length; i += 2) {
  1450. resultArray.push(start_code.substr(i, 2));
  1451. }
  1452. return resultArray;
  1453. },
  1454. /**
  1455. * ArrayBuffer转16进度字符串
  1456. */
  1457. ab2hex(buffer) {
  1458. const hexArr = Array.prototype.map.call(
  1459. new Uint8Array(buffer),
  1460. function(bit) {
  1461. // console.log('====================' + bit + '==========================')
  1462. return ('00' + bit.toString(16)).slice(-2)
  1463. }
  1464. )
  1465. return hexArr.join('');
  1466. },
  1467. /**
  1468. * 16进制转10进制
  1469. */
  1470. sixteen_to_ten(str) {
  1471. return parseInt(str, 16);
  1472. }
  1473. }
  1474. }
  1475. </script>
  1476. <style scoped lang="scss">
  1477. .content {
  1478. width: 100%;
  1479. height: 100%;
  1480. .container {
  1481. width: 100%;
  1482. padding: 20rpx 40rpx;
  1483. box-sizing: border-box;
  1484. .header {
  1485. display: flex;
  1486. justify-content: center;
  1487. position: relative;
  1488. height: 200rpx;
  1489. .scan {
  1490. display: flex;
  1491. flex-direction: column;
  1492. justify-content: center;
  1493. align-items: center;
  1494. height: 200rpx;
  1495. width: 30%;
  1496. .iconfont {
  1497. margin-bottom: 10rpx;
  1498. font-size: 100rpx;
  1499. color: $my-color-primary;
  1500. }
  1501. }
  1502. .scan_hover {
  1503. border-radius: 15rpx;
  1504. background-color: $my-color-btn-background;
  1505. }
  1506. .qinshihao {
  1507. display: flex;
  1508. align-items: center;
  1509. position: fixed;
  1510. top: 20rpx;
  1511. right: 30rpx;
  1512. font-size: 28rpx;
  1513. height: 38rpx;
  1514. .icon-zhuye {
  1515. margin-right: 10rpx;
  1516. font-family: Microsoft YaHei-3970(82674968);
  1517. color: $my-color-primary;
  1518. }
  1519. .compustxt {
  1520. font-size: 18rpx;
  1521. }
  1522. }
  1523. }
  1524. .start_text {
  1525. .start_top,
  1526. .start_mid {
  1527. display: flex;
  1528. justify-content: space-between;
  1529. height: 100rpx;
  1530. align-items: center;
  1531. border-bottom: 2rpx #ccc solid;
  1532. .item_left {
  1533. display: flex;
  1534. align-items: center;
  1535. }
  1536. .start_mid_txt {
  1537. padding: 16rpx;
  1538. border-radius: 10rpx;
  1539. font-size: 36rpx;
  1540. font-weight: bold;
  1541. color: #333;
  1542. }
  1543. .iconfont {
  1544. font-size: 50rpx;
  1545. color: $my-color-primary;
  1546. margin-right: 20rpx;
  1547. }
  1548. .start_payamount {
  1549. display: flex;
  1550. justify-content: flex-end;
  1551. align-items: center;
  1552. font-size: 38rpx;
  1553. padding: 10rpx;
  1554. font-family: Microsoft YaHei-3970(82674968);
  1555. color: #B2B2B2;
  1556. border-radius: 10rpx;
  1557. .icon-dayuhao {
  1558. margin: 0 0 0 20rpx;
  1559. font-size: 38rpx;
  1560. color: #B2B2B2;
  1561. }
  1562. }
  1563. }
  1564. .start_bot {
  1565. display: flex;
  1566. justify-content: space-between;
  1567. height: 100rpx;
  1568. align-items: center;
  1569. .kongzhonglianjie {
  1570. margin: 0;
  1571. height: 60rpx;
  1572. line-height: 60rpx;
  1573. font-size: 28rpx;
  1574. background-color: #1296DB;
  1575. color: #FFFFFF;
  1576. }
  1577. .start_bot_txt {
  1578. margin-left: 20rpx;
  1579. color: #333;
  1580. font-size: 28rpx;
  1581. }
  1582. }
  1583. }
  1584. .btn_room {
  1585. font-size: 28rpx;
  1586. background-color: #41c560;
  1587. margin: 10rpx auto;
  1588. }
  1589. .start_up_process {
  1590. padding: 20rpx 0;
  1591. color: #007AFF;
  1592. }
  1593. .ad {
  1594. margin: 0 -40rpx;
  1595. padding: 10rpx;
  1596. width: 730rpx;
  1597. height: 424rpx;
  1598. .ad_img {
  1599. height: 100%;
  1600. width: 100%;
  1601. }
  1602. }
  1603. .title {
  1604. height: 100rpx;
  1605. margin: 0 -40rpx;
  1606. padding: 0 40rpx;
  1607. line-height: 100rpx;
  1608. color: #808080;
  1609. font-size: 32rpx;
  1610. background: #f2f2f2;
  1611. }
  1612. .record-item {
  1613. width: 100%;
  1614. .uni-list-cell-db {
  1615. height: 100rpx;
  1616. line-height: 100rpx;
  1617. font-weight: bold;
  1618. .uni-input {
  1619. display: flex;
  1620. align-items: center;
  1621. height: 58rpx;
  1622. text:nth-child(1) {
  1623. margin-right: 10rpx;
  1624. }
  1625. }
  1626. }
  1627. .item-list {
  1628. height: 80rpx;
  1629. display: flex;
  1630. align-items: center;
  1631. justify-content: space-between;
  1632. border-top: 2rpx #ccc solid;
  1633. .icon-shijian {
  1634. margin-right: 8rpx;
  1635. }
  1636. .icon-shuidi {
  1637. margin-right: 3rpx;
  1638. }
  1639. .item-list-txt {
  1640. font-size: 28rpx;
  1641. &:nth-of-type(2) {
  1642. color: #515151;
  1643. }
  1644. &:nth-of-type(3) {
  1645. color: #f76200;
  1646. font-size: 32rpx;
  1647. }
  1648. }
  1649. }
  1650. }
  1651. }
  1652. }
  1653. </style>