1
0
forked from dyf/APP
Files
APP/pages/common/addDevice/addBle.vue

1766 lines
39 KiB
Vue
Raw Normal View History

<template>
<view class="content">
2026-04-01 08:46:32 +08:00
<uni-nav-bar :border="false" @clickLeft="prevPage" fixed="true" statusBar="true" background-color="#121212"
color="#FFFFFF" :title="Status.navbar.title">
<template v-slot:left>
<view>
<uni-icons type="left" size="24" color="#FFFFFF"></uni-icons>
</view>
</template>
<block slot="right">
<view class="navbarRight center">
<image @click.stop="handleRightClick(index,item)" v-for="item,index in Status.navbar.icons"
class="img" :src="item.src" mode="aspectFit"></image>
</view>
</block>
</uni-nav-bar>
<view class="topStatric">
<view class="lblTitle">
<view class="red">搜不到设备时,请尝试重启蓝牙,或重启App后重试</view>
</view>
<view class="lblTitle">
<view>添加:{{type.typeName}} 设备数量:{{devicesCnt}}</view>
2026-04-01 08:46:32 +08:00
<view class="btn" style="color: #FFFFFF;" @click="ReSearch()">刷新</view>
</view>
<view class="lblTitle">
<uni-easyinput :styles="{color:'#ffffff'}" :clearable="true" class="uni-mt-5" :trim="'both'"
prefixIcon="search" v-model="search" placeholder="名称筛选"></uni-easyinput>
</view>
<view class="th">
<text>
蓝牙设备列表
</text>
<text class="margintLeft10">
{{SearchEquips.length}}
</text>
</view>
2026-04-22 08:29:06 +08:00
<view class="tab">
<view class="center tabItem" @click="Status.tabIndex=0" :class="{'active':Status.tabIndex==0}">未入库(<text
class="mathIcon">{{UnJoin.length}}</text>)</view>
<view class="center tabItem" @click="Status.tabIndex=1" :class="{'active':Status.tabIndex==1}">已入库(<text
class="mathIcon">{{joined.length}}</text>)</view>
<view class="center tabItem" @click="Status.tabIndex=2" :class="{'active':Status.tabIndex==2}">已筛选(<text
class="mathIcon">{{SearchEquips.length}}</text>)</view>
<view class="center tabItem" @click="Status.tabIndex=3" :class="{'active':Status.tabIndex==3}">全部(<text
class="mathIcon">{{EquipMents.length}}</text>)</view>
2026-04-22 08:29:06 +08:00
</view>
</view>
<view class="mainContent">
<view class="p100">
<view class="list searchList">
2026-04-22 08:29:06 +08:00
<view class="item" v-on:click="Link(item,index)" v-for="item, index in list"
v-show="!item['linkStatu']">
<view class="leftImg ">
<image src="/static/images/common/bluetooth.png" class="titleIco" mode="heightFix">
</image>
</view>
<view class="centertxt ">
<view class="name">
<text class="fleft">蓝牙名:{{item.name?item.name:'Unnamed'}}</text>
<text class="fright" :class="item.link?'green':'red'">{{item.link?'已连接':'未连接'}}</text>
<view class="clear"></view>
</view>
<view class="name lbl" v-if="item.advertisData">广播数据:{{item.advertisData}}</view>
<view class="name lbl">Mac:
<text class="green" v-if="item.macAddress">{{item.macAddress}}</text>
<view class="red" v-if="!item.macAddress && item.link">
<view class="rotateAnimation">
<uni-icons type="spinner-cycle" color="#FFFFFF"></uni-icons>
</view>
</view>
</view>
<view class="name lbl">IMEI:
<text class="green" v-if="item.imei">{{item.imei}}</text>
<view class="red" v-if="!item.imei && item.link">
<view class="rotateAnimation">
<uni-icons type="spinner-cycle" color="#FFFFFF"></uni-icons>
</view>
</view>
</view>
<view class="name lbl">信号:{{item.RSSI}}dBm</view>
<view class="name lbl">
状态:
<text :class="item.isUpload?'green':'red'">{{item.remark}}</text>
</view>
<view class="name lbl">
设备名:
2026-04-01 08:46:32 +08:00
<text class="green">{{item.device_name}}</text>
</view>
</view>
<view class="rightIco " :class="item.isUpload?'bggreen':'bgred'">
</view>
</view>
</view>
</view>
</view>
<global-loading ref="loading" />
2026-04-01 08:46:32 +08:00
<MsgBox ref="msgPop" />
</view>
</template>
<script>
import bleTool from '@/utils/BleHelper.js';
import request from '@/utils/request.js';
import {
showLoading,
hideLoading,
updateLoading
} from '@/utils/loading.js'
2026-04-01 08:46:32 +08:00
import common from '@/utils/Common.js'
const pagePath = "pages/common/addBLE/addEquip";
2026-04-01 08:46:32 +08:00
import {
MsgSuccess,
MsgError,
MsgClose,
MsgWarning,
showPop,
2026-04-02 08:45:36 +08:00
MsgClear,
MsgInfo
2026-04-01 08:46:32 +08:00
} from '@/utils/MsgPops.js';
import MQTT from '@/utils/MqHelper.js';
var ble = null;
var these = null;
var eventChannel = null;
var time = null;
var time1 = null;
2026-04-01 08:46:32 +08:00
var mq = null;
var isValidTime = null;
export default {
data() {
return {
Status: {
intval: null,
2026-04-01 08:46:32 +08:00
pcAuthori: false,
navbar: {
icons: [
{
src: '/static/images/common/scane.png'
}
],
title: '添加设备',
showBack: true,
height: 90
2026-04-22 08:29:06 +08:00
},
tabIndex: 0
},
search: '',
groupid: '',
type: '',
deviceTypes: [], //设备类型
PairEquip: [], //已配对设备
EquipMents: [], //搜索出来的设备
devices: [],
devicesCnt: 0,
2026-04-01 08:46:32 +08:00
privateNetUrl: '',
scanKey: '',
typeKeys: [{
"type_name": "BJQ6170",
"ble": "BJQ6170"
},
{
"type_name": "HBY210",
"ble": "HBY210"
},
{
"type_name": "HBY670",
"ble": "HBY670"
},
{
"type_name": "BJQ6150",
"ble": "BJQ6150"
},
{
"type_name": "HBY650",
"ble": "HBY650"
},
{
"type_name": "BJQ7305",
"ble": "BJQ7305"
},
{
"type_name": "BJQ4877",
"ble": "BJQ4877"
},
{
"type_name": "HBY100",
"ble": "HBY100"
},
{
"type_name": "BJQ6070",
"ble": "BJQ6075"
},
{
"type_name": "HBY102",
"ble": "HBY102"
},
{
"type_name": "HBY018A",
"ble": "HBY018A"
},
{
"type_name": "BJQ6107",
"ble": "BJQ6107"
},
{
"type_name": "HBY100-J",
"ble": "HBY100J"
},
{
"type_name": "XH6155",
"ble": "BJQ6155"
},
{
"type_name": "BJQ6075J",
"ble": "BJQ6075"
},
{
"type_name": "HBY008A",
"ble": "HBY008A"
},
{
"type_name": "HBY100-Y",
"ble": "HBY100Y"
},
{
"type_name": "HBY102-J",
"ble": "HBY102J"
}
]
}
},
computed: {
cType(){
let f=this.typeKeys.find(v=>{
return v.type_name==this.type.typeName;
});
return f;
},
list() {
if (this.Status.tabIndex == 0) {
2026-04-22 08:29:06 +08:00
return this.UnJoin;
}
if (this.Status.tabIndex == 1) {
2026-04-22 08:29:06 +08:00
return this.joined;
}
if (this.Status.tabIndex == 2) {
return this.SearchEquips;
}
return this.EquipMents;
2026-04-22 08:29:06 +08:00
},
SearchEquips: function() {
let f = this.EquipMents.filter(v => {
return v.name.toLowerCase().indexOf(this.search.toLowerCase()) > -1
});
return f;
2026-04-22 08:29:06 +08:00
},
joined() {
let f = this.EquipMents.filter(v => {
2026-04-22 08:29:06 +08:00
return v.name.toLowerCase().indexOf(this.search.toLowerCase()) > -1 && v.isUpload;
});
return f;
2026-04-22 08:29:06 +08:00
},
UnJoin() {
let f = this.EquipMents.filter(v => {
2026-04-22 08:29:06 +08:00
return v.name.toLowerCase().indexOf(this.search.toLowerCase()) > -1 && !v.isUpload;
});
return f;
2026-04-22 08:29:06 +08:00
},
},
onHide: function() {
ble.StopSearch();
},
onUnload() {
2026-04-01 08:46:32 +08:00
if (ble) {
ble.StopSearch().then(res => {
console.log("停止搜索成功")
}).catch(ex => {
console.error("停止搜索成功", ex);
});
ble.removeAllCallback(pagePath);
ble.disconnectDevice();
}
if (mq) {
mq.disconnect();
}
},
onLoad() {
2026-04-01 08:46:32 +08:00
these = this;
2026-04-01 08:46:32 +08:00
mq = MQTT.getMqTool();
mq.init();
this.groupid = common.DateFormat(new Date(), 'yyyy-MM-dd HH:mm:ss');
ble = bleTool.getBleTool();
// serv = serTool.serverInit();
//已连接过但删除了设备
// #ifdef H5
this.EquipMents = [{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "F281938F-27FC-4739-4ACA-58B8D3BC44A6",
"name": "JQZM-HBY670-1C7493",
"linkStatu": false,
link: true
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "469FB381-B47E-1E40-8073-EF50B5704AAB",
"name": "JQZM-EF4651",
"linkStatu": false
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "F281938F-27FC-4739-4ACA-58B8D3BC44A6",
"name": "JQZM-HBY670-1C7493",
"linkStatu": false,
link: true
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "469FB381-B47E-1E40-8073-EF50B5704AAB",
"name": "JQZM-EF4651",
"linkStatu": false
}, {
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "F281938F-27FC-4739-4ACA-58B8D3BC44A6",
"name": "JQZM-HBY670-1C7493",
"linkStatu": false,
link: true
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "469FB381-B47E-1E40-8073-EF50B5704AAB",
"name": "JQZM-EF4651",
"linkStatu": false
}, {
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "F281938F-27FC-4739-4ACA-58B8D3BC44A6",
"name": "JQZM-HBY670-1C7493",
"linkStatu": false,
link: true
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "469FB381-B47E-1E40-8073-EF50B5704AAB",
"name": "JQZM-EF4651",
"linkStatu": false
}, {
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "F281938F-27FC-4739-4ACA-58B8D3BC44A6",
"name": "JQZM-HBY670-1C7493",
"linkStatu": false,
link: true
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "469FB381-B47E-1E40-8073-EF50B5704AAB",
"name": "JQZM-EF4651",
"linkStatu": false
}, {
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "F281938F-27FC-4739-4ACA-58B8D3BC44A6",
"name": "JQZM-HBY670-1C7493",
"linkStatu": false,
link: true
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "469FB381-B47E-1E40-8073-EF50B5704AAB",
"name": "JQZM-EF4651",
"linkStatu": false
}, {
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "F281938F-27FC-4739-4ACA-58B8D3BC44A6",
"name": "JQZM-HBY670-1C7493",
"linkStatu": false,
link: true
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "469FB381-B47E-1E40-8073-EF50B5704AAB",
"name": "JQZM-EF4651",
"linkStatu": false
}, {
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "F281938F-27FC-4739-4ACA-58B8D3BC44A6",
"name": "JQZM-HBY670-1C7493",
"linkStatu": false,
link: true
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "469FB381-B47E-1E40-8073-EF50B5704AAB",
"name": "JQZM-EF4651",
"linkStatu": false
}, {
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "F281938F-27FC-4739-4ACA-58B8D3BC44A6",
"name": "JQZM-HBY670-1C7493",
"linkStatu": false,
link: true
},
{
"RSSI": -62,
"advertisData": "",
"advertisServiceUUIDs": [
"0000FFE0-0000-1000-8000-00805F9B34FB"
],
"deviceId": "469FB381-B47E-1E40-8073-EF50B5704AAB",
"name": "JQZM-EF4651",
"linkStatu": false
}
]
// #endif
// #ifdef APP
this.EquipMents = [];
// these.EquipMents=[];
ble.addDeviceFound((arr) => {
arr = arr.devices;
let promis = [];
let newDevice = false;
for (var i = 0; i < arr.length; i++) {
arr[i].linkStatu = false;
if (!arr[i].name) {
continue;
}
2026-04-01 08:46:32 +08:00
2026-04-02 08:45:36 +08:00
arr[i].name = arr[i].name.replace(/\r\n/g, '').replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,'');
2026-04-01 08:46:32 +08:00
if(these.cType){
if(arr[i].name.indexOf(these.cType.ble)===-1){
continue;
}
}
2026-04-01 08:46:32 +08:00
let f = these.EquipMents.find(function(v, index) {
if (v.deviceId == arr[i].deviceId) {
these.$set(these.EquipMents[index], "RSSI", arr[i].RSSI);
return true;
}
return false;
});
if (!f) {
newDevice = true;
arr[i].remark = '正在校验...';
arr[i].isValid = false;
if (arr[i].advertisData) {
arr[i].macAddress = arr[i].advertisData;
}
2026-04-22 08:29:06 +08:00
these.EquipMents.unshift(arr[i]);
}
}
2026-04-01 08:46:32 +08:00
these.sendEquipToMq();
if (newDevice) {
clearTimeout(isValidTime);
isValidTime = setTimeout(these.getDevice, 2000); //延迟执行验证
}
}, pagePath);
// console.log("addEquip")
ble.addReceiveCallback((receivData, f, path, arr) => {
console.log("收到消息", receivData)
console.log("f=", f)
let item = null;
if (f.macAddress) {
item = this.EquipMents.find((v, index) => {
if (v.deviceId == f.deviceId) {
v.macAddress = f.macAddress;
this.$set(this.EquipMents[index], "macAddress", f.macAddress);
console.log("22222");
return true;
}
return false;
});
console.log("111111");
}
if (f.imei) {
2026-04-01 08:46:32 +08:00
f.imei = f.imei.replace(/\u0000/g, '');
item = this.EquipMents.find((v, index) => {
if (v.deviceId == f.deviceId) {
v.imei = f.imei;
this.$set(this.EquipMents[index], "imei", f.imei);
return true;
}
return false;
});
}
if (this.type.communicationMode == 2) {
if (f.macAddress || f.imei) {
this.uploadItem(item);
}
} else { //==1
if (f.macAddress) {
this.uploadItem(item);
}
}
}, pagePath);
ble.addStateBreakCallback(() => {
MsgError('蓝牙不可用', '确定', these);
2026-04-22 08:29:06 +08:00
these.EquipMents.filter((v, i) => {
these.$set(these.EquipMents[i], 'link', false);
});
}, pagePath);
ble.addStateRecoveryCallback(() => {
2026-04-14 15:19:05 +08:00
these.ReSearch();
MsgSuccess('蓝牙恢复可用', '确定', these, () => {
2026-04-06 14:02:00 +08:00
MsgClear(these);
2026-04-22 08:29:06 +08:00
});
},
pagePath);
ble.addDisposeCallback((res) => {
these.EquipMents.find((v, i) => {
if (res.deviceId == v.deviceId) {
these.$set(these.EquipMents[i], 'link', false);
return true;
}
return false;
});
}, pagePath);
ble.addRecoveryCallback((res) => {
these.EquipMents.find((v, i) => {
if (res.deviceId == v.deviceId) {
these.$set(these.EquipMents[i], 'link', true);
return true;
}
return false;
});
}, pagePath);
// #endif
eventChannel = this.getOpenerEventChannel();
eventChannel.on('addType', function(rec) {
console.log("接收到父页面的参数:", rec);
these.type = rec.data;
let ct=these.typeKeys.find(v=>{
if(v.type_name==these.type.typeName){
these.search=v.ble;
return true;
}
return false;
});
let callback = () => {
these.getTypeDeviceCnt().then(res => {
2026-04-01 08:46:32 +08:00
console.error("设备数量:", res);
these.devicesCnt = res;
if (res > 0 && res <= 10000) {
these.getAlltypeDevices().then(devs => {
these.devices = devs;
these.ReSearch();
});
return;
}
these.ReSearch();
}).catch(ex => {
these.devicesCnt = 0;
these.ReSearch();
});
}
2026-04-01 08:46:32 +08:00
callback();
2026-04-01 08:46:32 +08:00
});
2026-04-01 08:46:32 +08:00
2026-04-22 08:29:06 +08:00
// #ifdef APP|APP-PLUS
setTimeout(() => {
MsgInfo("如需要在PC上查看此数据,请复制链接后通过微信发送到PC,在PC端打开然后点右上角扫码授权", "复制链接", these, true, () => {
2026-04-22 08:29:06 +08:00
console.log("开始访问剪切板");
2026-04-01 08:46:32 +08:00
uni.setClipboardData({
data: 'https://static-mp-5b7c35fc-f6fe-4100-a2e1-3669e4d4bfc9.next.bspapp.com/AppTools/views/index.html',
success() {
2026-04-01 08:46:32 +08:00
uni.showToast({
title: '已复制链接'
2026-04-01 08:46:32 +08:00
});
2026-04-02 08:45:36 +08:00
plus.runtime.openURL('weixin://', (err) => {
MsgError("打开微信失败,请手动打开微信,发送至'文件传输助手'");
2026-04-02 08:45:36 +08:00
});
},
2026-04-22 08:29:06 +08:00
fail(ex) {
console.error("ex=", ex);
2026-04-01 08:46:32 +08:00
}
});
});
}, 500);
2026-04-22 08:29:06 +08:00
// #endif
},
onShow: function() {
if (these.type) {
this.ReSearch();
}
},
methods: {
2026-04-01 08:46:32 +08:00
prevPage() {
uni.navigateBack({
});
},
handleRightClick: function(s, e) {
this.scan();
},
initWatch() {
this.$watch("devicesCnt", (newVal, oldVal) => {
const phone = uni.getStorageSync('phone');
mq.sendData('pc/' + phone, JSON.stringify({
devicesCnt: this.devicesCnt
}), false);
});
},
//获取某个类型下的所有设备
getAlltypeDevices() {
return new Promise((succ, err) => {
2026-04-01 08:46:32 +08:00
let json = {
"tenant_id": this.type.tenantId,
"deviceType": this.type.deviceTypeId
};
request({
url: "/app/xinghan/device/getEquipAllByType",
method: 'POST',
data: json,
}).then(res => {
if (res && res.code == 200) {
succ(res.data);
return;
}
err(res);
}).catch(ex => {
console.error("ex=", ex);
err(ex);
});
});
},
//获取类型下的设备数量
getTypeDeviceCnt() {
return new Promise((resolve, reject) => {
2026-04-01 08:46:32 +08:00
let json = {
"tenant_id": this.type.tenantId,
"deviceType": this.type.deviceTypeId
};
console.error("json=", json);
request({
url: "/app/xinghan/device/getEquipCountByType",
method: 'POST',
data: json,
}).then(res => {
console.error("getEquipCountByType res.data=", res.data)
if (res && res.code == 200) {
resolve(res.data);
return;
}
reject(res);
}).catch(ex => {
console.error("ex=", ex);
reject(ex);
});
});
},
getDevice() {
let task = (item) => {
return new Promise((resolve, reject) => {
let f = null;
let fIndex = -1;
these.EquipMents.find(function(v, index) {
if (v.deviceId == item.deviceId) {
f = v;
fIndex = index;
return true;
}
return false;
});
if (fIndex == -1) {
reject("检验出现异常");
console.error("fIndex异常")
return;
}
if (this.devicesCnt > 0) {
console.log("从缓存验证")
if (this.devices && this.devices.length > 0) {
console.log("正在从缓存验证1111")
let eqp = this.devices.find(v => {
let flag = false;
if (!item.advertisData) {
flag = v.bluetooth_name.replace(/\r\n/g, '').replace(
/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '') == item.name;
} else {
flag = v.deviceMac == item.advertisData;
}
return flag;
});
if (eqp) {
console.log("缓存验证成功");
these.$set(these.EquipMents[fIndex], "isUpload",
true);
these.$set(these.EquipMents[fIndex], "remark",
"校验完成,设备已入库");
these.$set(these.EquipMents[fIndex], "macAddress",
eqp.device_mac);
these.$set(these.EquipMents[fIndex], "device_name", eqp.device_name);
these.$set(these.EquipMents[fIndex], 'isValid', true);
console.log("从缓存中找到了设备", eqp);
resolve(eqp);
return;
}
// else{
// console.error("缓存验证失败");
// }
}
// console.error("缓存中找不到此设备22222222", this.devices);
// these.$set(these.EquipMents[fIndex], "remark", "校验完成,设备未入库");
// these.$set(these.EquipMents[fIndex], 'isValid', true);
// reject(null);
// these.sendEquipToMq();
2026-04-01 08:46:32 +08:00
// return;
}
2026-04-01 08:46:32 +08:00
let succCallback = (data) => {
if (data) {
these.$set(these.EquipMents[fIndex], "isUpload",
true);
these.$set(these.EquipMents[fIndex], "remark",
"校验完成,设备已入库");
these.$set(these.EquipMents[fIndex], "macAddress",
data.device_mac);
these.$set(these.EquipMents[fIndex], "imei", data
.device_imei);
these.$set(these.EquipMents[fIndex], "device_name", data.device_name);
2026-04-01 08:46:32 +08:00
} else {
console.error("设备未入库111111", data)
these.$set(these.EquipMents[fIndex], "remark",
"校验完成,设备未入库");
2026-04-01 08:46:32 +08:00
}
2026-04-01 08:46:32 +08:00
these.sendEquipToMq();
}
2026-04-01 08:46:32 +08:00
let errCallback = (ex) => {
if (ex === null) {
these.$set(these.EquipMents[fIndex], "remark", "校验完成,设备未入库");
} else {
these.$set(these.EquipMents[fIndex], "remark", "校验出现异常");
}
2026-04-01 08:46:32 +08:00
these.sendEquipToMq();
}
2026-04-01 08:46:32 +08:00
let p2 = new Promise((succ, err) => {
if (item.advertisData) {
console.error("通过广播数据匹配mac地址");
request({
url: '/app/device/getDeviceInfoByDeviceMac',
method: 'GET',
data: {
deviceMac: item.advertisData
}
}).then(res => {
console.log("通过广播数据验证成功:", res)
if (res && res.code == 200) {
if (res.data) {
let data = {
device_mac: res.data.deviceMac,
device_imei: res.data.deviceImei,
device_name: res.data.deviceName,
id: res.data.id,
bluetooth_name: res.data.bluetoothName
};
succ(data);
} else {
err(null);
}
return;
}
2026-04-01 08:46:32 +08:00
err(res);
}).catch(ex => {
err(ex);
});
} else {
//从后台通过类型和名称查询设备
console.error("通过类型和名称查询设备");
let json = {
"tenant_id": this.type.tenantId,
"deviceType": this.type.deviceTypeId,
"deviceName": item.name
};
request({
url: '/app/xinghan/device/GetDeviceByName',
data: json,
method: 'POST'
}).then(res => {
console.log("通过名称校验结果", res);
if (res && res.code == 200) {
if (res.data) {
succ(res.data);
} else {
err(null);
2026-04-01 08:46:32 +08:00
}
return;
}
2026-04-01 08:46:32 +08:00
err(res);
}).catch(ex => {
err(ex);
});
}
2026-04-01 08:46:32 +08:00
});
p2.then(res => {
succCallback(res);
resolve(res);
2026-04-01 08:46:32 +08:00
}).catch(ex => {
errCallback(ex);
reject(ex);
}).finally(() => {
these.$set(these.EquipMents[fIndex], 'isValid', true);
});
});
}
2026-05-19 17:38:56 +08:00
// for (let i = 0; i < this.EquipMents.length; i++) {
// let element = this.EquipMents[i];
// if (!element.isValid) {
// task(element).catch(ex => {
// if (ex === null && element.advertisData) {
// console.log("广播自动入库");
// this.uploadItem(element);
// }
// });
// }
// }
},
2026-04-01 08:46:32 +08:00
scan() {
uni.scanCode({
success: (res) => {
console.log('条码内容:' + res.result);
let getUrlParams = (url) => {
var p = {},
s = (url.indexOf('?') > -1 ? url.split('?')[1] : '').split('&');
for (var i = 0; i < s.length; i++) {
if (!s[i]) continue;
var kv = s[i].split('=');
p[decodeURIComponent(kv[0])] = kv[1] ? decodeURIComponent(kv[1].replace(
/\+/g, ' ')) : '';
}
return p;
}
let json = getUrlParams(res.result);
if (!json.key) {
MsgError('无效的二维码', '', these);
2026-04-01 08:46:32 +08:00
return;
}
this.scanKey = json.key;
let msg = {
scanResult: '已扫码',
scanCode: 200
};
mq.sendData('pc/' + json.key, JSON.stringify(msg), false);
uni.showModal({
title: '授权申请',
content: 'pc端授权登陆',
confirmText: '同意',
cancelText: '拒绝',
showCancel: true,
success(res) {
if (res.confirm) {
these.pcAuthori(json);
return;
}
if (res.cancel) {
msg.scanResult = "用户拒绝授权";
msg.scanCode = 500;
mq.sendData('pc/' + json.key, JSON.stringify(msg), false);
}
},
})
},
fail: (err) => {
console.log('扫码失败', err);
uni.showToast({
title: '扫码失败',
icon: 'none'
});
}
});
},
pcAuthori() { //同意授权
const token = 'Bearer ' + uni.getStorageSync('token');
const clientid = uni.getStorageSync('clientID');
const phone = uni.getStorageSync('phone');
let msg = {
scanResult: '用户同意授权',
scanUsr: phone,
scanCode: 0,
Authorization: token,
clientid: clientid,
};
console.log("同意授权", msg);
this.Status.pcAuthori = true;
mq.sendData('pc/' + this.scanKey, JSON.stringify(msg), false);
these.sendEquipToMq();
},
sendEquipToMq() {
if (mq && this.scanKey) {
const phone = uni.getStorageSync('phone');
setTimeout(() => {
mq.sendData('pc/' + phone, JSON.stringify({
EquipMents: this.EquipMents
}), false);
}, 500);
}
},
ReSearch() {
if (!ble) {
MsgError('蓝牙模块未初始化', '', this);
return;
}
showLoading(this, {
text: '请稍候...'
});
ble.disconnectDevice().finally(dis => {
2026-04-01 08:46:32 +08:00
ble.StopSearch().finally(res => {
2026-04-22 08:29:06 +08:00
this.EquipMents = [];
this.PairEquip = [];
setTimeout(() => {
2026-05-19 17:38:56 +08:00
ble.StartSearch().then(result => {}).catch(err => {
console.error("err=", err);
MsgError("出现错误:" + err.msg, '', these);
}).finally(() => {
hideLoading(these);
});
}, 600)
}).catch(ex => {
console.error("ex=", ex);
2026-04-01 08:46:32 +08:00
MsgError("出现错误:" + ex.msg, '', these);
});
});
},
uploadItem(item) {
clearTimeout(time);
ble.disconnectDevice(item.deviceId).catch(ex => {});
let exec = () => {
let json = {
// "assignId": 0,
"deviceType": this.type.id,
// "customerId": 0,
"deviceName": item.name, //typeName
"deviceMac": item.macAddress,
"bluetoothName": item.name,
"deviceImei": item.imei,
// "deviceSn": "",
// "file": "",
"remark": this.groupid
}
request({
url: '/app/xinghan/device/add',
method: 'post',
data: json
}).then(res => {
console.log("res=", res);
if (res && res.code == 200) {
this.EquipMents.find((v, index) => {
if (v.deviceId == item.deviceId) {
this.$set(this.EquipMents[index], "isUpload", true);
this.$set(this.EquipMents[index], "remark", "上传成功");
this.devices.push({
bluetooth_name: item.name,
device_mac: item.macAddress,
2026-04-01 08:46:32 +08:00
device_name: item.name
});
this.devicesCnt = this.devices.length;
return true;
}
return false;
});
} else {
console.error("入库错误,", item);
console.error("入库结果,", res);
this.EquipMents.find((v, index) => {
if (v.deviceId == item.deviceId) {
this.$set(this.EquipMents[index], "remark", res.msg);
if (res.msg.indexOf('已存在') > -1) {
this.$set(this.EquipMents[index], "isUpload", true);
} else {
this.$set(this.EquipMents[index], "isUpload", false);
this.devices.find((d, i) => {
if (d.device_mac == item.macAddress) {
this.$set(this.EquipMents[index],
"device_name", d
.device_name);
return true;
}
});
}
2026-04-01 08:46:32 +08:00
return true;
}
return false;
});
2026-04-01 08:46:32 +08:00
}
2026-04-01 08:46:32 +08:00
}).catch(ex => {}).finally(() => {
these.sendEquipToMq();
});
}
time = setTimeout(exec, 100)
},
Link: function(item) {
if (item.advertisData) {
this.uploadItem(item);
return;
}
let exec = () => {
showLoading(this, {
text: "正在连接..."
});
let index = 1;
2026-04-22 08:29:06 +08:00
let total = 1;
let linkCallback = (res) => {
let c = these.PairEquip.find(function(v) {
return v.deviceId == item.deviceId;
});
if (!c) {
these.PairEquip.push(item);
}
2026-05-19 17:38:56 +08:00
console.log("连接成功,开始发送识别指令", these.device);
hideLoading(these);
2026-05-19 17:38:56 +08:00
let json = {
ins_disc: 1
}
ble.sendString(item.deviceId, json, item.writeServiceId, item.wirteCharactId, 30).then(res => {
}).catch(ex => {
console.error("蓝牙识别指令发送失败", ex);
});
}
let execLink = () => {
return new Promise((resolve, reject) => {
if (index > total) {
reject({
msg: "连接超时"
});
return;
}
ble.LinkBlue(item.deviceId).then((res) => {
console.log("连接成功");
these.EquipMents.find((v, index) => {
if (v.deviceId == item.deviceId) {
this.$set(this.EquipMents[index], "link",
true);
return true;
}
return false;
});
resolve(res);
}).catch((ex) => {
if (index == total) {
console.log("连接了N次都没连上");
reject(ex);
return;
}
index++;
updateLoading(this, {
text: ex.msg + ",正在重试第" + index + "次"
})
execLink().then(resolve).catch(reject);
})
});
}
execLink().then((res) => {
linkCallback(res);
2026-04-01 08:46:32 +08:00
these.sendEquipToMq();
}).catch(ex => {
console.log("ex=", ex)
MsgError("连接失败" + ex.code + ex.msg, '', these);
hideLoading(these);
});
}
if (this.PairEquip && this.PairEquip.length) {
ble && ble.disconnectDevice();
this.PairEquip = [];
exec();
} else {
exec();
}
}
}
}
</script>
<style>
.tabItem.active {
border-bottom: 2rpx solid #BBE600;
color: #BBE600;
2026-04-22 08:29:06 +08:00
}
.mathIcon {
2026-04-22 08:29:06 +08:00
color: #BBE600;
}
.tab {
2026-04-22 08:29:06 +08:00
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: space-evenly;
height: 60rpx;
font-size: 28rpx;
2026-04-22 08:29:06 +08:00
}
.noLink {
text-align: center;
width: 100%;
font-size: 28rpx;
}
.content {
background-color: #121212;
color: #ffffffde;
box-sizing: border-box;
overflow: hidden;
width: 100%;
min-height: 100vh;
height: auto;
}
.p100 {
width: 100%;
height: 100%;
}
.fleft {
float: left;
}
.fright {
float: right;
}
.clear {
clear: both;
}
.center {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: center;
align-items: center;
}
.topAnimate {
position: absolute;
left: 0rpx;
width: 100%;
height: 400rpx;
top: 20px;
/* 距离视口顶部 20px 时固定 */
z-index: 100;
/* 确保元素显示在最上层 */
}
.animate {
width: 100%;
height: 400rpx;
position: relative;
}
.animate .animateContent {
position: relative;
z-index: 0;
}
.animate .imgContent {
position: absolute;
z-index: 1;
width: 100%;
height: 100%;
}
.animate .imgContent .img {
height: 100rpx;
width: 100rpx;
background: #bbe600;
border-radius: 50%;
}
.animate .titleIco {
width: 36rpx;
height: 36rpx;
}
.circle {
position: absolute;
border-radius: 50%;
background-color: #bbe60033;
animation: expand 4s infinite ease-out;
display: inline-block;
transform: translate(-50%, -50%);
}
.circle:nth-child(2) {
animation-delay: 1s;
}
.circle:nth-child(3) {
animation-delay: 2s;
}
@keyframes expand {
0% {
width: 0;
height: 0;
opacity: 0.8;
}
100% {
width: 18.75rem;
height: 18.75rem;
opacity: 0.2;
}
}
.mainContent {
padding: 30rpx;
box-sizing: border-box;
width: 100%;
overflow-y: scroll;
}
.mainContent .p100 {}
.lblTitle {
color: #26df1cde;
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 700;
text-align: left;
width: 100%;
height: 60rpx;
line-height: 60rpx;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
align-items: center;
justify-content: space-between;
}
.list {
min-height: 120rpx;
}
2026-04-22 08:29:06 +08:00
.list .item {
width: 100%;
min-height: 120rpx;
height: auto;
box-sizing: border-box;
padding: 10rpx;
border-radius: 8px;
background: #1a1a1a;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
margin-top: 20rpx;
position: relative;
}
.list .item .leftImg {
width: 60rpx;
height: 60rpx;
}
.list .item .centertxt {
width: calc(100% - 60rpx);
height: 100%;
padding-left: 10rpx;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: space-evenly;
align-items: flex-start;
align-content: flex-start;
}
.list .item .rightIco {
position: absolute;
bottom: 0px;
right: 0px;
width: 0;
height: 0;
border-style: solid;
border-width: 0 0 30rpx 30rpx;
}
.list .item .leftImg .titleIco {
width: 100%;
height: 100%;
}
.list .item .name {
color: #ffffffde;
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
line-height: 36rpx;
text-align: left;
width: 100%;
}
.list .item .name.lbl {
font-size: 26rpx !important;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
align-items: center;
justify-content: flex-start;
}
.list .item .name .green {
color: limegreen;
}
.list .item .name .red {
color: #FF0000;
}
.list .item .id {
color: #ffffff99;
font-family: "PingFang SC";
font-size: 24rpx;
font-weight: 400;
line-height: 36rpx;
text-align: left;
}
.list .item .rightIco .img {
width: 45rpx;
height: 45rpx;
}
.openBlue {
padding: 30rpx;
width: 100%;
box-sizing: border-box;
height: auto;
}
.openBlue .txt {
color: rgba(255, 255, 255, 0.87);
font-family: "PingFang SC";
font-size: 28rpx;
font-weight: 400;
letter-spacing: 0.14rpx;
text-align: center;
}
.openBlue .btns {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
align-items: center;
justify-content: space-evenly;
margin-top: 50rpx;
width: 100%;
height: auto;
}
.openBlue .btn {
border-radius: 91rpx;
box-sizing: border-box;
width: 25%;
height: 60rpx;
text-align: center;
font-family: "PingFang SC";
font-size: 28rpx;
letter-spacing: 12rpx;
display: flex !important;
align-items: center;
letter-spacing: 0.375rem;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: center;
}
.openBlue .cancel {
border: 1px solid rgba(255, 255, 255, 1);
color: rgba(255, 255, 255, 1);
}
.openBlue .ok {
background-color: #BBE600;
color: #232323;
}
.margintLeft10 {
margin-left: 20rpx;
color: #BBE600;
font-size: 36rpx;
}
.bleIco {
width: 60rpx;
}
.th {
display: flex;
height: 70rpx;
line-height: 70rpx;
}
.bgred {
border-color: transparent transparent #FF0000 transparent;
}
.bggreen {
border-color: transparent transparent #4CAF50 transparent;
}
@keyframes rotateClockwise {
from {
transform: rotate(0deg);
/* 起始角度0度 */
}
to {
transform: rotate(360deg);
/* 结束角度360度顺时针一圈 */
}
}
/* 应用动画到元素 */
.rotateAnimation {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: center;
align-items: center;
width: 32rpx;
height: 32rpx;
animation: rotateClockwise 3s linear infinite;
}
2026-04-01 08:46:32 +08:00
.topStatric {
width: 100%;
box-sizing: border-box;
padding: 0rpx 30rpx;
2026-04-01 08:46:32 +08:00
position: fixed;
top: 0rpx;
z-index: 99;
background-color: #121212;
}
/* #ifdef H5 */
.topStatric {
top: 44px;
}
.mainContent {
2026-04-22 08:29:06 +08:00
margin-top: 280rpx;
}
2026-04-22 08:29:06 +08:00
.searchList {
width: 100%;
height: calc(100% - 186rpx);
overflow-y: scroll;
margin-top: 90rpx;
}
/* #endif */
/* #ifdef APP */
.mainContent {
margin-top: 240rpx;
}
.topStatric {
2026-04-22 08:29:06 +08:00
top: 130rpx
}
2026-04-22 08:29:06 +08:00
.searchList {
width: 100%;
height: calc(100% - 186rpx);
overflow-y: scroll;
margin-top: 150rpx;
}
2026-04-01 08:46:32 +08:00
/* #endif */
.uni-mt-5 {
background-color: #000000;
}
.uni-easyinput__content {
background-color: #121212 !important;
}
2026-04-01 08:46:32 +08:00
.navbarRight .img {
width: 35rpx;
height: 35rpx;
margin-right: 20rpx;
}
.uni-navbar--fixed {
top: 0rpx;
}
/deep/ .uni-navbar--fixed {
top: 0px;
}
/deep/ .uni-navbar__placeholder {
display: none !important;
}
</style>