From 71347fe6f934de97232491b7cdfba11196b145e6 Mon Sep 17 00:00:00 2001 From: Jian Sun Date: Sun, 4 Dec 2022 23:16:44 +0800 Subject: [PATCH 1/3] :tada: Add wechat app, ble feature --- src/wechat_app/app.js | 21 + src/wechat_app/app.json | 15 + src/wechat_app/app.wxss | 10 + src/wechat_app/images/ic_ble.png | Bin 0 -> 2757 bytes src/wechat_app/images/ic_sel.png | Bin 0 -> 878 bytes src/wechat_app/images/ic_unsel.png | Bin 0 -> 1035 bytes src/wechat_app/pages/index/handler.js | 110 ++++ src/wechat_app/pages/index/index.js | 485 ++++++++++++++++++ src/wechat_app/pages/index/index.json | 3 + src/wechat_app/pages/index/index.wxml | 95 ++++ src/wechat_app/pages/index/index.wxss | 242 +++++++++ src/wechat_app/pages/logs/logs.js | 18 + src/wechat_app/pages/logs/logs.json | 4 + src/wechat_app/pages/logs/logs.wxml | 6 + src/wechat_app/pages/logs/logs.wxss | 8 + src/wechat_app/pages/selble/selble.js | 212 ++++++++ src/wechat_app/pages/selble/selble.json | 4 + src/wechat_app/pages/selble/selble.wxml | 27 + src/wechat_app/pages/selble/selble.wxss | 43 ++ src/wechat_app/project.config.json | 52 ++ src/wechat_app/project.private.config.json | 7 + src/wechat_app/sitemap.json | 7 + src/wechat_app/utils/bletool.js | 560 +++++++++++++++++++++ src/wechat_app/utils/runtime.js | 1 + src/wechat_app/utils/util.js | 19 + 25 files changed, 1949 insertions(+) create mode 100644 src/wechat_app/app.js create mode 100644 src/wechat_app/app.json create mode 100644 src/wechat_app/app.wxss create mode 100644 src/wechat_app/images/ic_ble.png create mode 100644 src/wechat_app/images/ic_sel.png create mode 100644 src/wechat_app/images/ic_unsel.png create mode 100644 src/wechat_app/pages/index/handler.js create mode 100644 src/wechat_app/pages/index/index.js create mode 100644 src/wechat_app/pages/index/index.json create mode 100644 src/wechat_app/pages/index/index.wxml create mode 100644 src/wechat_app/pages/index/index.wxss create mode 100644 src/wechat_app/pages/logs/logs.js create mode 100644 src/wechat_app/pages/logs/logs.json create mode 100644 src/wechat_app/pages/logs/logs.wxml create mode 100644 src/wechat_app/pages/logs/logs.wxss create mode 100644 src/wechat_app/pages/selble/selble.js create mode 100644 src/wechat_app/pages/selble/selble.json create mode 100644 src/wechat_app/pages/selble/selble.wxml create mode 100644 src/wechat_app/pages/selble/selble.wxss create mode 100644 src/wechat_app/project.config.json create mode 100644 src/wechat_app/project.private.config.json create mode 100644 src/wechat_app/sitemap.json create mode 100644 src/wechat_app/utils/bletool.js create mode 100644 src/wechat_app/utils/runtime.js create mode 100644 src/wechat_app/utils/util.js diff --git a/src/wechat_app/app.js b/src/wechat_app/app.js new file mode 100644 index 0000000..b48f6ee --- /dev/null +++ b/src/wechat_app/app.js @@ -0,0 +1,21 @@ +// app.js +App({ + onLaunch() { + // 展示本地存储能力 + const logs = wx.getStorageSync('logs') || [] + logs.unshift(Date.now()) + wx.setStorageSync('logs', logs) + + // 登录 + wx.login({ + success: res => { + // 发送 res.code 到后台换取 openId, sessionKey, unionId + } + }) + }, + globalData: { + userInfo: null, + selble:"", //所选择蓝牙的mac + bleUtil:"", //蓝牙助手 + } +}) diff --git a/src/wechat_app/app.json b/src/wechat_app/app.json new file mode 100644 index 0000000..ed43b57 --- /dev/null +++ b/src/wechat_app/app.json @@ -0,0 +1,15 @@ +{ + "pages":[ + "pages/selble/selble", + "pages/index/index", + "pages/logs/logs" + ], + "window":{ + "backgroundTextStyle":"light", + "navigationBarBackgroundColor": "#fff", + "navigationBarTitleText": "Weixin", + "navigationBarTextStyle":"black" + }, + "style": "v2", + "sitemapLocation": "sitemap.json" +} diff --git a/src/wechat_app/app.wxss b/src/wechat_app/app.wxss new file mode 100644 index 0000000..06c6fc9 --- /dev/null +++ b/src/wechat_app/app.wxss @@ -0,0 +1,10 @@ +/**app.wxss**/ +.container { + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + padding: 200rpx 0; + box-sizing: border-box; +} diff --git a/src/wechat_app/images/ic_ble.png b/src/wechat_app/images/ic_ble.png new file mode 100644 index 0000000000000000000000000000000000000000..a4769a91640958bdff054118ec698027b2876c74 GIT binary patch literal 2757 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 Eg7GSi3jhEB literal 0 HcmV?d00001 diff --git a/src/wechat_app/images/ic_unsel.png b/src/wechat_app/images/ic_unsel.png new file mode 100644 index 0000000000000000000000000000000000000000..194588fd27f2d81a34765d80bde14cf159915bb0 GIT binary patch literal 1035 zcmV+m1oZofP)A0N`Dv)JUmRI(Mlv{|aDgYHCvu1TQi3vjB1c7{GC6K1xKNH=E6KVHnOy zaHUkwE)gWQS{W{;NZzLiT}Q5e0+SHWm)e7 zxE{by0QPFFPbK%Q01)^43jkXHd|a>B_g5;FU)Penb!KvMa!aGpI7~#+mh(!foykfp z0~j40y`rnrW!ot17!^4Xbco~2( zW(2@<0Df>BXIrsYJb&4l69J?WK@gmXukS&vwcMw;8V?^|x5YKg8AxY-T^Sl|k70mp&0Pu-u0KfsQ^})=uU*w#SeT110 zkul~g0Na^)x9hqy{|5li^L7!@rvOd}0J(0PEz9Z|7#NV(D)UvXR(ovQ7T*0V0O~Sq z>h=1jN~I#dGhbt4V;vnG9WtC68v-DH8RgF|0od>sY%B>k{2I0%A^)n|%5WtFu zDESmK^R2Gyp3M?OtT{wkE!wu-vowr+-=ARSegIQi>tdDwj4?F;#pPin$zoJr%Q%jr zXvbP5SUcd!am>tjNVQiJB(sj=Y|luL$c?)Zz-wA-nFoIG(JS>6H> zlk#xf4lyQg5z(t@)lzIso(J$uY)sB5r5;ITOj;nsnl&1YmjQ@1b6VC6z!4()jEKJP z>grmuX7ls&d1mfq=KBEbOIWi2!0Z3nnk9Q0YdB%-lcF0_@?nvP-ie}Uq}{{T)*ZJJ ziamE6XCE`~A)>9!EPcHu{{9OQ%`)?8B03fX!AEKB`Jb2D;uJIHG@Aeb002ovPDHLk FV1jth { + var isSuccess = false; + app.globalData.bleUtil.sendMsg(data, function (res) { + isSuccess = true; + if (res.errCode == 0) { + that.appendLogs("发送数据 " + data + " 成功",that); + success(true); + } else { + that.appendLogs("发送数据 " + data + " 失败",that); + success(false); + } + }, false); + //3秒后若没有发送成功,则认为发送失败 + setTimeout(function(res){ + if(!isSuccess){ + success(false); + that.appendLogs("发送数据 " + data + " 失败",that); + } + },3000); + }); +} + +function sleep(times,that) { + return new Promise((success, fail) => { + setTimeout(function (res) { + success(true); + that.appendLogs("延迟 " + times + " 毫秒",that); + }, times); + }); +} + + + +var sendList = async (sendlist,sendtimes,that) => { + var i = 0; + isSend = true; + while(isSend){ + let result = await sendBleMsg(sendlist[i],that); + if(!result){ + stop(that); + return; + } + await sleep(sendtimes,that); + i++; + if(i > sendlist.length - 1){ + i = 0; + } + } +} + + +var sendCoustomList = async (sendlist,title,that) => { + that.appendLogs("开始发送功能 " + title ,that); + that.setData({ + isRund:true + }) + isSend = true; + while(isSend){ + for(var x in sendlist){ + if(sendlist[x].opertype == "DE"){ + await sleep(sendlist[x].value,that); + } else if(sendlist[x].opertype == "SEND"){ + let result = await sendBleMsg(sendlist[x].value,that); + if(!result){ + stop(that); + return; + } + } + } + if(that.data.ismenuRund){ + isSend = true; + } else { + isSend = false; + } + } + + that.setData({ + isRund:false + }) + that.appendLogs("功能 " + title + "发送完毕",that); + +} + + +var stop = function(that){ + isSend = false; + if(that){ + that.setData({ + isRund:false + }) + that.appendLogs("停止发送",that); + } +} + +module.exports = { + sendList: sendList, + stop, + sendCoustomList +} \ No newline at end of file diff --git a/src/wechat_app/pages/index/index.js b/src/wechat_app/pages/index/index.js new file mode 100644 index 0000000..5e819fe --- /dev/null +++ b/src/wechat_app/pages/index/index.js @@ -0,0 +1,485 @@ +// pages/uploadimg/uploadimg.js +const app = getApp(); +var util = require("../../utils/util.js"); +var handler = require("handler.js"); +var timer = {}; +var menuToCmd = {}; +Page({ + + /** + * 页面的初始数据 + */ + data: { + imgswiperset: { //swiper信息设置 + indicator_dots: false, //是否显示面板指示点 + autoplay: false, //是否自动切换 + interval: 10000, //自动切换时间间隔 + duration: 200, //滑动动画时长 + indicator_color: '#b0b0b0', //指示点颜色 + indicator_active_color: 'rgb(19, 157, 236)', //当前选中的指示点颜色 + circular: false, //是否采用衔接滑 + }, + msg:"", + isShowDialog: false, //是否显示弹窗 + statusinfo: { + status: '未连接(点击切换蓝牙)', + }, + write_id:"--", + notifty_id:"--", + title:"选择服务", + logs:[], + sendtimes:0, + servicelist:[], + lastindex:"item0", + ismenuRund:false,//是否循环发送 + customMen:[],//自定义控制菜单 + isRund:false,//是否正在循环发送消息 + menu:[ + { + value:"", + issel:false, + }, + { + value:"", + issel:false, + }, + { + value:"", + issel:false, + }, + { + value:"", + issel:false, + }, + ] + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function(options) { + if(app.globalData.selble.deviceId){ + wx.setNavigationBarTitle({ + title:(app.globalData.selble.name || "未知设备") + "(" + app.globalData.selble.deviceId + ")" + }) + } + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady: function() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow: function() { + if (app.globalData.issel && app.globalData.bleUtil != "") { + var that = this; + that.data.statusinfo.status = '连接中'; + app.globalData.issel = false; + appendLogs("连接设备中",that); + that.setData({ + statusinfo: that.data.statusinfo + }) + //连接蓝牙 + app.globalData.bleUtil.connect(app.globalData.selble.deviceId, function(res) { + //连接回调 + if (res.return_code == "0") { + that.data.statusinfo.status = '已连接'; + appendLogs("连接设备成功",that); + that.setData({ + statusinfo: that.data.statusinfo + }) + } else { + that.data.statusinfo.status = '连接失败'; + appendLogs("连接设备失败",that); + that.setData({ + statusinfo: that.data.statusinfo + }) + } + }, function(res) { + //接收到数据回调 + console.log("接受到消息:" + res.value.strHexData); + appendLogs("接受到消息 " + res.value.strHexData,that); + }); + } + getMenuList(this); + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide: function() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload: function() { + this.selBle(); + handler.stop(); + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh: function() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom: function() { + + }, + /** + * 用户点击右上角分享 + */ + onShareAppMessage: function() { + + }, + menuCheckBocChange:function(res){ + this.data.ismenuRund = res.detail.value; + }, + gotoStop:function(res){ + handler.stop(this); + }, + doSendItem:function(res){ + + if (app.globalData.bleUtil == "") { + showHintModal("未连接设备"); + appendLogs("未连接设备",this); + return; + } + + if (this.data.write_id == '--') { + showHintModal("未选择可写服务"); + appendLogs("未选择可写服务",this); + return; + } + + var item = res.currentTarget.dataset.item; + var sendlist = getCMD(item); + + if(!sendlist){ + return; + } + + handler.sendCoustomList(sendlist,item,this); + + }, + doClearData:function(res){ + this.setData({ + logs:[] + }) + wx.showToast({ + title: "清除成功", + icon:"none" + }) + }, + doRund:function(res){ + if(this.data.isRund){ + handler.stop(this); + return; + } + if (app.globalData.bleUtil == "") { + showHintModal("未连接设备"); + appendLogs("未连接设备",this); + return; + } + if (!app.globalData.bleUtil.isCanWrite()) { + showHintModal("未选择可写服务"); + appendLogs("未选择可写服务",this); + return; + } + + var sendtimes = parseInt(this.data.sendtimes); + + if(!sendtimes && sendtimes != 0){ + showHintModal("循环发送间隔不正确"); + appendLogs("循环发送间隔不正确",this); + return; + } + + var that = this; + + var menu = that.data.menu; + var sendlist = []; + + for(var x in menu){ + if(menu[x].value && menu[x].issel){ + sendlist.push(menu[x].value); + } + } + if(sendlist.length == 0){ + showHintModal("需循环发送的内容为空"); + appendLogs("需循环发送的内容为空",this); + return; + } + + + appendLogs("开始循环发送",this); + + this.setData({ + isRund:true + }) + + handler.sendList(sendlist,sendtimes,that); + + + }, + doGetSendTimes:function(res){ + this.data.sendtimes = res.detail.value; + }, + selBle: function(res) { + var that = this; + that.data.statusinfo.status = '已断开连接'; + that.setData({ + statusinfo:that.data.statusinfo + }) + if (!app.globalData.bleUtil && app.globalData.bleUtil != "") { + app.globalData.bleUtil.disconnect(function(res) {}); + } + appendLogs("断开当前连接",this); + }, + doSend:function(res){ + if (app.globalData.bleUtil == "") { + showHintModal("未连接设备"); + appendLogs("未连接设备",this); + return; + } + var msg = res.detail.value.msg; + + sendBleMsg(msg,this); + }, + doSendValue:function(res){ + if (app.globalData.bleUtil == "") { + showHintModal("未连接设备"); + appendLogs("未连接设备",this); + return; + } + if (!app.globalData.bleUtil.isCanWrite()) { + showHintModal("未选择可写服务"); + appendLogs("未选择可写服务",this); + return; + } + var index = res.currentTarget.dataset.index; + var menu = this.data.menu; + if (!menu[index].value) { + showHintModal("不能发送空值"); + appendLogs("不能发送空值",this); + return; + } + sendBleMsg(menu[index].value,this); + }, + doShowSelService:function(res){ + var type = res.currentTarget.dataset.type; + if(!app.globalData.bleUtil || !app.globalData.bleUtil.getdevConStatus()){ + showHintModal("未连接成功,请先连接成功再试"); + return; + } + var servicelist = app.globalData.bleUtil.getServiceList(); + if(!servicelist){ + showHintModal("未成功获取服务,或服务不存在"); + return; + } + var title = type == "write"?"选择可写服务":"选择可读/通知服务"; + this.setData({ + type, + isShowDialog:true, + title, + servicelist + }) + }, + /** + * 隐藏显示 + */ + doHidenDiaolog: function (res) { + this.setData({ + isShowDialog:false + }) + }, + donothing: function (res) { + + }, + changeOpen:function(res){ + var index = res.currentTarget.dataset.index; + var servicelist = this.data.servicelist; + servicelist[index].open = !servicelist[index].open; + this.setData({ + servicelist + }) + }, + doShowMenu:function(res){ + var item = res.currentTarget.dataset.item; + var index = res.currentTarget.dataset.index; + wx.showActionSheet({ + itemList: ["编辑","删除"], + success:function(res) { + switch(res.tapIndex){ + case 0:{ + wx.navigateTo({ + url: '../addsendbtn/addsendbtn?title=' + item , + }) + } + break; + case 1:{ + wx.showModal({ + content:"确认删除按钮 " + item + ",删除后不可恢复", + success:function(res) { + if(res.confirm){ + app.globalData.menu.splice(index,1); + wx.setStorageSync("menulist", app.globalData.menu); + that.setData({ + customMen:app.globalData.menu + }) + } + } + }) + } + break; + } + } + }) + }, + doSelUuid:function(res){ + var item = res.currentTarget.dataset.item; + var each = res.currentTarget.dataset.each; + if(this.data.type == "write" && each.properties.write){ + app.globalData.bleUtil.setWriteUUID(item.uuid,each.uuid); + wx.showToast({ + title: '设置成功', + icon:"none" + }) + this.setData({ + isShowDialog:false, + write_id:each.uuid + }) + } else if (this.data.type == "reno" && (each.properties.read || each.properties.notify)){ + if(each.properties.notify){ + app.globalData.bleUtil.setNotiftyUUID(item.uuid,each.uuid); + } else if(each.properties.read){ + app.globalData.bleUtil.setReadUUID(item.uuid,each.uuid); + } + wx.showToast({ + title: '设置成功', + icon:"none" + }) + this.setData({ + isShowDialog:false, + notifty_id:each.uuid + }) + } else { + var hint = this.data.type == "write"?"当前服务不可写":"当前服务不可读且不可通知"; + showHintModal(hint); + } + }, + doGetInput:function(res){ + var index = res.currentTarget.dataset.index; + var menu = this.data.menu; + menu[index].value = res.detail.value; + }, + checkboxChange:function(res){ + console.log(res); + const index = res.detail.value; + var menu = this.data.menu; + for(var x in menu){ + menu[x].issel = false; + } + for(var j in index){ + menu[index[j]].issel = true; + } + }, + doReadValue:function(res){ + if (app.globalData.bleUtil == "") { + showHintModal("未连接设备"); + appendLogs("未连接设备",this); + return; + } + if (!app.globalData.bleUtil.isCanRead() && !app.globalData.bleUtil.isCanNotifty()) { + showHintModal("未选择可写服务"); + appendLogs("未选择可写服务",this); + return; + } + app.globalData.bleUtil.doRead(); + appendLogs("成功读取",this); + }, + gotoAddSendBtn:function(res){ + wx.navigateTo({ + url: '../addsendbtn/addsendbtn', + }) + }, + appendLogs, +}) + +function appendLogs(info,that){ + var logs = that.data.logs; + var date = new Date(); + var nowtime = util.formatTime(date); + info = "【" + nowtime + "】" + info; + if(logs.length > 1000){ + logs.shift(); + } + logs.push(info); + that.setData({ + logs, + lastindex:"item" + (logs.length - 1) + }) +} + +function showHintModal(msg) { + wx.showModal({ + title: '提示', + content: msg, + showCancel: false, + confirmText: "我知道了" + }) +} + +function sendBleMsg(msg,that) { + appendLogs("发送数据 " + msg + " 中",that); + app.globalData.bleUtil.sendMsg(msg, function(res) { + if (res.errCode == 0) { + appendLogs("发送数据 " + msg + " 成功",that); + return false; + } else { + appendLogs("发送数据 " + msg + " 失败," + res.msg,that); + return true; + } + }, false); +} + +function getMenuList(that){ + if(app.globalData.menu){ + that.setData({ + customMen:app.globalData.menu + }) + return; + } + let menulist = wx.getStorageSync('menulist'); + if(!menulist){ + menulist = []; + } + app.globalData.menu = menulist; + that.setData({ + customMen:menulist + }) +} + +function getCMD(title){ + if(menuToCmd[title]){ + return menuToCmd[title]; + } + let send = wx.getStorageSync(title); + if(!send){ + util.showHintModal("不存在该条指令"); + return; + } + menuToCmd[title] = send; + return send; +} \ No newline at end of file diff --git a/src/wechat_app/pages/index/index.json b/src/wechat_app/pages/index/index.json new file mode 100644 index 0000000..8835af0 --- /dev/null +++ b/src/wechat_app/pages/index/index.json @@ -0,0 +1,3 @@ +{ + "usingComponents": {} +} \ No newline at end of file diff --git a/src/wechat_app/pages/index/index.wxml b/src/wechat_app/pages/index/index.wxml new file mode 100644 index 0000000..50aa418 --- /dev/null +++ b/src/wechat_app/pages/index/index.wxml @@ -0,0 +1,95 @@ + + + + + + {{statusinfo.status}} + + + + + + + + + + + 当前写服务:{{write_id}} + 当前读/通知服务:{{notifty_id}} + + + + + + + + + + + + + + + + + 温馨提示:左滑可进入自定义功能区 + + + + + 自定义功能区 + + + + + + + + + + + + 温馨提示:右滑可返回发送区,长按可编辑或删除 + + + + + + + + + + + {{item}} + + + + \ No newline at end of file diff --git a/src/wechat_app/pages/index/index.wxss b/src/wechat_app/pages/index/index.wxss new file mode 100644 index 0000000..1f171fd --- /dev/null +++ b/src/wechat_app/pages/index/index.wxss @@ -0,0 +1,242 @@ +/* pages/uploadimg/uploadimg.wxss */ +.main_view_back { + width: 100vw; +} + +.item_view_back { + width: 90vw; + margin-left: 5vw; + margin-top: 1vw; + +} + +.item_img { + width: 5vw; + height: 5vw; +} + +.item_title_name { + color: #000; + font-size: 90%; +} + +.item_title { + width: 100%; + margin-top: 2vw; +} + +.img_back_class { + width: 100%; + height: 81%; + margin-top: 2vw; +} + +.img_size { + width: 50vw; + height: 50vw; + border-radius: 50%; +} + +.border_blue { + border: 1px dashed rgba(0, 120, 253, 1); +} + +.border_white { + border: 1px dashed white; +} + +.small_img_size { + width: 5vw; + height: 5vw; +} + +.blue_text { + color: #1A8DFF; + font-size: 90%; +} + +.btn_disable { + width: 90%; + margin-left: 5%; + color: white; + font-size: 80%; + background: linear-gradient(180deg, rgba(189, 189, 189, 1) 0%, rgba(102, 102, 102, 1) 100%, rgba(204, 204, 204, 1) 100%); + border-radius: 10px; +} + +.btn_normal { + width: 92%; + font-size: 80%; + color: white; + background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(255, 112, 191, 1) 0%, rgba(69, 178, 255, 1) 0%, rgba(0, 126, 255, 1) 100%); + border-radius: 10px; +} + +.btn_normal:active { + width: 92%; + font-size: 80%; + color: white; + background: rgba(0, 126, 255, 1); + border-radius: 10px; +} + +.item_title_back_class { + width: 87%; + margin-left: 5%; +} + +.selimg_list { + width: 94vw; + margin: 3vw 0; +} + +.sma_img_size { + width: 15vw; + height: 15vw; + margin-left: 3vw; + border-radius: 50%; +} + +.btn_class, +.btn_class:active { + width: 90vw; + margin-top: 10px; + margin-left: 5vw; + font-size: 90%; + color: #fff; + border-radius: 10px; +} + +.btn_class { + background: rgb(51, 225, 231); +} + +.btn_class:active { + background: rgb(51, 225, 231); +} + +.send_back { + width: 84vw; + margin-left: 5vw; + margin-top: 3vw; + background: #FFF; + padding: 3vw; + border-radius: 5px; +} + + + +.dialog_close { + font-size: 100%; + width: 100vw; + height: 15vw; + font-family: PingFangSC-Medium; + font-weight: 500; + background: #fff; + text-align: center; + color: rgba(0, 0, 0, 1); + box-shadow:0px -2px 5px 0px rgba(0, 0, 0, 0.1); +} + +.dialog_top { + width: 80%; + padding: 3% 10%; + background: rgba(248, 248, 248, 1); + box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1); +} + +.dialog_devname { + font-size: 110%; + font-family: PingFangSC-Heavy; + font-weight: 800; + color: rgba(0, 0, 0, 1); +} + +.dialog_mac { + font-size: 90%; + margin-top: 2%; + font-family: PingFangSC-Medium; + font-weight: 500; + color: rgba(0, 0, 0, 1); +} + +.dialog_menu { + padding: 5%; + width: 90%; + background: #fff; + box-shadow:0px -2px 5px 0px rgba(0, 0, 0, 0.1); +} + +.dialog_red_text, .dialog_green_text { + font-size: 80%; + font-family: PingFangSC-Medium; + font-weight: 500; + border-radius: 5px; + color: #fff; + padding: 1px 2%; + max-height: 6vw; + min-width: 16vw; +} + + +.dialog_red_text { + background: rgba(238, 68, 42, 1); +} + +.dialog_green_text { + background: rgba(33, 167, 130, 1); +} + +.small_text{ + font-size: 100%; + color: #000; +} + +.dialog_view_back{ + width: 100vw; + height: 100vh; + top: 0; + position: fixed; + z-index: 2; + background: rgba(0, 0, 0, 0.8); +} + +.dialog_cneter_view{ + width: 80vw; + background: #fff; + border-radius: 10px; +} + +.dialog_title_view{ + width: 100%; + padding: 3% 0%; + background: linear-gradient(0deg, rgb(19, 138, 207) 0%, rgb(46, 164, 231) 100%); + border-radius: 10px 10px 0 0; + color: #fff; + font-size: 90%; +} + +.dialog_content_view{ + width: 90%; + padding: 5%; + height: 50vh; + color: #000; + font-size: 80%; +} + +.dialog_text{ + font-size:90%; + color:#000; +} + +::-webkit-scrollbar { + display: none; + width: 0; + height: 0; + color: transparent; +} + +.swiper_class{ + width: 100vw; + height: 60vh; +} \ No newline at end of file diff --git a/src/wechat_app/pages/logs/logs.js b/src/wechat_app/pages/logs/logs.js new file mode 100644 index 0000000..85f6aac --- /dev/null +++ b/src/wechat_app/pages/logs/logs.js @@ -0,0 +1,18 @@ +// logs.js +const util = require('../../utils/util.js') + +Page({ + data: { + logs: [] + }, + onLoad() { + this.setData({ + logs: (wx.getStorageSync('logs') || []).map(log => { + return { + date: util.formatTime(new Date(log)), + timeStamp: log + } + }) + }) + } +}) diff --git a/src/wechat_app/pages/logs/logs.json b/src/wechat_app/pages/logs/logs.json new file mode 100644 index 0000000..3ee76c1 --- /dev/null +++ b/src/wechat_app/pages/logs/logs.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText": "查看启动日志", + "usingComponents": {} +} \ No newline at end of file diff --git a/src/wechat_app/pages/logs/logs.wxml b/src/wechat_app/pages/logs/logs.wxml new file mode 100644 index 0000000..0b6b645 --- /dev/null +++ b/src/wechat_app/pages/logs/logs.wxml @@ -0,0 +1,6 @@ + + + + {{index + 1}}. {{log.date}} + + diff --git a/src/wechat_app/pages/logs/logs.wxss b/src/wechat_app/pages/logs/logs.wxss new file mode 100644 index 0000000..94d4b88 --- /dev/null +++ b/src/wechat_app/pages/logs/logs.wxss @@ -0,0 +1,8 @@ +.log-list { + display: flex; + flex-direction: column; + padding: 40rpx; +} +.log-item { + margin: 10rpx; +} diff --git a/src/wechat_app/pages/selble/selble.js b/src/wechat_app/pages/selble/selble.js new file mode 100644 index 0000000..37b369b --- /dev/null +++ b/src/wechat_app/pages/selble/selble.js @@ -0,0 +1,212 @@ +// pages/selble/selble.js +var Bletool = require("../../utils/bletool.js"); +// var util = require("../../utils/util.js"); +const app = getApp(); +var bleUtil; +Page({ + + /** + * 页面的初始数据 + */ + data: { + getDevList: {}, //已扫描到设备列表 + deviceslist: [ + + ], //蓝牙数据 + devicename: 0, + repdata: "", + hint: "", + selmac:'' + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + var that = this; + that.data.getDevList = {}; + app.globalData.issel = false; + if (app.globalData.bleUtil == ""){ + bleUtil = new Bletool(); + app.globalData.bleUtil = bleUtil; + bleUtil.initble(function (res) { + console.log(res); + if (res.return_code == "0") { + setTimeout(function (res) { + //开始蓝牙扫描 10秒后停止扫描 + wx.showNavigationBarLoading(); + bleUtil.startScanle(function (res) { + //获取设备回调 + console.log(res); + if (!that.data.getDevList[res.devices[0].deviceId]) { + var devices = that.data.deviceslist; + devices.push(res.devices[0]); + that.data.getDevList[res.devices[0].deviceId] = devices.length; + that.setData({ + deviceslist: devices + }); + } else { + var devices = that.data.deviceslist; + var index = that.data.getDevList[res.devices[0].deviceId] - 1; + devices[index].RSSI = res.devices[0].RSSI; + that.setData({ + deviceslist: devices + }); + } + }, function (res) { + if (res.msg == "扫描结束") { + //扫描结束 + wx.hideNavigationBarLoading() + } + }, 10000, true); + }, 1000); + } else { + bleUtil = undefined; + app.globalData.bleUtil = ""; + wx.showModal({ + title: '提示', + content: '蓝牙初始化失败,请检查是否已打开蓝牙', + showCancel: false, + confirmText: "我知道了", + success:function(Res){ + wx.navigateBack({ + complete: (res) => { + + }, + }) + } + }) + } + }, function (res) { + console.log(res); + + }, function (res) { + console.log(res); + }); + } else { + bleUtil = app.globalData.bleUtil; + that.refresh(); + app.globalData.bleUtil.disconnect(function (res) { + console.log(res); + }); + } + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady: function () { + + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow: function () { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide: function () { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload: function () { + if (bleUtil) { + bleUtil.stopScanle(); + } + if (app.globalData.bleUtil != "") { + app.globalData.bleUtil.close(function(res) { + console.log(res); + app.globalData.bleUtil = ""; + }); + } + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh: function () { + this.refresh(); + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom: function () { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage: function () { + + }, + selItem: function (res) { + var that = this; + var item = res.currentTarget.dataset.item; + app.globalData.selble = item; + that.setData({ + selmac: item.deviceId + }) + }, + doback:function(res){ + app.globalData.issel = true; + bleUtil.stopScanle(); + wx.navigateTo({ + url: '../index/index', + }) + }, + refresh:function(res){ + var that = this; + if (bleUtil) { + wx.showNavigationBarLoading(); + bleUtil.startScanle(function (res) { + //获取设备回调 + console.log(res); + if (!that.data.getDevList[res.devices[0].deviceId]) { + var devices = that.data.deviceslist; + devices.push(res.devices[0]); + that.data.getDevList[res.devices[0].deviceId] = devices.length; + that.setData({ + deviceslist: devices + }); + } else { + var devices = that.data.deviceslist; + var index = that.data.getDevList[res.devices[0].deviceId] - 1; + devices[index].RSSI = res.devices[0].RSSI; + that.setData({ + deviceslist: devices + }); + } + }, function (res) { + if (res.return_code == 1) { + showHintModal("正在扫描中,请勿重复操作"); + } + if (res.msg == "扫描结束") { + //扫描结束 + wx.hideNavigationBarLoading() + } + }, 10000, true); + } else { + showHintModal("蓝牙未打开,请打开蓝牙后,重新打开该页面"); + } + } +}) + +function showHintModal(msg) { + wx.showModal({ + title: '提示', + content: msg, + showCancel: false, + confirmText: "我知道了", + success: function (res) { } + }) +} \ No newline at end of file diff --git a/src/wechat_app/pages/selble/selble.json b/src/wechat_app/pages/selble/selble.json new file mode 100644 index 0000000..25481c5 --- /dev/null +++ b/src/wechat_app/pages/selble/selble.json @@ -0,0 +1,4 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "选择设备" +} \ No newline at end of file diff --git a/src/wechat_app/pages/selble/selble.wxml b/src/wechat_app/pages/selble/selble.wxml new file mode 100644 index 0000000..734a522 --- /dev/null +++ b/src/wechat_app/pages/selble/selble.wxml @@ -0,0 +1,27 @@ + + + + + + + {{item.name || "未知设备"}}({{item.deviceId}}) + + + + + + 信号值:{{item.RSSI || "0"}} + + + 广播包数据:{{item.advertisData || ""}} + + + + + + 刷新 + + + + + \ No newline at end of file diff --git a/src/wechat_app/pages/selble/selble.wxss b/src/wechat_app/pages/selble/selble.wxss new file mode 100644 index 0000000..94a9fd8 --- /dev/null +++ b/src/wechat_app/pages/selble/selble.wxss @@ -0,0 +1,43 @@ +/* pages/selble/selble.wxss */ +.item_class{ + width: 94vw; + padding: 3vw 3vw 0vw 3vw; + background: #fff; +} +.ble_img{ + width: 7vw; + height: 7vw; +} +.item_name_text{ + margin-left: 5px; + font-size:90%; + font-family:PingFangSC-Medium; + font-weight:500; + color:rgba(51,51,51,1); +} +.item_sel_img{ + width: 5vw; + height: 5vw; +} +.line{ + margin-top:3vw; + width: 100%; + height: 1px; + background: #E4E4E4; + +} +.bottom_fix_show{ + width:90vw; + padding: 4vw 5vw; + position: fixed; + bottom: 0; + background: #fff; +} +.bottom_text{ + display: flex; + font-size:90%; + font-family:PingFangSC-Medium; + font-weight:500; + color:rgba(12,135,255,1); +} + diff --git a/src/wechat_app/project.config.json b/src/wechat_app/project.config.json new file mode 100644 index 0000000..4ef61f8 --- /dev/null +++ b/src/wechat_app/project.config.json @@ -0,0 +1,52 @@ +{ + "description": "项目配置文件", + "packOptions": { + "ignore": [], + "include": [] + }, + "setting": { + "bundle": false, + "userConfirmedBundleSwitch": false, + "urlCheck": true, + "scopeDataCheck": false, + "coverView": true, + "es6": true, + "postcss": true, + "compileHotReLoad": false, + "lazyloadPlaceholderEnable": false, + "preloadBackgroundData": false, + "minified": true, + "autoAudits": false, + "newFeature": false, + "uglifyFileName": false, + "uploadWithSourceMap": true, + "useIsolateContext": true, + "nodeModules": false, + "enhance": true, + "useMultiFrameRuntime": true, + "useApiHook": true, + "useApiHostProcess": true, + "showShadowRootInWxmlPanel": true, + "packNpmManually": false, + "enableEngineNative": false, + "packNpmRelationList": [], + "minifyWXSS": true, + "showES6CompileOption": false, + "minifyWXML": true, + "babelSetting": { + "ignore": [], + "disablePlugins": [], + "outputPath": "" + } + }, + "compileType": "miniprogram", + "libVersion": "2.19.4", + "appid": "wx08af813924f7522e", + "projectname": "miniprogram-92", + "condition": {}, + "editorSetting": { + "tabIndent": "insertSpaces", + "tabSize": 2 + }, + "simulatorPluginLibVersion": {} +} \ No newline at end of file diff --git a/src/wechat_app/project.private.config.json b/src/wechat_app/project.private.config.json new file mode 100644 index 0000000..2f44481 --- /dev/null +++ b/src/wechat_app/project.private.config.json @@ -0,0 +1,7 @@ +{ + "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", + "projectname": "imuviz", + "setting": { + "compileHotReLoad": true + } +} \ No newline at end of file diff --git a/src/wechat_app/sitemap.json b/src/wechat_app/sitemap.json new file mode 100644 index 0000000..ca02add --- /dev/null +++ b/src/wechat_app/sitemap.json @@ -0,0 +1,7 @@ +{ + "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", + "rules": [{ + "action": "allow", + "page": "*" + }] +} \ No newline at end of file diff --git a/src/wechat_app/utils/bletool.js b/src/wechat_app/utils/bletool.js new file mode 100644 index 0000000..ded6652 --- /dev/null +++ b/src/wechat_app/utils/bletool.js @@ -0,0 +1,560 @@ +/** + * 蓝牙集成 插件 + * 2020-06-10 灵 + * 梦辛工作室 + * v1.0.3 + */ + +var Until = { + getBleService() { + wx.getBLEDeviceServices({ + deviceId: data.connectedDeviceId, + success: function (res) { + for (var i = 0; i < res.services.length; i++) { + console.log("service:" + res.services[i].uuid); + getChar(res.services[i]); + } + } + }) + }, +} + +var data = { + uuid: "FFF0", //FFE0 + status: 0, //可用状态 1 - 可用 0 - 不可用 + sousuo: 0, //搜索状态 1 - 搜索中 0 - 为搜索 + connectedDeviceId: "", //已连接设备uuid + serviceslist: [], + services: "", // 连接设备的服务 + characteristics: "", // 连接设备的状态值 + writeServicweId: "", // 可写服务uuid + writeCharacteristicsId: "", //可写特征值uuid + readServicweId: "", // 可读服务uuid + readCharacteristicsId: "", //可读特征值uuid + notifyServicweId: "", //通知服务UUid + notifyCharacteristicsId: "", //通知特征值UUID + inputValue: "", + characteristics1: "", // 连接设备的状态值 + isOpenadatper: false, //是否初始化蓝牙适配器 + connectStatus: false, //连接状态 + onNotifyChange:{}, + + mTimeOut: {} //扫描Timeout对象 +} + +function ab2hex(buffer) { + var hexArr = Array.prototype.map.call( + new Uint8Array(buffer), + function (bit) { + return ('00' + bit.toString(16)).slice(-2) + } + ) + return hexArr.join(' '); +} + +function hex2str(str) { + var len = str.length / 2; + var result = ""; + for (var i = 0; i < len; i++) { + let data = str.substring(i * 2, i * 2 + 2); + result += String.fromCharCode(parseInt(data, 16)); + } + return result; +} + +function strToHexCharCode(str) { + if (str === "") + return ""; + var hexCharCode = []; + hexCharCode.push("0x"); + for (var i = 0; i < str.length; i++) { + hexCharCode.push((str.charCodeAt(i)).toString(16)); + } + return hexCharCode.join(""); +} + +function readNotify(re) { + if (!data.readServicweId && !data.readCharacteristicsId) { + re({ + code: 1, + desc: "未选择读服务UUID和可读特征值UUID" + }); + return; + } + // 必须在这里的回调才能获取 + wx.onBLECharacteristicValueChange(function (res) { + console.log('characteristic value comed:', res); + let msg = ab2hex(res.value); + let str = hex2str(msg); + res.value.strHexData = msg; + res.value.strData = str; + re(res); //接受消息 + }) + wx.readBLECharacteristicValue({ + deviceId: data.connectedDeviceId, + serviceId: data.readServicweId, + characteristicId: data.readCharacteristicsId, + success(res) { + console.log('readBLECharacteristicValue:', res.errCode) + } + }) +} + +function opennotify(re) { + if (!data.notifyServicweId && !data.notifyCharacteristicsId) { + re({ + code: 1, + desc: "未选择服务UUID和特征值UUID" + }); + return; + } + //开启通知 + wx.notifyBLECharacteristicValueChange({ + state: true, + deviceId: data.connectedDeviceId, + serviceId: data.notifyServicweId, + characteristicId: data.notifyCharacteristicsId, + success: function (res) { + console.log('notifyBLECharacteristicValueChange success', res.errMsg) + + wx.onBLECharacteristicValueChange(function (res) { + let msg = ab2hex(res.value); + let str = hex2str(msg); + res.value.strHexData = msg; + res.value.strData = str; + console.log(res); + re(res); //接受消息 + }) + } + }) +} + +function getChar(services) { + services.characteristics = []; + //获取特征值 + wx.getBLEDeviceCharacteristics({ + deviceId: data.connectedDeviceId, + serviceId: services.uuid, + success: function (res) { + let notify_id, write_id, read_id; + + for (let i = 0; i < res.characteristics.length; i++) { + + let charc = res.characteristics[i]; + + if (charc.properties.notify && charc.uuid.indexOf(data.notifyCharacteristicsId) >= 0) { + notify_id = charc.uuid; + console.log("notify_id:" + notify_id); + } + + if (charc.properties.write && charc.uuid.indexOf(data.writeCharacteristicsId) >= 0) { + write_id = charc.uuid; + console.log("write_id:" + write_id); + } + + if (charc.properties.read && charc.uuid.indexOf(data.readCharacteristicsId) >= 0) { + read_id = charc.uuid; + console.log("read_id:" + read_id); + } + + console.log("charc_uuid:" + charc.uuid); + services.characteristics.push(charc); + + } + + data.serviceslist.push(services); + + // if (notify_id != null ) { + // data.notifyServicweId = services.uuid; + // data.notifyCharacteristicsId = notify_id; + // } + // if(write_id != null){ + // data.writeServicweId = services.uuid; + // data.writeCharacteristicsId = write_id; + // } + // if(read_id != null){ + // data.readServicweId = services.uuid; + // data.readCharacteristicsId = read_id; + // } + } + }) +} + +//蓝牙使用类 +class bletool { + /** + * 构造函数 + * + * @param {Object} options 接口参数,key 为必选参数 + */ + constructor() {} + /** + * 设置uuid + */ + setUUID(uuid) { + data.uuid = uuid; + } + + setWriteUUID(serviceuuid, uuid) { + data.writeServicweId = serviceuuid; + data.writeCharacteristicsId = uuid; + } + + isCanWrite(){ + return (data.writeServicweId || false) && (data.writeCharacteristicsId || false); + } + + setReadUUID(serviceuuid, uuid,callback) { + data.readServicweId = serviceuuid; + data.readCharacteristicsId = uuid; + if(callback){ + data.onNotifyChange = callback; + } + readNotify(data.onNotifyChange); + } + + isCanRead(){ + return (data.readServicweId || false) && (data.readCharacteristicsId|| false); + } + + setNotiftyUUID(serviceuuid, uuid,callback) { + data.notifyServicweId = serviceuuid; + data.notifyCharacteristicsId = uuid; + if(callback){ + data.onNotifyChange = callback; + } + opennotify(data.onNotifyChange); + } + + isCanNotifty(){ + return (data.notifyServicweId || false) && (data.notifyCharacteristicsId|| false); + } + + doRead(){ + wx.readBLECharacteristicValue({ + deviceId: data.connectedDeviceId, + serviceId: data.readServicweId, + characteristicId: data.readCharacteristicsId, + success(res) { + console.log('readBLECharacteristicValue:', res.errCode) + } + }) + } + + getServiceList() { + return data.serviceslist; + } + /** + * 获得蓝牙适配器状态 + */ + getAdapterStatus() { + return data.isOpenadatper; + } + /** + * 获得蓝牙连接状态 + */ + getdevConStatus() { + return data.connectStatus; + } + /** + * 初始化蓝牙 + * @parameter chcb 蓝牙状态改变回调 + * @parameter concb 蓝牙连接状态改变回调 + * @parameter recb 初始化成功与否回调 + */ + initble(recb, chcb, concb) { + //打开适配器 判断是否支持蓝牙 + var info = { + return_code: "1", + msg: "" + } + if (wx.openBluetoothAdapter) { + wx.openBluetoothAdapter({ + success: function (res) { + /** + * 监听蓝牙适配器状态 + */ + data.isOpenadatper = true; + info.return_code = "0"; + info.msg = "初始化成功!"; + recb(info); + console.log(res); + wx.onBluetoothAdapterStateChange( + function (res) { + if (typeof chcb == "function") { + chcb(res); + } + data.sousuo = res.discovering ? 1 : 0, + data.status = res.available ? 1 : 0 + } + ); + /** + * 获取本机蓝牙适配器状态 + */ + wx.getBluetoothAdapterState({ + success: function (res) { + data.sousuo = res.discovering ? 1 : 0, + data.status = res.available ? 1 : 0 + } + }); + /** + * 监听蓝牙状态状态 + */ + wx.onBLEConnectionStateChange( + function (res) { + concb(res); + data.connectedDeviceId = res.deviceId; + data.connectStatus = res.connected; + }) + return true; + }, + fail: function (res) { + info.return_code = "1"; + info.msg = "初始化失败!"; + recb(info); + data.isOpenadatper = false; + + } + }); + } else { + info.return_code = "1"; + info.msg = "初始化失败!"; + recb(info); + data.isOpenadatper = false; + } + } + + /** + * 开始扫描 + *@parameter getDevCb - 发现设备回调 endTime 扫描结束时间 + *@return info{return_code:"0",msg:"",rep:{}} + *return_code 返回操作结果 msg - 返回操作信息 rep - 扫描到的蓝牙设备信息 infoFB- 返回操作信息 isduplica - 是否搜索重复设备 + */ + startScanle(getDevCb, infoFB, endTime, isduplica) { + var info = { + return_code: "1", + msg: "", + rep: {} + } + if (data.sousuo == 1) { + info.return_code = "1"; + info.msg = "正在搜索中..."; + infoFB(info); + } else { + wx.startBluetoothDevicesDiscovery({ + allowDuplicatesKey: isduplica, + success: function (res) { + data.sousuo = 1; + info.return_code = "0"; + info.msg = "搜索成功"; + infoFB(info); + wx.onBluetoothDeviceFound( + function (res) { + if (typeof getDevCb == "function") { + res.devices[0].advertisData = ab2hex(res.devices[0].advertisData); + getDevCb(res); + } + }) + }, + fail:function(res){ + data.sousuo = 0; + info.return_code = "0"; + info.msg = "搜索失败"; + info.res = res; + infoFB(info); + } + }) + data.mTimeOut = setTimeout(function (res) { + + wx.stopBluetoothDevicesDiscovery({ + success: function (res) { + data.sousuo = 0; + info.return_code = "0"; + info.msg = "扫描结束"; + infoFB(info); + }, + fail: function (res) { + + } + }) + }, endTime); + } + } + /** + * 停止扫描 + * @return true - 成功 false - 失败 + */ + stopScanle() { + if (data.sousuo == 1) { + clearTimeout(data.mTimeOut); + } + wx.stopBluetoothDevicesDiscovery({ + success: function (res) { + data.sousuo = 0; + }, + fail: function (res) {} + }) + } + /** + * 连接设备,连接超时时间3秒 + * @parameter id - 设备id readCb - 设备接收数据回调 suceeF - 连接成功与否回调 + * @return true - 成功 false - 失败 + */ + connect(id, suceeF, readCb) { + var info = { + return_code: "1", + msg: "" + } + if (data.connectStatus) { + info.return_code = "1"; + info.msg = "当前已连接!"; + suceeF(info); + } else { + wx.showLoading({ + title: '连接蓝牙设备中...', + }) + wx.createBLEConnection({ + deviceId: id, + timeout: 10000, + success: function (res) { + wx.hideLoading(); + data.connectStatus = true; + data.connectedDeviceId = id; + wx.showToast({ + title: '连接成功', + icon: 'success', + duration: 1000 + }) + info.return_code = "0"; + info.msg = "连接设备成功"; + //获取服务 + if (typeof readCb == "function") { + data.onNotifyChange = readCb; + Until.getBleService(readCb); + } + suceeF(info); + }, + fail: function (res) { + wx.hideLoading() + wx.showToast({ + title: '连接设备失败', + icon: 'none', + duration: 1000 + }) + info.return_code = "1"; + info.msg = "连接设备失败"; + console.log(res) + data.connectStatus = false; + suceeF(info); + } + }) + wx.stopBluetoothDevicesDiscovery({ + success: function (res) { + data.sousuo = 0; + console.log("停止蓝牙搜索") + console.log(res) + } + }) + } + return info; + } + /** + *像蓝牙设备蓝牙发送数据 + * msg - 发送的消息 sendab - 发送结果回调 ishex - 是否是hex字符串 + */ + sendMsg(msg, sendab, ishex) { + var info = { + errCode: "1", + msg: "发送失败!" + } + if (msg == "") { + sendab(info); + } + var hexs = ""; + if (ishex) { + hexs = msg; + } else { + hexs = strToHexCharCode(msg); + } + var typedArray = new Uint8Array(hexs.match(/[\da-f]{2}/gi).map(function (h) { + return parseInt(h, 16); + })); + var buffer = typedArray.buffer; + + if (!data.writeServicweId && !data.writeCharacteristicsId) { + sendab({ + errCode: 1, + msg: "未选择可写服务UUID和可写特征值UUID" + }); + return; + } + wx.writeBLECharacteristicValue({ + deviceId: data.connectedDeviceId, + serviceId: data.writeServicweId, + characteristicId: data.writeCharacteristicsId, + value: buffer, + success: function (res) { + info.errCode = "0"; + info.msg = "发送成功"; + console.log(res); + if (typeof sendab == "function") { + sendab(info); + } + }, + fail: function (res) { + console.log(res); + info.errCode = "1"; + info.msg = "发送失败"; + if (typeof sendab == "function") { + sendab(info); + } + } + }) + return info; + } + /** + * 断开连接 + *@return info{return_code:"0",msg:""} return_code 返回操作结果 msg - 返回操作信息 + */ + disconnect(infoFb) { + var info = { + return_code: "1", + msg: "" + } + if (data.connectStatus) { + wx.closeBLEConnection({ + deviceId: data.connectedDeviceId, + success: function (res) { + data.connectStatus = false; + info.return_code = "0"; + info.msg = "断开成功"; + infoFb(info); + }, + }) + } else { + info.return_code = "1"; + info.msg = "未连接任何设备"; + infoFb(info); + } + } + /** + * 关闭适配器 + */ + close(infoFB) { + var info = { + return_code: "1", + msg: "关闭失败" + } + wx.closeBluetoothAdapter({ + success: function (res) { + info.return_code = "0"; + info.msg = "关闭成功!"; + infoFB(info); + }, + fail: function (res) { + infoFB(info); + } + }) + } +} +module.exports = bletool; \ No newline at end of file diff --git a/src/wechat_app/utils/runtime.js b/src/wechat_app/utils/runtime.js new file mode 100644 index 0000000..67da0bd --- /dev/null +++ b/src/wechat_app/utils/runtime.js @@ -0,0 +1 @@ +!(function(global){"use strict";var Op=Object.prototype;var hasOwn=Op.hasOwnProperty;var undefined;var $Symbol=typeof Symbol==="function"?Symbol:{};var iteratorSymbol=$Symbol.iterator||"@@iterator";var asyncIteratorSymbol=$Symbol.asyncIterator||"@@asyncIterator";var toStringTagSymbol=$Symbol.toStringTag||"@@toStringTag";var inModule=typeof module==="object";var runtime=global.regeneratorRuntime;if(runtime){if(inModule){module.exports=runtime}return}runtime=global.regeneratorRuntime=inModule?module.exports:{};function wrap(innerFn,outerFn,self,tryLocsList){var protoGenerator=outerFn&&outerFn.prototype instanceof Generator?outerFn:Generator;var generator=Object.create(protoGenerator.prototype);var context=new Context(tryLocsList||[]);generator._invoke=makeInvokeMethod(innerFn,self,context);return generator}runtime.wrap=wrap;function tryCatch(fn,obj,arg){try{return{type:"normal",arg:fn.call(obj,arg)}}catch(err){return{type:"throw",arg:err}}}var GenStateSuspendedStart="suspendedStart";var GenStateSuspendedYield="suspendedYield";var GenStateExecuting="executing";var GenStateCompleted="completed";var ContinueSentinel={};function Generator(){}function GeneratorFunction(){}function GeneratorFunctionPrototype(){}var IteratorPrototype={};IteratorPrototype[iteratorSymbol]=function(){return this};var getProto=Object.getPrototypeOf;var NativeIteratorPrototype=getProto&&getProto(getProto(values([])));if(NativeIteratorPrototype&&NativeIteratorPrototype!==Op&&hasOwn.call(NativeIteratorPrototype,iteratorSymbol)){IteratorPrototype=NativeIteratorPrototype}var Gp=GeneratorFunctionPrototype.prototype=Generator.prototype=Object.create(IteratorPrototype);GeneratorFunction.prototype=Gp.constructor=GeneratorFunctionPrototype;GeneratorFunctionPrototype.constructor=GeneratorFunction;GeneratorFunctionPrototype[toStringTagSymbol]=GeneratorFunction.displayName="GeneratorFunction";function defineIteratorMethods(prototype){["next","throw","return"].forEach(function(method){prototype[method]=function(arg){return this._invoke(method,arg)}})}runtime.isGeneratorFunction=function(genFun){var ctor=typeof genFun==="function"&&genFun.constructor;return ctor?ctor===GeneratorFunction||(ctor.displayName||ctor.name)==="GeneratorFunction":false};runtime.mark=function(genFun){if(Object.setPrototypeOf){Object.setPrototypeOf(genFun,GeneratorFunctionPrototype)}else{genFun.__proto__=GeneratorFunctionPrototype;if(!(toStringTagSymbol in genFun)){genFun[toStringTagSymbol]="GeneratorFunction"}}genFun.prototype=Object.create(Gp);return genFun};runtime.awrap=function(arg){return{__await:arg}};function AsyncIterator(generator){function invoke(method,arg,resolve,reject){var record=tryCatch(generator[method],generator,arg);if(record.type==="throw"){reject(record.arg)}else{var result=record.arg;var value=result.value;if(value&&typeof value==="object"&&hasOwn.call(value,"__await")){return Promise.resolve(value.__await).then(function(value){invoke("next",value,resolve,reject)},function(err){invoke("throw",err,resolve,reject)})}return Promise.resolve(value).then(function(unwrapped){result.value=unwrapped;resolve(result)},reject)}}var previousPromise;function enqueue(method,arg){function callInvokeWithMethodAndArg(){return new Promise(function(resolve,reject){invoke(method,arg,resolve,reject)})}return previousPromise=previousPromise?previousPromise.then(callInvokeWithMethodAndArg,callInvokeWithMethodAndArg):callInvokeWithMethodAndArg()}this._invoke=enqueue}defineIteratorMethods(AsyncIterator.prototype);AsyncIterator.prototype[asyncIteratorSymbol]=function(){return this};runtime.AsyncIterator=AsyncIterator;runtime.async=function(innerFn,outerFn,self,tryLocsList){var iter=new AsyncIterator(wrap(innerFn,outerFn,self,tryLocsList));return runtime.isGeneratorFunction(outerFn)?iter:iter.next().then(function(result){return result.done?result.value:iter.next()})};function makeInvokeMethod(innerFn,self,context){var state=GenStateSuspendedStart;return function invoke(method,arg){if(state===GenStateExecuting){throw new Error("Generator is already running");}if(state===GenStateCompleted){if(method==="throw"){throw arg;}return doneResult()}context.method=method;context.arg=arg;while(true){var delegate=context.delegate;if(delegate){var delegateResult=maybeInvokeDelegate(delegate,context);if(delegateResult){if(delegateResult===ContinueSentinel)continue;return delegateResult}}if(context.method==="next"){context.sent=context._sent=context.arg}else if(context.method==="throw"){if(state===GenStateSuspendedStart){state=GenStateCompleted;throw context.arg;}context.dispatchException(context.arg)}else if(context.method==="return"){context.abrupt("return",context.arg)}state=GenStateExecuting;var record=tryCatch(innerFn,self,context);if(record.type==="normal"){state=context.done?GenStateCompleted:GenStateSuspendedYield;if(record.arg===ContinueSentinel){continue}return{value:record.arg,done:context.done}}else if(record.type==="throw"){state=GenStateCompleted;context.method="throw";context.arg=record.arg}}}}function maybeInvokeDelegate(delegate,context){var method=delegate.iterator[context.method];if(method===undefined){context.delegate=null;if(context.method==="throw"){if(delegate.iterator.return){context.method="return";context.arg=undefined;maybeInvokeDelegate(delegate,context);if(context.method==="throw"){return ContinueSentinel}}context.method="throw";context.arg=new TypeError("The iterator does not provide a 'throw' method")}return ContinueSentinel}var record=tryCatch(method,delegate.iterator,context.arg);if(record.type==="throw"){context.method="throw";context.arg=record.arg;context.delegate=null;return ContinueSentinel}var info=record.arg;if(!info){context.method="throw";context.arg=new TypeError("iterator result is not an object");context.delegate=null;return ContinueSentinel}if(info.done){context[delegate.resultName]=info.value;context.next=delegate.nextLoc;if(context.method!=="return"){context.method="next";context.arg=undefined}}else{return info}context.delegate=null;return ContinueSentinel}defineIteratorMethods(Gp);Gp[toStringTagSymbol]="Generator";Gp[iteratorSymbol]=function(){return this};Gp.toString=function(){return"[object Generator]"};function pushTryEntry(locs){var entry={tryLoc:locs[0]};if(1 in locs){entry.catchLoc=locs[1]}if(2 in locs){entry.finallyLoc=locs[2];entry.afterLoc=locs[3]}this.tryEntries.push(entry)}function resetTryEntry(entry){var record=entry.completion||{};record.type="normal";delete record.arg;entry.completion=record}function Context(tryLocsList){this.tryEntries=[{tryLoc:"root"}];tryLocsList.forEach(pushTryEntry,this);this.reset(true)}runtime.keys=function(object){var keys=[];for(var key in object){keys.push(key)}keys.reverse();return function next(){while(keys.length){var key=keys.pop();if(key in object){next.value=key;next.done=false;return next}}next.done=true;return next}};function values(iterable){if(iterable){var iteratorMethod=iterable[iteratorSymbol];if(iteratorMethod){return iteratorMethod.call(iterable)}if(typeof iterable.next==="function"){return iterable}if(!isNaN(iterable.length)){var i=-1,next=function next(){while(++i=0;--i){var entry=this.tryEntries[i];var record=entry.completion;if(entry.tryLoc==="root"){return handle("end")}if(entry.tryLoc<=this.prev){var hasCatch=hasOwn.call(entry,"catchLoc");var hasFinally=hasOwn.call(entry,"finallyLoc");if(hasCatch&&hasFinally){if(this.prev=0;--i){var entry=this.tryEntries[i];if(entry.tryLoc<=this.prev&&hasOwn.call(entry,"finallyLoc")&&this.prev=0;--i){var entry=this.tryEntries[i];if(entry.finallyLoc===finallyLoc){this.complete(entry.completion,entry.afterLoc);resetTryEntry(entry);return ContinueSentinel}}},"catch":function(tryLoc){for(var i=this.tryEntries.length-1;i>=0;--i){var entry=this.tryEntries[i];if(entry.tryLoc===tryLoc){var record=entry.completion;if(record.type==="throw"){var thrown=record.arg;resetTryEntry(entry)}return thrown;}}throw new Error("illegal catch attempt");},delegateYield:function(iterable,resultName,nextLoc){this.delegate={iterator:values(iterable),resultName:resultName,nextLoc:nextLoc};if(this.method==="next"){this.arg=undefined}return ContinueSentinel}}})((function(){return this})()||Function("return this")()); \ No newline at end of file diff --git a/src/wechat_app/utils/util.js b/src/wechat_app/utils/util.js new file mode 100644 index 0000000..764bc2c --- /dev/null +++ b/src/wechat_app/utils/util.js @@ -0,0 +1,19 @@ +const formatTime = date => { + const year = date.getFullYear() + const month = date.getMonth() + 1 + const day = date.getDate() + const hour = date.getHours() + const minute = date.getMinutes() + const second = date.getSeconds() + + return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}` +} + +const formatNumber = n => { + n = n.toString() + return n[1] ? n : `0${n}` +} + +module.exports = { + formatTime +} From 4919d5fd29d3b16ae74960a619547c7df1800bea Mon Sep 17 00:00:00 2001 From: Jian Sun Date: Sun, 4 Dec 2022 23:22:58 +0800 Subject: [PATCH 2/3] :lipstick: Update style file --- src/wechat_app/app.wxss | 214 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 212 insertions(+), 2 deletions(-) diff --git a/src/wechat_app/app.wxss b/src/wechat_app/app.wxss index 06c6fc9..164a110 100644 --- a/src/wechat_app/app.wxss +++ b/src/wechat_app/app.wxss @@ -1,4 +1,7 @@ /**app.wxss**/ +page{ + background: #EFF2F6; +} .container { height: 100%; display: flex; @@ -6,5 +9,212 @@ align-items: center; justify-content: space-between; padding: 200rpx 0; - box-sizing: border-box; -} + box-sizing: border-box; +} +.match_screen{ + width: 100vw; + height: 100vh +} +.flex_row, .flex_column { + display: flex; +} + +.flex_row { + flex-direction: row; +} + +.flex_column { + flex-direction: column; +} + +.flex_vcenter, .flex_center { + align-items: center; +} + +.flex_hcenter, .flex_center { + justify-content: center; +} + + + +.flex_wrap { + flex-wrap: wrap; +} + +.flex_space { + justify-content: space-between; +} + +.flex_grow_1 { + flex-grow: 1; +} + +.flex_end { + justify-content: flex-end; +} + +.flex_start { + justify-content: flex-start; +} + +.border_bottom_class { + border-bottom: 1px solid rgba(204, 204, 204, 1); +} + +.border_bottom_class_foucs { + border-bottom: 1px solid rgba(46, 152, 233, 1); +} + +.table_boot_two { + width: 16.6666667%; +} + +.table_boot_three { + width: 25%; +} + +.table_boot_four { + width: 33.33%; +} + +.table_boot_nine { + width: 75%; +} + +.table_boot_six { + width: 50%; +} + +.table_boot_ten { + width: 83.3333333%; +} + +.table_boot_eight { + width: 66.666667%; +} + +.table_boot_seven { + width: 58.3333333%; +} + +.table_boot_height_six { + height: 50%; +} + +.table_boot_height_one { + height: 8.333333%; +} + +.table_boot_height_two { + height: 16.6666667%; +} + +.table_boot_height_three { + height: 25%; +} + +.table_boot_height_four { + height: 33.33333333%; +} + +.table_boot_height_five { + height: 41.6666667%; +} + +.table_boot_height_seven { + height: 58.3333333%; +} + +.table_boot_height_eight { + height: 66.666667%; +} + +.table_boot_height_nine { + height: 75%; +} + +.table_boot_height_ten { + height: 83.3333333%; +} + +.table_boot_height_ele { + height: 91.66667%; +} + +.table_boot_height_twle { + height: 100%; +} + +.white_back{ + background: #fff; +} + +.pos_fixed { + position: fixed; + z-index: -1; +} + +.text_center { + text-align: center; +} + + +.btn_yellow_class,.btn_yellow_class:active,.btn_yellow_class_dissable{ + width:90%; + margin-left: 5%; + border-radius:4px; + color: #fff; + font-size:100%; + font-family:PingFangSC-Heavy; + font-weight:800; +} + +.btn_yellow_class{ + background:rgba(0,120,253,1); +} + +.btn_yellow_class:active{ + background:rgb(5, 100, 207); +} + +.btn_yellow_class_dissable{ + background:rgba(204,204,204,1); +} + +.no_data_back{ + width: 100vw; + height: 60vh +} + +.no_data_img{ + width: 20vw; + height: 20vw; +} + +.no_data_hint{ + font-size: 80%; + color:#B0B0B0; +} + +.btn_disable{ + position: fixed; + right: 3vw; + color: white; + font-size: 80%; + background:linear-gradient(180deg,rgba(189,189,189,1) 0%,rgba(102,102,102,1) 100%,rgba(204,204,204,1) 100%); + border-radius:10px; +} + +.btn_normal,.btn_normal:active{ + font-size: 80%; + color: white; + border-radius:10px; +} + +.btn_normal{ + background:linear-gradient(180deg,rgba(255,255,255,1) 0%,rgba(255,112,191,1) 0%,rgba(69,178,255,1) 0%,rgba(0,126,255,1) 100%); +} + +.btn_normal:active{ + background:rgba(0,126,255,1); +} From fedf75291b9fd453c5c3deb6580264339eaa8507 Mon Sep 17 00:00:00 2001 From: Jian Sun Date: Sun, 4 Dec 2022 23:40:18 +0800 Subject: [PATCH 3/3] Enable lazy code loading --- src/wechat_app/app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wechat_app/app.json b/src/wechat_app/app.json index ed43b57..a3238bb 100644 --- a/src/wechat_app/app.json +++ b/src/wechat_app/app.json @@ -11,5 +11,6 @@ "navigationBarTextStyle":"black" }, "style": "v2", + "lazyCodeLoading": "requiredComponents", "sitemapLocation": "sitemap.json" }