1、项目需求:
使用uni-app开发门锁小程序,主要功能有:门锁添加、远程开锁、蓝牙开锁、密码管理、指纹管理。
2、项目重点:
前端需要调用厂家提供的设备文档来进行设备的添加、设备钥匙(密码、指纹)的添加、设备的开锁。
3、项目前期配置
微信平台配置好插件:在项目的manifest.json导入该插件:
4、具体页面流程:
设备api进行二次封装方便使用:
创建detectingBluetooth.ts文件,使用class创建对象并将设备api二次封装方便后续使用。
declare const wx: any;
// 门锁各类方法
export class HandlerBluetooth {
/**
*@function 处理检测蓝牙开启
* @returns true为开启 fsle为关闭
*/
async handleGetSetting() {
return new Promise<boolean>((resolve, reject) => {
uni.getSetting({
success(res) {
if (!res.authSetting['scope.bluetooth']) {
uni.showModal({
title: '提示',
content: '当前小程序未开启蓝牙授权,是否前往授权?',
success(res) {
if (res.confirm) {
wx.openBluetoothAdapter();
resolve(true);
} else if (res.cancel) {
resolve(false);
}
},
});
} else {
uni.openBluetoothAdapter({
success: (res) => {
resolve(true);
},
fail: (res) => {
//如果手机上的蓝牙没有打开,可以提醒用户
resolve(false);
uni.showModal({
title: '提示',
content: '请打开手机蓝牙',
showCancel: false,
});
uni.closeBluetoothAdapter({});
},
});
}
},
});
});
}
/**
* @function 处理添加蓝牙设备
* @param plugin plugin对象
* @returns 成功返回蓝牙对象,失败返回失败对象
*/
async handleAddBluetoothDevice(plugin: any) {
return new Promise<any>((resolve, reject) => {
// 监听“初始化完成”事件
plugin.on('ready', function (plugin) {
console.info('plugin is on ready', plugin);
plugin
.addBluetoothDevice()
.then(function (res) {
uni.hideLoading();
resolve(res);
})
.catch(function (err) {
uni.hideLoading();
reject(err);
});
});
// 监听“运行错误”事件
plugin.on('error', function (err) {
console.info('plugin is on error -->', err);
});
});
}
/**
* @function 处理蓝牙开锁
* @param plugin plugin对象
* @returns 开锁成功或者失败
*/
async handleOpenLock(plugin: any) {
return new Promise<any>((resolve, reject) => {
plugin
.openLock()
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
/**
* @function 添加蓝牙钥匙
* @param type 添加方式 :0:按指定的钥匙类型添加;1:按内容添加
* @param keyType 钥匙类型:0: 指纹 1:密码 2:卡片 3:遥控 4:二维码 5:机械钥匙 6:人脸 7:App
* @param keyGroupId 用户组 ID:901
* @param plugin plugin对象
*/
async handleAddkeyKey(type: number, keyType: number, keyGroupId: number, plugin: any, key?: string) {
return new Promise<any>((resolve, reject) => {
let params: any = {
type,
keyType,
keyGroupId,
lockKeyId: 0,
validEndTime: '',
validStartTime: '',
usageCount: 255,
validTimeMode: 0, // 时间模式为有效期类型
};
if (key) {
params.key = key;
}
console.log('params--->', params);
plugin
.addKey(params)
.then((res) => {
resolve(res);
})
.catch((err) => {
console.log('err--->', err);
resolve(err);
uni.hideLoading();
});
});
}
/**
* @function 更新钥匙
* @param newPassword 新密码
* @param lockKeyId 门锁中钥匙的唯一 Id
* @param plugin plugin对象
* @returns
*/
async handleUpdateKey(newPassword: string, lockKeyId: number, plugin: any) {
return new Promise<any>((resolve, reject) => {
plugin
.updatePassword({ newPassword, lockKeyId })
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
/**
* @function 校验门锁初始信息
* @param plugin plugin对象
* @returns 返回成功或失败对象
*/
async handleValidateLockInitialInfo(plugin: any) {
return new Promise<any>((resolve, reject) => {
plugin.validateLockInitialInfo({ isSuccess: true }).then((res) => {
const options = {
openMode: 2,
volumeEnable: 1,
antiLockEnable: 2,
};
plugin
.setSystemInfo(options)
.then((res) => {
resolve(res);
})
.catch((err) => {
resolve(err);
});
});
});
}
}
添加设备:
初始化设备并连接:
import { HandlerBluetooth } from '../../utils/detectingBluetooth';
declare const requirePlugin: any;
const detectingBluetoothObj = new HandlerBluetooth();
const createPlugin = requirePlugin('BLELockSDK'); // 使用蓝牙插件
const Plugin = createPlugin();
let plugin: any;
// 定义数据
var config = {
keyGroupId: ‘’, // 由业务服务器返回
};
// 添加门锁
function insertDoorLock() {
detectingBluetoothObj.handleGetSetting().then((res) => {
if (res) {
uni.showLoading({
title: '连接中...',
mask: true,
});
// 初始化时调用方式
plugin = new Plugin({
keyGroupId: config.keyGroupId,
});
detectingBluetoothObj.handleAddBluetoothDevice(plugin).then((res) => {
const data = JSON.parse(JSON.stringify(res));
Object.assign(options.form.extAttrMap, data.data.DNAInfo); // 后面对接后端需要的数据
options.form.deviceInfo.deviceCode = data.data.DNAInfo.lockMac;// 后面对接后端需要的数据
isShow.value = true;
});
}
});
}
校验门锁初始信息、设置设备参数、对接后端新增设备:
function submitInsert() {
const submitData = {
spaceId: options.form.spaceId,
deviceInfo: options.form.deviceInfo,
extAttrMap: options.form.extAttrMap,
};
//校验门锁初始信息、设置设备参数
detectingBluetoothObj.handleValidateLockInitialInfo(plugin).then((res) => {
if (res) {
const data = JSON.parse(JSON.stringify(res));
if (data.errCode === '01') {
iotAccess.insert4LockDevice(submitData).then((res) => {
// 对接后端
if (res) {
uni.hideLoading();
util.showToast('添加设备成功', 'success');
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1500);
}
});
}
}
});
}
设备详情:
蓝牙开锁 远程开锁:
import util from '../../utils/util';
import { HandlerBluetooth } from '../../utils/detectingBluetooth';
// #region 蓝牙所需参数
declare const requirePlugin: any;
const detectingBluetoothObj = new HandlerBluetooth();
const createPlugin = requirePlugin('BLELockSDK');
const Plugin = createPlugin();
let plugin: any;
// 定义数据
var config = {
keyGroupId: '', // 由业务服务器返回
lockMac: '',
aesKey: '',
authCode: '',
};
// #endregion
// #region 蓝牙开锁+远程开锁
function handleOpenDoor(type: 'bluetooth' | 'remote') {
switch (type) {
// 蓝牙
case 'bluetooth':
uni.showLoading({
title: '蓝牙开锁中...',
mask: true,
});
handle();
break;
// 远程
case 'remote':
uni.showLoading({
title: '远程开锁中...',
mask: true,
});
iotAccess.openDoor(doorInfo.id).then((res) => {
if (res) {
uni.hideLoading();
util.showToast('开锁成功', 'success');
}
});
break;
}
}
function handle() {
if (options.flag) {
return;
}
options.flag = true;
setTimeout(() => {
options.flag = false;
}, 1000); // 防止开锁连点
detectingBluetoothObj.handleGetSetting().then((res) => {
if (res) {
if (options.isFirst) { // 第一次开锁需要初始化设备速度会慢,后面开锁速度就会
plugin = new Plugin({
authCode: config.authCode,
aesKey: config.aesKey,
lockMac: config.lockMac,
keyGroupId: config.keyGroupId,
});
plugin.on('ready', function () {
openLock();
});
options.isFirst = false;
} else {
openLock();
}
}
});
}
function openLock() {
detectingBluetoothObj
.handleOpenLock(plugin)
.then(() => {
const params = {
device: { id: doorInfo.id },
user: { id: authorInfo.userId },
identifyMode: 'Bluetooth',
status: 'Success',
};
iotAccess
.insertAcessRecordPage(params)
.then((res) => {
uni.hideLoading();
if (res) {
util.showToast('开锁成功', 'success');
}
})
.catch(() => {
uni.hideLoading();
util.showToast('开锁失败', 'none');
});
})
.catch(() => {
uni.hideLoading();
util.showToast('开锁失败', 'success');
});
}
密码管理:
import { HandlerBluetooth } from '../../utils/detectingBluetooth';
// #region 蓝牙所需参数
declare const requirePlugin: any;
const detectingBluetoothObj = new HandlerBluetooth();
const createPlugin = requirePlugin('BLELockSDK');
const Plugin = createPlugin();
let plugin: any;
// 定义数据
var config = {
keyGroupId: '', // 由业务服务器返回
lockMac: '',
aesKey: '',
authCode: '',
};
// #endregion
function handleConfirmSearch() {
uni.showLoading({
title: '加载中....',
mask: true,
});
handlerBluetooth.handleGetSetting().then((res) => {
if (res) {
if (options.isFirst) {
plugin = new Plugin({
authCode: config.authCode,
aesKey: config.aesKey,
lockMac: config.lockMac,
keyGroupId: config.keyGroupId,
});
plugin.on('ready', function () {
console.log('ready====>');
handleAddkeyOrUpdateKey();
});
options.isFirst = false;
} else {
handleAddkeyOrUpdateKey();
}
}
});
}
// 不存在密码时添加钥匙、存在密码时修改密码
function handleAddkeyOrUpdateKey() {
if (options.isPassword) { // 页面初始化根据id查询设备是否有密码,存在则调用修改,不存在则调用添加
console.log('添加密码');
handlerBluetooth
.handleAddkeyKey(1, 1, config.keyGroupId, plugin, form.submitPassword)
.then((res) => {
handleUpdateLockPassword(doorInfo.id, form.submitPassword, res.data.lockKeyId);
})
.catch((err) => {
handleShowToast('失败,请重试', 'none');
});
} else {
console.log('修改密码');
handlerBluetooth
.handleUpdateKey(form.submitPassword, Number(doorInfo.passwordLockKeyId), plugin)
.then((res) => {
handleUpdateLockPassword(doorInfo.id, form.submitPassword, res.data.lockKeyId);
})
.catch(() => {
uni.hideLoading();
handleShowToast('失败,请重试', 'none');
});
}
}
function handleUpdateLockPassword(deviceId: string, password: string, passwordLockKeyId: number) {
iotAccess
.updateLockPassword(deviceId, password, passwordLockKeyId)
.then((res) => {
if (res) {
uni.hideLoading();
handleShowToast('密码修改成功', 'success');
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
})
.catch((err) => {
uni.hideLoading();
handleShowToast(err.description, 'none');
});
}
指纹管理:
import { HandlerBluetooth } from '../../utils/detectingBluetooth';
// #region 蓝牙所需参数
declare const requirePlugin: any;
const detectingBluetoothObj = new HandlerBluetooth();
const createPlugin = requirePlugin('BLELockSDK');
const Plugin = createPlugin();
let plugin: any;
// 定义数据
var config = {
keyGroupId: '', // 由业务服务器返回
lockMac: '',
aesKey: '',
authCode: '',
};
// #endregion
// #region 方法
function handleGetDeviceInfo() {
//根据id查询设备详细信息
iotAccess.getDevice(doorInfo.id).then((res) => {
if (res) {
const data = JSON.parse(JSON.stringify(res.data.data));
config.lockMac = data.device.extAttrMap.lockMac;
config.aesKey = data.device.extAttrMap.aesKey;
config.authCode = data.device.extAttrMap.generalAuthCode;
handleGetSetting();
}
});
}
function handleGetSetting() {
if (!options.isOpen) { // 标识符判断手机蓝牙是否开启
detectingBluetoothObj.handleGetSetting().then((res) => {
options.isOpen = res;
if (res) {
uni.showLoading({
title: '正在读取设备...',
mask: true,
});
handleSetPlugin();
}
});
} else {
handleSetPlugin();
}
}
function handleSetPlugin() {
if (options.isFirst) {
plugin = new Plugin({
authCode: config.authCode,
aesKey: config.aesKey,
lockMac: config.lockMac,
keyGroupId: config.keyGroupId,
});
plugin.on('ready', function (ready) {
console.log('ready--->', ready);
detectingBluetoothObj.handleAddkeyKey(0, 0, config.keyGroupId, plugin);
});
plugin.on('report:addKey', (res) => {
// 监听设备指纹的添加
console.log('监听指纹---->');
if (res.errCode == '01') {
const params = {
deviceInfo: { id: doorInfo.id },
lockKeyId: res.data.lockKeyId,
lockKeyName: '未命名',
lockKeyType: '1',
};
iotAccess.addLockUserKey(params).then((res) => {
if (res) {
const data = JSON.parse(JSON.stringify(res.data.data));
uni.redirectTo({
url: '', // 跳转页面对接后端将指纹添加到该设备上
});
}
});
}
});
options.isFirst = false;
} else {
detectingBluetoothObj.handleAddkeyKey(0, 0, config.keyGroupId, plugin);
}
}
// #endregion