123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- <template>
- <view class="kk-printer">
- <view class="kk-printer-btn">
- <u-button v-if="printBtnStyle=='blue-large'" @tap="handlePrintTap(1)" :loading="isPrinting||isConnecting" shape="circle" :custom-style="{background:$config('primaryColor')}" type="primary">{{isPrinting?printingText:defaultText}}</u-button>
- <u-button v-if="printBtnStyle=='default-mid'" shape="circle" size="medium" hover-class="none" @tap="handlePrintTap(1)" :loading="isPrinting||isConnecting">{{isPrinting?printingText:defaultText}}</u-button>
- </view>
- <view class="kk-shadow" :class="isShowSearch?'show':''" @tap="handleSearchClose">
- <view class="kk-modal" @tap.stop="doNothing">
- <view class="kk-search-device">
- <!-- <view class="kk-filter-wrap">
- <view class="filter-title">根据SRRI过滤设备</view>
- <slider @change="handleSRRIChange" max='-20' min='-100' value="-95" show-value/>
- </view> -->
- <!-- <view class="kk-filter-wrap">
- <view class="filter-title">根据蓝牙名过滤</view>
- <input type="text" placeholder-class="kk-placeholder-class" placeholder="请输入蓝牙名字或设备ID搜索" v-model="filterName" />
- </view> -->
- <view style="text-align: left;">
- <u-parse :html="content"></u-parse>
- </view>
- <view class="kk-btn-wrap">
- <view class="kk-btn-item confirm-btn" @tap="searchBtnTap" v-if="!isSearching">
- 搜索设备
- </view>
- <view class="kk-btn-item confirm-btn" v-else>
- 搜索中...
- </view>
- <view class="kk-btn-item" @tap="stopSearchBtnTap">
- 停止搜索
- </view>
- </view>
- <view class="kk-devices-wrap">
- <view class="empty-wrap" v-if="filterDeviceList.length <= 0">
- <view class="empty-icon"></view>
- <view class="empty-text">~ 无可搜索到的设备 ~</view>
- </view>
- <view class="" v-else>
- <view class="kk-devices-item" v-for="(item,index) in filterDeviceList" :key="index" @tap="handleConnectDevice(item)">
- <view>
- <view class="name">
- <text>设备名称:</text>
- <text>{{item.name?item.name:'未命名'}}</text>
- </view>
- <view class="flex align_center justify_between">
- <view class="rssi">
- <text>信号强度:</text>
- <text>({{Math.max(0, item.RSSI + 100)}}%)</text>
- </view>
- <view style="width: 120rpx;text-align: right;">
- <!-- <u-icon :size="60" color="#55aaff" name="plus-circle"></u-icon> -->
- <u-button :loading="isConnecting" @tap="handleConnectDevice(item)" shape="circle" size="mini" :custom-style="{background:$config('primaryColor')}" type="primary">{{isConnecting?'连接中':'连接'}}</u-button>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view style="margin-top: 20upx;">
- <view v-if="!isConnecting" style="text-align: center;padding: 20upx;border:2upx solid #eee;border-radius: 15upx;" @tap="handleSearchClose">取消打印</view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import tsc from '@/components/kk-printer/printer/tsc.js'
- // import esc from '@/components/kk-printer/printer/esc.js'
- import * as cpcl from '@/components/kk-printer/printer/cpcl.js'
- import * as blesdk from './utils/bluetoolth';
- import util from './utils/util.js';
- export default {
- data(){
- return{
- content: `
- <div style="font-size:12px;">
- <p>注意事项:</p>
- <p>1、连接打印机之前,先打开手机蓝牙开关</p>
- <p>2、如果已有其它手机连接,请手动断开或重启打印机</p>
- <p>3、如果连接打印机没有任何反应或需要切换连接其它打印机,请在“我的”页面点击“重置打印机”后再试</p>
- <p>4、目前仅支持“得力(DL-886BW(NEW))”、“新北洋(BTP-P39)”蓝牙打印机</p>
- </div>
- `,
- //是否正在打印
- isPrinting:false,
- //是否正在搜索设备
- isSearching:false,
- // 是否正在连接
- isConnecting: false,
- //是否显示蓝牙列表
- isShowSearch:false,
- //按蓝牙名过滤
- filterName: ['DL-','BTP-'],
- //按信号过滤
- filterRSSI:-95,
- //设备列表
- devicesList:[],
- //连接的设备ID
- deviceId:'',
- deviceName: '',
- //根据设备ID获取的服务
- services:'',
- //获取特征值时返回的三要素
- serviceId: '',
- writeId: '',
- readId: ''
- }
- },
- props:{
- //按钮默认文字
- defaultText:{
- type:String,
- default:'快速打印'
- },
- //按钮打印中的文字
- printingText:{
- type:String,
- default:'打印中...'
- },
- // 按钮样式
- printBtnStyle:{
- type: String,
- default: 'blue-large'
- },
- roomcode:{
- type:String,
- require:true
- },
- CustName:{
- type:String,
- require:true
- },
- roomid:{
- type:String,
- require:true
- },
- autoConnect: {
- type: Boolean,
- default: true
- }
- },
- computed:{
- mapFilterRSSI(){
- return (0 - this.filterRSSI)
- },
- filterDeviceList(){
- let devices = this.devicesList;
- let name = this.filterName;
- let rssi = this.filterRSSI;
- //按RSSI过滤
- let filterDevices1 = devices.filter((item)=>{
- return item.RSSI > rssi
- })
- // 按名字过滤
- let filterDevices2
- if(name!=''){
- filterDevices2 = filterDevices1.filter((item)=>{
- return name.find(a => item.name.indexOf(a) >= 0 || item.deviceId.indexOf(a) >= 0)
- })
- }else{
- filterDevices2 = filterDevices1
- }
- // 根据广播数据提取MAC地址
- for (let i = 0; i < filterDevices2.length;i++) {
- if (filterDevices2[i].hasOwnProperty('advertisData')){
- if (filterDevices2[i].advertisData.byteLength == 8) {
- filterDevices2[i].advMac = util.buf2hex(filterDevices2[i].advertisData.slice(2, 7));
- }
- }
- }
- return filterDevices2
- }
- },
- mounted() {
- if(this.autoConnect){
- this.handlePrintTap(0)
- }
- },
- beforeDestroy(){
- this.stopSearchBtnTap();
- },
- methods:{
- doNothing(){
- return;
- },
- //点击打印按钮,flag : true 如果已连接直接执行打印命令,false,不执行
- handlePrintTap(flag){
- //打开蓝牙适配器
- blesdk.openBlue().then((res)=>{
- //获取已连接设备
- blesdk.getConnectedBluetoothDevices().then((res)=>{
- const lastDevice = uni.getStorageSync('vuex_lastBuleDevice')
- console.log(lastDevice)
- console.log(res,this.deviceId,this.serviceId,this.writeId,this.onPrintSuccess)
- // 如果之前连接过设备
- if(lastDevice){
- // 有正在连接的设备,且和上次连接设备一样
- if(res.devices.length && res.devices[0].deviceId == lastDevice.deviceId){
- this.deviceId = lastDevice.deviceId
- this.deviceName = lastDevice.name
- this.serviceId = lastDevice.serviceId
- this.writeId = lastDevice.writeId
- this.readId = lastDevice.readId
- console.log(this.deviceName.indexOf('DL-')>=0?tsc:cpcl)
- if(flag){
- this.isPrinting = true;
- this.$nextTick(()=>{
- this.$emit("startPrint",{
- deviceId: this.deviceId,
- serviceId: this.serviceId,
- writeId: this.writeId
- },
- this.deviceName.indexOf('DL-')>=0?tsc:cpcl,
- blesdk)
- })
- }
- }else{
- // 重新直接连接
- this.handleConnectDevice(lastDevice)
- }
- }else{
- if(this.autoConnect || flag){
- //若没有已连接设备,弹框搜索设备
- this.isShowSearch = true
- this.devicesList = []
- this.searchBtnTap()
- }
- }
- }).catch((err)=>{
- blesdk.catchToast(err);
- })
- }).catch((err)=>{
- console.log(err)
- blesdk.catchToast(err);
- })
- },
- onGetDevice(res){
- this.devicesList = res;
- },
- handleSearchClose(){
- if(!this.isConnecting){
- this.isShowSearch = false
- this.stopSearchBtnTap()
- }
- },
- handleSRRIChange(e){
- this.filterRSSI = e.detail.value
- },
- //开始搜索设备
- searchBtnTap(){
- blesdk.startBluetoothDevicesDiscovery();
- this.isSearching = true;
- blesdk.onfindBlueDevices(this.onGetDevice)
- },
- //停止搜索设备
- stopSearchBtnTap(){
- blesdk.stopBlueDevicesDiscovery();
- this.isSearching = false;
- },
- //点击连接设备
- handleConnectDevice(device){
- const _this = this
- let deviceId = device.deviceId;
- let name = device.name;
- this.deviceId = deviceId;
- this.deviceName = name;
- this.isConnecting = true
- this.stopSearchBtnTap()
- uni.onBLEConnectionStateChange(function(res){
- console.log('连接',res)
- if(res.connected){
- plus.nativeUI.toast('设备'+ res.deviceId + '已连接',{
- verticalAlign:'center'
- })
- }else{
- _this.closeConnect()
- plus.nativeUI.toast('设备'+ res.deviceId + '已断开连接',{
- verticalAlign:'center'
- })
- _this.isShowSearch = true
- _this.devicesList = []
- _this.searchBtnTap()
- }
- _this.isConnecting = false
- })
- blesdk.createBLEConnection(deviceId, this.onConnectSuccess, this.onConnectFail);
- },
- onConnectSuccess(res){
- this.stopSearchBtnTap()
- this.isConnecting = false
- blesdk.getBLEDeviceServices(this.deviceId, this.onGetServicesSuccess, this.onGetServicesFail);
- },
- onConnectFail(err){
- console.log('链接失败',err)
- this.isConnecting = false
- blesdk.catchToast(err.res)
- uni.setStorageSync('vuex_lastBuleDevice','')
- if(err.res.code == 10012){
- this.isShowSearch = true
- this.devicesList = []
- this.searchBtnTap()
- }
- },
- onGetServicesSuccess(res){
- console.log('获取服务',res)
- this.services = res.serviceId;
- blesdk.getDeviceCharacteristics(this.deviceId, this.services, this.onGetCharacterSuccess, this.onGetCharacterFail);
- },
- onGetServicesFail(err){
- console.log('获取服务失败')
- },
- onGetCharacterSuccess(res){
- console.log('获取特征值成功',res)
- this.serviceId = res.serviceId;
- this.writeId = res.writeId;
- this.readId = res.readId;
- this.isShowSearch = false;
- try {
- uni.setStorageSync('vuex_lastBuleDevice', {deviceId:this.deviceId,serviceId:this.serviceId,writeId:this.writeId,readId:this.readId,name:this.deviceName});
- } catch (e) {
- // error
- }
- },
- onGetCharacterFail(err){
- console.log('特征值获取失败')
- this.isPrinting = false;
- },
- onPrintSuccess(){
- this.isPrinting = false;
- console.log('打印成功')
- // this.$emit('onPrintSuccess')
- },
- onPrintFail(){
- console.log('打印失败')
- this.isPrinting = false;
- },
- closeConnect(){
- blesdk.closeBLEConnection(this.deviceId)
- this.isPrinting = false;
- uni.hideLoading();
- this.$emit('closeConnect')
- },
- }
- }
- </script>
- <style lang="scss" scoped>
- .kk-printer{
- &-btn{
- width:100%;
- height:100%;
- }
- .kk-shadow{
- display: none;
- &.show{
- display: block;
- width:100vw;
- height:100vh;
- background: rgba(0,0,0,0.4);
- position: fixed;
- top: 0;
- left: 0;
- display: flex;
- justify-content: center;
- align-items: center;
- z-index: 10000;
- .kk-modal{
- width:680upx;
- height: 80%;
- padding:24upx;
- box-sizing: border-box;
- overflow-y: auto;
- border-radius: 20upx;
- background: #ffffff;
- display: flex;
- justify-content: center;
- align-items: center;
- .kk-search-device{
- width:100%;
- height: 100%;
- .kk-filter-wrap{
- width:100%;
- height: 200upx;
- display: flex;
- flex-direction: column;
- justify-content: flex-start;
- align-items: flex-start;
- .filter-title{
- line-height: 70upx;
- font-size: 30upx;
- color: #999999;
- }
- &>slider{
- width:90%;
- height: 90upx;
- }
- &>input{
- padding:0 20upx;
- box-sizing: border-box;
- border-radius: 10upx;
- height: 90upx;
- width:100%;
- border: 1upx solid #ebebeb;
- }
- }
- .kk-btn-wrap{
- width:100%;
- height: 140upx;
- display: flex;
- justify-content: space-between;
- align-items: center;
- &>view{
- flex:1 1 auto;
- height: 80upx;
- line-height: 80upx;
- border-radius: 100upx;
- text-align: center;
- color:#ffffff;
- &.confirm-btn{
- background: #007AFF;
- margin-right:30upx;
- }
- &:nth-last-child(1){
- background: #DD524D;
- }
- }
- }
- .kk-devices-wrap{
- height: calc(100% - 460upx);
- overflow-y:auto;
- padding:10upx 20upx;
- box-sizing: border-box;
- border: 1upx solid #ebebeb;
- box-sizing: border-box;
- border-radius: 20upx;
- .empty-wrap{
- width:100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- .empty-icon{
- width:268upx;
- height: 240upx;
- background: url('./empty-icon.png') no-repeat;
- background-size:100% 100%;
- margin-bottom: 26upx;
- }
- .empty-text{
- width: 100%;
- line-height: 50upx;
- font-size: 30upx;
- text-align: center;
- color: #999999;
- }
- }
- .kk-devices-item{
- width:100%;
- border-bottom: 1upx solid #ebebeb;
- padding:20upx 0;
- box-sizing: border-box;
- &:nth-last-child(1){
- border-bottom: none;
- }
- button{
- width: auto;
- }
- }
- }
- }
- }
- }
-
- }
- }
- .kk-placeholder-class{
- font-size: 30upx;
- color:#999999;
- }
- </style>
|