3797 lines
119 KiB
JavaScript
3797 lines
119 KiB
JavaScript
/**
|
||
* @description 蓝牙数据持久化
|
||
*/
|
||
import { defineStore } from 'pinia'
|
||
import crc from 'crc'
|
||
import { sm4 } from 'sm-crypto'
|
||
import { md5 } from 'js-md5'
|
||
import { getServerDatetime } from '@/api/check'
|
||
import { getUserNoListRequest, updateLockUserNoRequest } from '@/api/key'
|
||
import { updateElectricQuantityRequest } from '@/api/room'
|
||
import { reportOpenDoorRequest } from '@/api/lockRecords'
|
||
import { updateTimezoneOffsetRequest } from '@/api/user'
|
||
import log from '@/utils/log'
|
||
import { useUserStore } from '@/stores/user'
|
||
import { getLastRecordTimeRequest, uploadRecordRequest } from '@/api/record'
|
||
import { transportType } from '@/constant/transportType'
|
||
import { passthrough } from '@/api/sdk'
|
||
|
||
// 定时器
|
||
let timer
|
||
// 特性值回调
|
||
let characteristicValueCallback = null
|
||
// 搜索次数
|
||
let searchNumber = 10
|
||
// 搜索提示标志
|
||
let searchTipFlag = true
|
||
|
||
// 命令ID
|
||
const cmdIds = {
|
||
// 获取公钥
|
||
getPublicKey: 0x3090,
|
||
// 获取私钥
|
||
getCommKey: 0x3091,
|
||
// 获取锁状态
|
||
getLockStatus: 0x3040,
|
||
// 新增用户
|
||
addUser: 0x3001,
|
||
// 开门
|
||
openDoor: 0x3005,
|
||
// 重置设备
|
||
resetDevice: 0x3004,
|
||
// 清理用户
|
||
cleanUser: 0x300c,
|
||
// 扩展命令
|
||
expandCmd: 0x3030,
|
||
// 校准时间
|
||
calibrationTime: 0x30f0,
|
||
// 锁密码列表
|
||
lockPasswordList: 0x3021,
|
||
// 锁卡片列表
|
||
lockCardList: 0x3022,
|
||
// 锁指纹列表
|
||
lockFingerprintList: 0x3023,
|
||
// 锁人脸列表
|
||
lockFaceList: 0x3024,
|
||
// 锁掌静脉列表
|
||
lockPalmVeinList: 0x3025,
|
||
// 锁遥控列表
|
||
lockRemoteList: 0x3026,
|
||
// 锁设置列表
|
||
lockSettingList: 0x302a,
|
||
// 获取Wi-Fi列表
|
||
getWifiList: 0x30f6,
|
||
// Wi-Fi列表
|
||
wifiList: 0x30f7,
|
||
// 配网
|
||
distributionNetwork: 0x30f4,
|
||
// 配网结果
|
||
distributionNetworkResult: 0x30f5
|
||
}
|
||
|
||
// 子命令ID
|
||
const subCmdIds = {
|
||
// 设置开锁密码
|
||
setLockPassword: 3,
|
||
// 重置开锁密码
|
||
resetLockPassword: 19,
|
||
// 注册卡片
|
||
registerCard: 24,
|
||
// 注册卡片确认
|
||
registerCardConfirm: 22,
|
||
// 注册卡片取消
|
||
registerCardCancel: 25,
|
||
// 注册指纹
|
||
registerFingerprint: 36,
|
||
// 注册指纹确认
|
||
registerFingerprintConfirm: 32,
|
||
// 注册指纹取消
|
||
registerFingerprintCancel: 37,
|
||
// 注册指纹过程
|
||
registerFingerprintProcess: 33,
|
||
// 注册人脸
|
||
registerFace: 81,
|
||
// 注册人脸确认
|
||
registerFaceConfirm: 82,
|
||
// 注册人脸取消
|
||
registerFaceCancel: 86,
|
||
// 注册人脸过程
|
||
registerFaceProcess: 83,
|
||
// 注册遥控
|
||
registerRemote: 26,
|
||
// 注册遥控确认
|
||
registerRemoteConfirm: 27,
|
||
// 注册遥控取消
|
||
registerRemoteCancel: 28,
|
||
// 注册掌纹
|
||
registerPalmVein: 42,
|
||
// 注册掌纹确认
|
||
registerPalmVeinConfirm: 43,
|
||
// 注册掌纹取消
|
||
registerPalmVeinCancel: 44,
|
||
// 同步操作记录
|
||
syncRecord: 41,
|
||
// 更新管理员密码
|
||
updateAdminPassword: 2,
|
||
// 修改设置
|
||
updateSetting: 70,
|
||
// 修改设置带参数
|
||
updateSettingWithParams: 72,
|
||
// 微信票据
|
||
weChatTickets: 55
|
||
}
|
||
|
||
export const useBluetoothStore = defineStore('ble', {
|
||
state() {
|
||
return {
|
||
/*
|
||
* 蓝牙状态
|
||
* -1 未知(初始状态)
|
||
* 0 正常
|
||
* 1 系统蓝牙未打开
|
||
* 2 小程序蓝牙功能被禁用
|
||
* 3 系统蓝牙未打开且小程序蓝牙功能被禁用
|
||
*/
|
||
bluetoothStatus: -1,
|
||
// 设备列表
|
||
deviceList: [],
|
||
// 当前锁信息
|
||
currentLockInfo: {},
|
||
// 当前锁设置信息
|
||
currentLockSetting: null,
|
||
// 当前锁消息设置
|
||
currentLockNoticeSetting: null,
|
||
// 消息序号
|
||
messageCount: 1,
|
||
// 是否初始化蓝牙
|
||
isInitBluetooth: false,
|
||
// 服务器时间
|
||
serverTimestamp: 0,
|
||
// 设备keyID
|
||
keyId: '0',
|
||
// 刚绑定的设备名称
|
||
bindedDeviceNameList: []
|
||
}
|
||
},
|
||
actions: {
|
||
// 更新锁消息设置
|
||
updateCurrentLockNoticeSetting(lockNoticeSetting) {
|
||
this.currentLockNoticeSetting = { ...this.currentLockNoticeSetting, ...lockNoticeSetting }
|
||
},
|
||
// 保存刚绑定的设备名称
|
||
updateBindedDeviceName(name) {
|
||
if (!this.bindedDeviceNameList.includes(name)) {
|
||
this.bindedDeviceNameList.push(name)
|
||
}
|
||
},
|
||
// 更新keyId
|
||
updateKeyId(keyId) {
|
||
this.keyId = keyId
|
||
},
|
||
// 二进制转字符串
|
||
uint8ArrayToString(uint8Array) {
|
||
let str = ''
|
||
for (let i = 0; i < uint8Array.length; i++) {
|
||
if (uint8Array[i] !== 0) {
|
||
str += String.fromCharCode(uint8Array[i])
|
||
}
|
||
}
|
||
return str
|
||
},
|
||
// 更新服务端时间戳
|
||
async updateServerTimestamp() {
|
||
const { code, data, message } = await getServerDatetime({})
|
||
let timestamp = new Date().getTime()
|
||
if (code === 0) {
|
||
this.serverTimestamp = parseInt(data.date / 1000, 10)
|
||
timestamp = data.date
|
||
}
|
||
return { code, data: { ...data, timestamp }, message }
|
||
},
|
||
// 关闭全部蓝牙监听并关闭蓝牙模拟
|
||
closeAllBluetooth() {
|
||
// #ifdef MP
|
||
uni.offBluetoothAdapterStateChange()
|
||
// #endif
|
||
uni.closeBluetoothAdapter({
|
||
success(res) {
|
||
console.log('关闭蓝牙模块', res)
|
||
}
|
||
})
|
||
},
|
||
// 初始化并监听
|
||
async initAndListenBluetooth(tipFlag) {
|
||
// 初始化蓝牙
|
||
const initResult = await this.initBluetooth(tipFlag)
|
||
if (initResult) {
|
||
// 更新蓝牙初始化状态
|
||
this.updateInitBluetooth(true)
|
||
// 监听蓝牙连接状态
|
||
this.onBluetoothConnectStatus()
|
||
// 监听设备特征值变化
|
||
this.onBluetoothCharacteristicValueChange()
|
||
|
||
return true
|
||
}
|
||
return false
|
||
},
|
||
// 更新是否初始化蓝牙字段
|
||
updateInitBluetooth(value) {
|
||
this.isInitBluetooth = value
|
||
},
|
||
// 初始化蓝牙模块
|
||
initBluetooth(tipFlag = true) {
|
||
const that = this
|
||
// 初始化蓝牙模块
|
||
return new Promise(resolve => {
|
||
uni.openBluetoothAdapter({
|
||
success() {
|
||
that.bluetoothStatus = 0
|
||
console.log('蓝牙初始化成功')
|
||
resolve(true)
|
||
},
|
||
fail(err) {
|
||
console.log('蓝牙初始化失败', err)
|
||
// 系统蓝牙未打开
|
||
if (err.errCode === 10001 || err.code === 10001) {
|
||
if (that.bluetoothStatus === 2) {
|
||
that.bluetoothStatus = 3
|
||
} else {
|
||
that.bluetoothStatus = 1
|
||
}
|
||
}
|
||
// 小程序蓝牙功能被禁用
|
||
if (err.errno === 103) {
|
||
if (that.bluetoothStatus === 1) {
|
||
that.bluetoothStatus = 3
|
||
} else {
|
||
that.bluetoothStatus = 2
|
||
}
|
||
}
|
||
// 蓝牙已经初始化
|
||
if (err.errMsg === 'openBluetoothAdapter:fail already opened' || err.code === -1) {
|
||
resolve(true)
|
||
return
|
||
}
|
||
if (err.errno === 3 && tipFlag) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '蓝牙功能需要附近设备权限,请前往设置开启微信的附近设备权限后再试',
|
||
showCancel: false,
|
||
confirmText: '确定',
|
||
success(res) {
|
||
if (res.confirm) {
|
||
uni.openAppAuthorizeSetting({
|
||
success(res) {
|
||
console.log(res)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
resolve(false)
|
||
}
|
||
})
|
||
})
|
||
},
|
||
// 监听蓝牙状态变化
|
||
onBluetoothState() {
|
||
const that = this
|
||
uni.onBluetoothAdapterStateChange(res => {
|
||
console.log('蓝牙状态改变', res)
|
||
if (that.bluetoothStatus === 3 && res.available) {
|
||
that.bluetoothStatus = 2
|
||
} else if (that.bluetoothStatus === 2 && !res.available) {
|
||
that.bluetoothStatus = 3
|
||
} else if (that.bluetoothStatus === 1 && res.available) {
|
||
that.bluetoothStatus = 0
|
||
} else if (that.bluetoothStatus === 0 && !res.available) {
|
||
that.bluetoothStatus = 1
|
||
} else if (that.bluetoothStatus === -1) {
|
||
if (res.available) {
|
||
that.bluetoothStatus = 0
|
||
} else {
|
||
that.bluetoothStatus = 1
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 监听蓝牙设备连接状态
|
||
onBluetoothConnectStatus() {
|
||
const that = this
|
||
uni.onBLEConnectionStateChange(function (res) {
|
||
if (res.deviceId === that.currentLockInfo.deviceId) {
|
||
console.log('设备连接状态改变', res)
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
connected: res.connected
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 解析特征值
|
||
async parsingCharacteristicValue(binaryData) {
|
||
const $user = useUserStore()
|
||
const that = this
|
||
// 0x20 明文 0x22 SM4(事先约定密钥) 0x23 SM4(设备指定密钥)
|
||
if (binaryData[7] === 0x20) {
|
||
if (binaryData[12] * 256 + binaryData[13] === cmdIds.getPublicKey) {
|
||
if (binaryData[14] === 0) {
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
publicKey: [...binaryData.slice(15, 31)]
|
||
})
|
||
}
|
||
characteristicValueCallback({
|
||
code: binaryData[14]
|
||
})
|
||
}
|
||
} else if (binaryData[7] === 0x22) {
|
||
// 截取入参
|
||
const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
|
||
// 解密
|
||
const key = new Uint8Array(16)
|
||
for (let i = 0; i < that.currentLockInfo.name.length; i++) {
|
||
key[i] = that.currentLockInfo.name.charCodeAt(i)
|
||
}
|
||
const decrypted = sm4.decrypt(cebBinaryData, key, { mode: 'ecb', output: 'array' })
|
||
console.log('ecb解密后的数据', decrypted)
|
||
|
||
if (decrypted[0] * 256 + decrypted[1] === cmdIds.getCommKey) {
|
||
if (decrypted[2] === 0) {
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
commKey: decrypted.slice(3, 19),
|
||
signKey: decrypted.slice(19, 35),
|
||
pwdTimestamp: this.arrayToTimestamp(decrypted.slice(35, 39)) * 1000
|
||
})
|
||
console.log('commKey', Array.from(that.currentLockInfo.commKey))
|
||
console.log('signKey', Array.from(that.currentLockInfo.signKey))
|
||
}
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
}
|
||
} else {
|
||
const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
|
||
const decrypted = sm4.decrypt(cebBinaryData, that.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array',
|
||
padding: 'none'
|
||
})
|
||
const length = binaryData[10] * 256 + binaryData[11]
|
||
console.log('ecb解密后的数据', decrypted)
|
||
|
||
const cmdId = decrypted[0] * 256 + decrypted[1]
|
||
|
||
switch (cmdId) {
|
||
case cmdIds.getLockStatus:
|
||
if (decrypted[2] === 0) {
|
||
const lockConfig = {
|
||
vendor: that.uint8ArrayToString(decrypted.slice(3, 23)),
|
||
product: decrypted[23],
|
||
model: that.uint8ArrayToString(decrypted.slice(24, 44)),
|
||
fwVersion: that.uint8ArrayToString(decrypted.slice(44, 64)),
|
||
hwVersion: that.uint8ArrayToString(decrypted.slice(64, 84)),
|
||
serialNum0: that.uint8ArrayToString(decrypted.slice(84, 100)),
|
||
serialNum1: that.uint8ArrayToString(decrypted.slice(100, 116)),
|
||
btDeviceName: that.uint8ArrayToString(decrypted.slice(116, 132)),
|
||
electricQuantity: decrypted[132],
|
||
electricQuantityStandby: decrypted[133],
|
||
restoreCount: decrypted[134] * 256 + decrypted[135],
|
||
restoreDate: this.arrayToTimestamp(decrypted.slice(136, 140)),
|
||
icPartNo: that.uint8ArrayToString(decrypted.slice(140, 150)),
|
||
indate: this.arrayToTimestamp(decrypted.slice(150, 154)) * 1000,
|
||
mac: that.uint8ArrayToString(decrypted.slice(154, 174)),
|
||
timezoneOffset: new Date().getTimezoneOffset() * -60
|
||
}
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
featureValue: that.uint8ArrayToString(decrypted.slice(175, 175 + decrypted[174])),
|
||
featureSettingValue: that.uint8ArrayToString(
|
||
decrypted.slice(
|
||
176 + decrypted[174],
|
||
176 + decrypted[174] + decrypted[175 + decrypted[174]]
|
||
)
|
||
),
|
||
featureSettingParams: Array.from(
|
||
decrypted.slice(176 + decrypted[174] + decrypted[175 + decrypted[174]])
|
||
),
|
||
lockConfig
|
||
})
|
||
characteristicValueCallback({
|
||
code: decrypted[2],
|
||
data: { lockConfig }
|
||
})
|
||
console.log('获取锁状态成功', that.currentLockInfo.lockConfig)
|
||
} else {
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
}
|
||
break
|
||
case cmdIds.getWifiList:
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
break
|
||
case cmdIds.wifiList:
|
||
const wifiList = []
|
||
for (let i = 0; i < decrypted[3]; i++) {
|
||
wifiList.push({
|
||
SSID: that.uint8ArrayToString(decrypted.slice(4 + 33 * i, 4 + 33 * i + 32)),
|
||
rssi: decrypted[33 + 33 * i]
|
||
})
|
||
}
|
||
uni.$emit('wifiList', {
|
||
status: decrypted[2],
|
||
wifiList
|
||
})
|
||
break
|
||
case cmdIds.distributionNetwork:
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
break
|
||
case cmdIds.distributionNetworkResult:
|
||
uni.$emit('distributionNetworkResult', {
|
||
status: decrypted[2]
|
||
})
|
||
break
|
||
case cmdIds.addUser:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(42, 46)
|
||
})
|
||
if (decrypted[46] === 0) {
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
lockUserNo: decrypted[47] * 256 + decrypted[48]
|
||
})
|
||
}
|
||
console.log('添加用户结果', decrypted[46], that.currentLockInfo.token)
|
||
characteristicValueCallback({
|
||
code: decrypted[46]
|
||
})
|
||
break
|
||
case cmdIds.expandCmd:
|
||
const subCmdId = decrypted[3]
|
||
switch (subCmdId) {
|
||
case subCmdIds.resetLockPassword:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(5, 9)
|
||
})
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
if (decrypted[2] === 0) {
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
encrpyKey: decrypted.slice(9, 17)
|
||
})
|
||
}
|
||
break
|
||
case subCmdIds.setLockPassword:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(5, 9)
|
||
})
|
||
characteristicValueCallback({
|
||
code: decrypted[2],
|
||
data: {
|
||
no: decrypted[9] * 256 + decrypted[10],
|
||
status: decrypted[11]
|
||
}
|
||
})
|
||
break
|
||
case subCmdIds.weChatTickets:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(5, 9)
|
||
})
|
||
if (decrypted[2] === 0) {
|
||
characteristicValueCallback({
|
||
code: decrypted[9]
|
||
})
|
||
} else {
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
}
|
||
break
|
||
case subCmdIds.registerCard:
|
||
case subCmdIds.registerRemote:
|
||
case subCmdIds.registerPalmVein:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(5, 9)
|
||
})
|
||
characteristicValueCallback({
|
||
code: decrypted[2],
|
||
data: {
|
||
status: decrypted[9]
|
||
}
|
||
})
|
||
break
|
||
case subCmdIds.registerFingerprint:
|
||
case subCmdIds.registerFace:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(5, 9)
|
||
})
|
||
characteristicValueCallback({
|
||
code: decrypted[2],
|
||
data: {
|
||
maxProcess: decrypted[11]
|
||
}
|
||
})
|
||
break
|
||
case subCmdIds.registerCardConfirm:
|
||
uni.$emit('registerCardConfirm', {
|
||
status: decrypted[5],
|
||
cardNumber: decrypted[6] * 256 + decrypted[7]
|
||
})
|
||
break
|
||
case subCmdIds.registerFingerprintConfirm:
|
||
uni.$emit('registerFingerprintConfirm', {
|
||
status: decrypted[5],
|
||
fingerprintNumber: decrypted[6] * 256 + decrypted[7]
|
||
})
|
||
break
|
||
case subCmdIds.registerFaceConfirm:
|
||
uni.$emit('registerFaceConfirm', {
|
||
status: decrypted[5],
|
||
faceNumber: decrypted[6] * 256 + decrypted[7]
|
||
})
|
||
break
|
||
case subCmdIds.registerRemoteConfirm:
|
||
uni.$emit('registerRemoteConfirm', {
|
||
status: decrypted[5],
|
||
remoteNumber: decrypted[6] * 256 + decrypted[7]
|
||
})
|
||
break
|
||
case subCmdIds.registerPalmVeinConfirm:
|
||
uni.$emit('registerPalmVeinConfirm', {
|
||
status: decrypted[5],
|
||
palmVeinNumber: decrypted[6] * 256 + decrypted[7]
|
||
})
|
||
break
|
||
case subCmdIds.registerFingerprintProcess:
|
||
uni.$emit('registerFingerprintProcess', {
|
||
status: decrypted[5],
|
||
process: decrypted[6]
|
||
})
|
||
break
|
||
case subCmdIds.registerFaceProcess:
|
||
uni.$emit('registerFaceProcess', {
|
||
status: decrypted[5],
|
||
process: decrypted[6]
|
||
})
|
||
break
|
||
case subCmdIds.syncRecord:
|
||
if (decrypted[2] === 0 && decrypted[6] > 0) {
|
||
const records = []
|
||
const count = decrypted[6] || 0
|
||
for (let i = 0; i < count; i++) {
|
||
let password = decrypted.slice(14 + 17 * i, 14 + 17 * i + 10)
|
||
if (password.every(item => item === 0)) {
|
||
password = null
|
||
} else {
|
||
password = this.uint8ArrayToString(password)
|
||
}
|
||
const record = {
|
||
type: decrypted[7 + 17 * i],
|
||
user: decrypted[8 + 17 * i] * 256 + decrypted[9 + 17 * i],
|
||
date: this.arrayToTimestamp(decrypted.slice(10 + 17 * i, 14 + 17 * i)) * 1000,
|
||
success: 1,
|
||
password
|
||
}
|
||
records.push(record)
|
||
}
|
||
const { code, message } = await uploadRecordRequest({
|
||
records,
|
||
lockId: this.currentLockInfo.lockId
|
||
})
|
||
characteristicValueCallback({ code, data: { count }, message })
|
||
} else {
|
||
characteristicValueCallback({ code: decrypted[2] })
|
||
}
|
||
break
|
||
case subCmdIds.updateAdminPassword:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(5, 9)
|
||
})
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
break
|
||
case subCmdIds.updateSetting:
|
||
// that.updateCurrentLockInfo({
|
||
// ...that.currentLockInfo,
|
||
// token: decrypted.slice(5, 9)
|
||
// })
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
break
|
||
case subCmdIds.updateSettingWithParams:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(5, 9)
|
||
})
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
break
|
||
default:
|
||
break
|
||
}
|
||
break
|
||
case cmdIds.openDoor:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(2, 6),
|
||
electricQuantity: decrypted[7],
|
||
electricQuantityStandby: decrypted[9]
|
||
})
|
||
console.log('开门', decrypted[6], that.currentLockInfo.token)
|
||
log.info({
|
||
code: decrypted[6],
|
||
message: `锁端返回状态码`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
characteristicValueCallback({
|
||
code: decrypted[6]
|
||
})
|
||
if (decrypted[6] === 0) {
|
||
log.info({
|
||
code: decrypted[6],
|
||
message: `开门成功`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
updateElectricQuantityRequest({
|
||
lockId: that.currentLockInfo.lockId,
|
||
electricQuantity: decrypted[7],
|
||
electricQuantityStandby: decrypted[9]
|
||
}).then(res => {
|
||
if (res.code === 0) {
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
electricQuantityDate: res.data.electricQuantityDate
|
||
})
|
||
}
|
||
})
|
||
reportOpenDoorRequest({
|
||
lockId: that.currentLockInfo.lockId,
|
||
keyId: that.keyId
|
||
}).then(res => {
|
||
console.log('上报开门结果', res)
|
||
})
|
||
updateTimezoneOffsetRequest({
|
||
timezoneOffset: new Date().getTimezoneOffset() * 60
|
||
}).then(res => {
|
||
console.log('上报时区结果', res)
|
||
})
|
||
}
|
||
break
|
||
case cmdIds.calibrationTime:
|
||
characteristicValueCallback({
|
||
code: decrypted[2]
|
||
})
|
||
break
|
||
case cmdIds.lockPasswordList:
|
||
case cmdIds.lockCardList:
|
||
case cmdIds.lockFingerprintList:
|
||
case cmdIds.lockFaceList:
|
||
case cmdIds.lockPalmVeinList:
|
||
case cmdIds.lockRemoteList:
|
||
case cmdIds.lockSettingList:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(3, 7)
|
||
})
|
||
let data
|
||
if (cmdId === cmdIds.lockSettingList) {
|
||
data = {
|
||
list: decrypted.slice(7, length)
|
||
}
|
||
} else {
|
||
data = {
|
||
page: decrypted[7],
|
||
size: decrypted[8],
|
||
list: decrypted.slice(9, length)
|
||
}
|
||
}
|
||
characteristicValueCallback({
|
||
code: decrypted[2],
|
||
data
|
||
})
|
||
break
|
||
default:
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
token: decrypted.slice(2, 6)
|
||
})
|
||
console.log('默认结果', decrypted[6], that.currentLockInfo.token)
|
||
characteristicValueCallback({
|
||
code: decrypted[6]
|
||
})
|
||
break
|
||
}
|
||
}
|
||
},
|
||
// 监听蓝牙设备特征值改变
|
||
onBluetoothCharacteristicValueChange() {
|
||
const that = this
|
||
// 完整数据
|
||
let completeArray
|
||
// 完整内容数据长度
|
||
let length
|
||
console.log('开始监听特征值改变')
|
||
uni.onBLECharacteristicValueChange(function (res) {
|
||
if (res.deviceId === that.currentLockInfo.deviceId) {
|
||
let binaryData = new Uint8Array(res.value)
|
||
if (
|
||
binaryData[0] === 0xef &&
|
||
binaryData[1] === 0x01 &&
|
||
binaryData[2] === 0xee &&
|
||
binaryData[3] === 0x02
|
||
) {
|
||
length = binaryData[8] * 256 + binaryData[9]
|
||
if (length + 14 > binaryData.length) {
|
||
completeArray = binaryData
|
||
} else {
|
||
that.parsingCharacteristicValue(binaryData)
|
||
}
|
||
} else if (completeArray) {
|
||
const combinedArray = new Uint8Array(completeArray.length + binaryData.length)
|
||
combinedArray.set(completeArray, 0)
|
||
combinedArray.set(binaryData, completeArray.length)
|
||
completeArray = combinedArray
|
||
if (length + 14 === completeArray.length) {
|
||
that.parsingCharacteristicValue(completeArray)
|
||
completeArray = null
|
||
}
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 开始搜索蓝牙设备
|
||
getBluetoothDevices() {
|
||
const that = this
|
||
if (this.bluetoothStatus !== 0) {
|
||
console.log('搜索未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return
|
||
}
|
||
this.deviceList = []
|
||
uni.startBluetoothDevicesDiscovery({
|
||
success() {
|
||
setTimeout(() => {
|
||
that.searchBluetoothDevices()
|
||
}, 300)
|
||
},
|
||
async fail(res) {
|
||
console.log('开始搜索失败', res)
|
||
if (res.errno === 1509008) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '安卓手机蓝牙功能需要定位权限,请前往设置开启微信的定位权限后再试',
|
||
showCancel: false,
|
||
success(res) {
|
||
if (res.confirm) {
|
||
uni.openAppAuthorizeSetting({
|
||
success(res) {
|
||
console.log(res)
|
||
}
|
||
})
|
||
}
|
||
uni.navigateBack()
|
||
}
|
||
})
|
||
}
|
||
if (res.errCode === 10000) {
|
||
// 重新初始化蓝牙适配器
|
||
await that.initBluetooth()
|
||
that.getBluetoothDevices()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 定时查询蓝牙设备
|
||
searchBluetoothDevices() {
|
||
const that = this
|
||
if (this.bluetoothStatus !== 0) {
|
||
console.log('搜索未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return
|
||
}
|
||
timer = setInterval(() => {
|
||
uni.getBluetoothDevices({
|
||
success(res) {
|
||
searchNumber--
|
||
if (searchNumber === 0 && searchTipFlag) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content:
|
||
'长时间未搜索到任何设备,请确认微信的附近设备权限开启后再试(鸿蒙系统在设置-隐私-定位服务中开启位置信息权限)',
|
||
showCancel: false,
|
||
success() {
|
||
uni.openAppAuthorizeSetting({
|
||
success(res) {
|
||
console.log(res)
|
||
}
|
||
})
|
||
uni.navigateBack()
|
||
}
|
||
})
|
||
}
|
||
const deviceList = res.devices
|
||
if (deviceList.length !== 0) {
|
||
searchTipFlag = false
|
||
}
|
||
that.deviceList = []
|
||
for (let i = 0; i < deviceList.length; i++) {
|
||
if (deviceList[i]?.advertisServiceUUIDs) {
|
||
const uuid = deviceList[i]?.advertisServiceUUIDs[0]
|
||
if (uuid && uuid.slice(2, 8) === '758824' && uuid.slice(30, 32) === '00') {
|
||
that.deviceList.push(deviceList[i])
|
||
}
|
||
if (uuid && uuid.slice(0, 2) === '75' && uuid.slice(4, 6) === '00') {
|
||
that.deviceList.push(deviceList[i])
|
||
}
|
||
}
|
||
}
|
||
// console.log('设备列表', that.deviceList)
|
||
},
|
||
async fail(res) {
|
||
console.log('获取设备列表失败', res)
|
||
if (res.errCode === 10000) {
|
||
// 重新初始化蓝牙适配器
|
||
await that.initBluetooth()
|
||
}
|
||
}
|
||
})
|
||
}, 1000)
|
||
},
|
||
// 停止搜索蓝牙设备
|
||
stopGetBluetoothDevices() {
|
||
searchNumber = 10
|
||
searchTipFlag = true
|
||
clearInterval(timer)
|
||
uni.stopBluetoothDevicesDiscovery()
|
||
},
|
||
// 蓝牙状态提示
|
||
async getBluetoothStatus() {
|
||
if (this.bluetoothStatus === 1) {
|
||
const initResult = await this.initBluetooth()
|
||
if (!initResult) {
|
||
// #ifdef MP-WEIXIN
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '蓝牙尚未打开,请先打开蓝牙',
|
||
showCancel: false,
|
||
success(res) {
|
||
if (res.confirm) {
|
||
wx.openSystemBluetoothSetting({
|
||
success(res) {
|
||
console.log(res)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
// #endif
|
||
// #ifdef APP-PLUS
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '蓝牙尚未打开,请先打开蓝牙',
|
||
showCancel: false,
|
||
success(res) {
|
||
if (res.confirm) {
|
||
// #ifdef APP-ANDROID
|
||
const main = plus.android.runtimeMainActivity()
|
||
const Intent = plus.android.importClass('android.content.Intent')
|
||
const BluetoothAdapter = plus.android.importClass(
|
||
'android.bluetooth.BluetoothAdapter'
|
||
)
|
||
const intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
|
||
main.startActivity(intent)
|
||
// #endif
|
||
}
|
||
}
|
||
})
|
||
// #endif
|
||
}
|
||
} else if (this.bluetoothStatus === 2 || this.bluetoothStatus === 3) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '小程序蓝牙功能被禁用,请打开小程序蓝牙权限',
|
||
showCancel: false,
|
||
confirmText: '去设置',
|
||
success(res) {
|
||
if (res.confirm) {
|
||
uni.openSetting()
|
||
}
|
||
}
|
||
})
|
||
}
|
||
},
|
||
// 检查小程序设置
|
||
checkSetting() {
|
||
const that = this
|
||
return new Promise(resolve => {
|
||
// #ifdef MP-WEIXIN
|
||
uni.getSetting({
|
||
async success(res) {
|
||
const bluetooth = res.authSetting['scope.bluetooth']
|
||
if (that.bluetoothStatus === -1) {
|
||
if (bluetooth !== false) {
|
||
that.bluetoothStatus = 0
|
||
} else {
|
||
that.bluetoothStatus = 2
|
||
}
|
||
} else if (that.bluetoothStatus === 0 && bluetooth === false) {
|
||
that.bluetoothStatus = 2
|
||
} else if (that.bluetoothStatus === 1 && bluetooth === false) {
|
||
that.bluetoothStatus = 3
|
||
} else if (that.bluetoothStatus === 2 && bluetooth !== false) {
|
||
that.bluetoothStatus = 0
|
||
await that.initBluetooth()
|
||
} else if (that.bluetoothStatus === 3 && bluetooth !== false) {
|
||
that.bluetoothStatus = 1
|
||
}
|
||
console.log('蓝牙权限', bluetooth, that.bluetoothStatus)
|
||
resolve(bluetooth)
|
||
},
|
||
fail() {
|
||
resolve(false)
|
||
}
|
||
})
|
||
// #endif
|
||
// #ifdef APP-PLUS
|
||
resolve(true)
|
||
// #endif
|
||
resolve(false)
|
||
})
|
||
},
|
||
// 连接蓝牙设备+获取设备服务+获取设备特征值
|
||
connectBluetoothDevice(number = 0) {
|
||
const that = this
|
||
return new Promise(resolve => {
|
||
if (that.bluetoothStatus !== 0) {
|
||
console.log('连接未执行', that.bluetoothStatus)
|
||
that.getBluetoothStatus()
|
||
resolve(false)
|
||
return
|
||
}
|
||
uni.createBLEConnection({
|
||
deviceId: that.currentLockInfo.deviceId,
|
||
timeout: 10000,
|
||
success(res) {
|
||
console.log('连接成功', res)
|
||
// 获取设备服务
|
||
const executeBluetoothOperation = () => {
|
||
uni.getBLEDeviceServices({
|
||
deviceId: that.currentLockInfo.deviceId,
|
||
success(res) {
|
||
let serviceId
|
||
for (let i = 0; i < res.services.length; i++) {
|
||
if (res.services[i].uuid.indexOf('FFF0') !== -1) {
|
||
serviceId = res.services[i].uuid
|
||
}
|
||
}
|
||
|
||
// 获取设备对应服务的特征值
|
||
uni.getBLEDeviceCharacteristics({
|
||
deviceId: that.currentLockInfo.deviceId,
|
||
serviceId,
|
||
success(res) {
|
||
let notifyCharacteristicId
|
||
let writeCharacteristicId
|
||
for (let i = 0; i < res.characteristics.length; i++) {
|
||
const characteristic = res.characteristics[i]
|
||
if (characteristic.properties.notify) {
|
||
notifyCharacteristicId = characteristic.uuid
|
||
}
|
||
if (characteristic.properties.write) {
|
||
writeCharacteristicId = characteristic.uuid
|
||
}
|
||
}
|
||
that.updateCurrentLockInfo({
|
||
...that.currentLockInfo,
|
||
serviceId,
|
||
notifyCharacteristicId,
|
||
writeCharacteristicId
|
||
})
|
||
that.notifyBluetoothCharacteristicValueChange()
|
||
resolve(true)
|
||
},
|
||
fail(res) {
|
||
if (res.errCode === 10006) {
|
||
uni.showToast({
|
||
title: '连接失败,请靠近设备并保持设备处于唤醒状态',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
console.log('获取设备特征值失败', res)
|
||
resolve(false)
|
||
}
|
||
})
|
||
},
|
||
fail(res) {
|
||
if (res.errCode === 10006) {
|
||
uni.showToast({
|
||
title: '连接失败,请靠近设备并保持设备处于唤醒状态',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
console.log('获取设备服务失败', res)
|
||
resolve(false)
|
||
}
|
||
})
|
||
}
|
||
|
||
// #ifdef APP-PLUS
|
||
setTimeout(executeBluetoothOperation, 800)
|
||
// #endif
|
||
|
||
// #ifdef MP
|
||
executeBluetoothOperation()
|
||
// #endif
|
||
},
|
||
async fail(res) {
|
||
console.log('连接失败', res)
|
||
if (res.errno === 1509007) {
|
||
resolve(true)
|
||
return
|
||
}
|
||
// #ifdef MP
|
||
if (res.errno === 1509001 && number < 1) {
|
||
// 超时直接返回
|
||
resolve(false)
|
||
return
|
||
}
|
||
// #endif
|
||
// #ifdef APP-PLUS
|
||
if (res.code === 10012 && number < 1) {
|
||
// 超时直接返回
|
||
resolve(false)
|
||
return
|
||
}
|
||
// #endif
|
||
if (number < 1) {
|
||
// 重新连接
|
||
resolve(await that.connectBluetoothDevice(number + 1))
|
||
}
|
||
}
|
||
})
|
||
})
|
||
},
|
||
// 更新当前锁信息
|
||
updateCurrentLockInfo(lockInfo) {
|
||
console.log('更新当前锁信息', lockInfo)
|
||
this.currentLockInfo = lockInfo
|
||
},
|
||
// 更新当前锁设置信息
|
||
updateCurrentLockSetting(lockSetting) {
|
||
console.log('更新当前锁设置信息', lockSetting)
|
||
this.currentLockSetting = lockSetting
|
||
},
|
||
// 订阅设备特征值改变
|
||
notifyBluetoothCharacteristicValueChange() {
|
||
const that = this
|
||
uni.notifyBLECharacteristicValueChange({
|
||
state: true,
|
||
deviceId: that.currentLockInfo.deviceId,
|
||
serviceId: that.currentLockInfo.serviceId,
|
||
characteristicId: that.currentLockInfo.notifyCharacteristicId,
|
||
success(res) {
|
||
console.log('订阅成功', res)
|
||
},
|
||
fail(res) {
|
||
console.log('订阅失败', res)
|
||
}
|
||
})
|
||
},
|
||
// 断开蓝牙连接
|
||
closeBluetoothConnection() {
|
||
const that = this
|
||
if (that.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN) {
|
||
uni.closeBLEConnection({
|
||
deviceId: that.currentLockInfo.deviceId,
|
||
success(res) {
|
||
console.log('断开连接成功', res)
|
||
},
|
||
fail(res) {
|
||
console.log('断开连接失败', res)
|
||
}
|
||
})
|
||
}
|
||
},
|
||
// 周数组转换
|
||
convertWeekdaysToNumber(weekDay) {
|
||
let weekStr = '00000000'
|
||
|
||
// eslint-disable-next-line no-restricted-syntax
|
||
for (const day of weekDay) {
|
||
const index = day % 7 // 将周日的索引转换为0
|
||
weekStr = weekStr.substring(0, index) + '1' + weekStr.substring(index + 1)
|
||
}
|
||
|
||
// 倒序 weekStr
|
||
weekStr = weekStr.split('').reverse().join('')
|
||
|
||
return parseInt(weekStr, 2)
|
||
},
|
||
// 查找设备并连接
|
||
async searchAndConnectDevice() {
|
||
const that = this
|
||
let timer1
|
||
let timer2
|
||
return new Promise(resolve => {
|
||
uni.startBluetoothDevicesDiscovery({
|
||
success() {
|
||
let searchFlag = false
|
||
timer2 = setTimeout(async () => {
|
||
uni.stopBluetoothDevicesDiscovery()
|
||
clearInterval(timer1)
|
||
if (!searchFlag) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content:
|
||
'长时间未搜索到任何设备,请确认微信的附近设备权限开启后再试(鸿蒙系统在设置-隐私-定位服务中开启位置信息权限)',
|
||
showCancel: false,
|
||
success() {
|
||
uni.openAppAuthorizeSetting({
|
||
success(res) {
|
||
console.log(res)
|
||
}
|
||
})
|
||
}
|
||
})
|
||
resolve({ code: -22 })
|
||
} else {
|
||
resolve({ code: -4 })
|
||
}
|
||
}, 10500)
|
||
timer1 = setInterval(() => {
|
||
uni.getBluetoothDevices({
|
||
success(res) {
|
||
const deviceList = res.devices
|
||
if (searchFlag === false && res.devices.length > 0) {
|
||
searchFlag = true
|
||
}
|
||
for (let i = 0; i < deviceList.length; i++) {
|
||
if (deviceList[i]?.name === that.currentLockInfo.name) {
|
||
const uuid = deviceList[i]?.advertisServiceUUIDs[0]
|
||
if (uuid && uuid.slice(2, 8) === '758824') {
|
||
console.log('设备UUID', uuid, uuid.slice(2, 8), uuid.slice(30, 32))
|
||
} else if (uuid && uuid.slice(0, 2) === '75') {
|
||
console.log('设备UUID', uuid, uuid.slice(2, 8), uuid.slice(4, 6))
|
||
}
|
||
if (
|
||
uuid &&
|
||
uuid.slice(2, 8) === '758824' &&
|
||
(uuid.slice(30, 32) === '01' ||
|
||
that.bindedDeviceNameList.includes(that.currentLockInfo.name))
|
||
) {
|
||
uni.stopBluetoothDevicesDiscovery()
|
||
clearTimeout(timer2)
|
||
clearInterval(timer1)
|
||
resolve({
|
||
code: 0,
|
||
data: {
|
||
deviceId: deviceList[i].deviceId
|
||
}
|
||
})
|
||
break
|
||
} else if (
|
||
uuid &&
|
||
uuid.slice(2, 8) === '758824' &&
|
||
uuid.slice(30, 32) === '00'
|
||
) {
|
||
uni.stopBluetoothDevicesDiscovery()
|
||
clearTimeout(timer2)
|
||
clearInterval(timer1)
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '锁已被重置,请重新绑定',
|
||
icon: 'none'
|
||
})
|
||
resolve({
|
||
code: -2
|
||
})
|
||
break
|
||
} else if (uuid && uuid.slice(0, 2) === '75' && uuid.slice(4, 6) === '01') {
|
||
uni.stopBluetoothDevicesDiscovery()
|
||
clearTimeout(timer2)
|
||
clearInterval(timer1)
|
||
resolve({
|
||
code: 0,
|
||
data: {
|
||
deviceId: deviceList[i].deviceId
|
||
}
|
||
})
|
||
break
|
||
} else if (uuid && uuid.slice(0, 2) === '75' && uuid.slice(4, 6) === '00') {
|
||
uni.stopBluetoothDevicesDiscovery()
|
||
clearTimeout(timer2)
|
||
clearInterval(timer1)
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '锁已被重置,请重新绑定',
|
||
icon: 'none'
|
||
})
|
||
resolve({
|
||
code: -2
|
||
})
|
||
break
|
||
} else {
|
||
uni.stopBluetoothDevicesDiscovery()
|
||
clearTimeout(timer2)
|
||
clearInterval(timer1)
|
||
resolve({
|
||
code: -3
|
||
})
|
||
break
|
||
}
|
||
}
|
||
}
|
||
},
|
||
async fail(res) {
|
||
console.log('获取设备列表失败', res)
|
||
if (res.errCode === 10000) {
|
||
// 重新初始化蓝牙适配器
|
||
await that.initBluetooth()
|
||
}
|
||
}
|
||
})
|
||
}, 1000)
|
||
},
|
||
async fail(res) {
|
||
console.log('开始搜索失败', res)
|
||
if (res.errCode === 10000) {
|
||
// 重新初始化蓝牙适配器
|
||
await that.initBluetooth()
|
||
that.searchAndConnectDevice()
|
||
} else if (res.errno === 1509008) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '安卓手机蓝牙功能需要定位权限,请前往设置开启微信的定位权限后再试',
|
||
showCancel: false,
|
||
success(res) {
|
||
if (res.confirm) {
|
||
uni.openAppAuthorizeSetting({
|
||
success(res) {
|
||
console.log(res)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
resolve({
|
||
code: -23
|
||
})
|
||
} else {
|
||
resolve({
|
||
code: -1
|
||
})
|
||
}
|
||
}
|
||
})
|
||
})
|
||
},
|
||
// 检查是否已添加为用户
|
||
async checkLockUser(flag = false) {
|
||
console.log('检查是否已添加为用户', this.currentLockInfo.lockUserNo)
|
||
if (this.currentLockInfo.lockUserNo === 0 || flag) {
|
||
const timestamp = parseInt(new Date().getTime() / 1000, 10)
|
||
const password = (Math.floor(Math.random() * 900000) + 100000).toString()
|
||
console.log('用户未添加,开始添加用户')
|
||
const addUserParams = {
|
||
name: this.currentLockInfo.name,
|
||
keyId: this.keyId,
|
||
authUid: this.currentLockInfo.senderUserId.toString(),
|
||
uid: this.currentLockInfo.uid.toString(),
|
||
openMode: 1,
|
||
keyType: 0,
|
||
startDate:
|
||
this.currentLockInfo.startDate === 0
|
||
? timestamp
|
||
: parseInt(this.currentLockInfo.startDate / 1000, 10),
|
||
expireDate:
|
||
this.currentLockInfo.endDate === 0
|
||
? 0xffffffff
|
||
: parseInt(this.currentLockInfo.endDate / 1000, 10),
|
||
useCountLimit: this.currentLockInfo.keyType === 3 ? 1 : 0xffff,
|
||
isRound: this.currentLockInfo.keyType === 4 ? 1 : 0,
|
||
weekRound:
|
||
this.currentLockInfo.keyType === 4
|
||
? this.convertWeekdaysToNumber(this.currentLockInfo.weekDays)
|
||
: 0,
|
||
startHour:
|
||
this.currentLockInfo.keyType === 4
|
||
? new Date(this.currentLockInfo.startDate).getHours()
|
||
: 0,
|
||
startMin:
|
||
this.currentLockInfo.keyType === 4
|
||
? new Date(this.currentLockInfo.startDate).getMinutes()
|
||
: 0,
|
||
endHour:
|
||
this.currentLockInfo.keyType === 4
|
||
? new Date(this.currentLockInfo.endDate).getHours()
|
||
: 0,
|
||
endMin:
|
||
this.currentLockInfo.keyType === 4
|
||
? new Date(this.currentLockInfo.endDate).getMinutes()
|
||
: 0,
|
||
role: Number(this.currentLockInfo.keyRight),
|
||
password
|
||
}
|
||
const { code: addUserCode } = await this.addLockUser(addUserParams)
|
||
console.log('添加用户蓝牙结果', addUserCode, addUserParams)
|
||
if (addUserCode === 0) {
|
||
const { code } = await updateLockUserNoRequest({
|
||
keyId: this.keyId,
|
||
lockUserNo: this.currentLockInfo.lockUserNo
|
||
})
|
||
console.log('添加用户请求结果', code)
|
||
return true
|
||
}
|
||
if (addUserCode === 0x0c) {
|
||
console.log('用户达上限,开始清理用户')
|
||
const { code: requestCode, data: requestData } = await getUserNoListRequest({
|
||
lockId: this.currentLockInfo.lockId
|
||
})
|
||
console.log('获取用户列表请求结果', requestCode, requestData)
|
||
if (requestCode !== 0) return false
|
||
const userNoList = requestData.userNos
|
||
const { code: cleanCode } = await this.cleanLockUser({
|
||
name: this.currentLockInfo.name,
|
||
keyId: this.keyId,
|
||
authUid: this.currentLockInfo.senderUserId.toString(),
|
||
uid: this.currentLockInfo.uid.toString(),
|
||
userNoList
|
||
})
|
||
console.log('清理用户蓝牙结果', cleanCode)
|
||
if (cleanCode === 0) {
|
||
return await this.checkLockUser()
|
||
}
|
||
return false
|
||
}
|
||
return addUserCode === 0x0f
|
||
}
|
||
return true
|
||
},
|
||
uint8ArrayToHex(uint8Array) {
|
||
return Array.from(uint8Array)
|
||
.map(b => b.toString(16).padStart(2, '0'))
|
||
.join('')
|
||
},
|
||
hexToArray(hexString) {
|
||
const result = []
|
||
for (let i = 0; i < hexString.length; i += 2) {
|
||
result.push(parseInt(hexString.slice(i, i + 2), 16))
|
||
}
|
||
return result
|
||
},
|
||
// 写入特征值
|
||
async transportMessage(binaryData) {
|
||
const that = this
|
||
|
||
if (that.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN) {
|
||
const content = that.uint8ArrayToHex(binaryData)
|
||
const { code, data, message } = await passthrough({
|
||
request_method: 'POST',
|
||
request_uri: '/api/v1/tencentYun/CallDeviceActionSync',
|
||
post_args: {
|
||
lockId: that.currentLockInfo.lockId,
|
||
actionId: 'starcloud_action',
|
||
len: content.length,
|
||
content
|
||
}
|
||
})
|
||
|
||
if (code === 0) {
|
||
if (data.Status === 'action execute success!') {
|
||
if (data.OutputParams.result === '') {
|
||
characteristicValueCallback({
|
||
code: 0,
|
||
message: `成功,${data.Status}`
|
||
})
|
||
} else {
|
||
const params = that.hexToArray(data.OutputParams.result)
|
||
console.log('转换后的数据', params)
|
||
that.parsingCharacteristicValue(params)
|
||
}
|
||
} else {
|
||
uni.showToast({
|
||
title: `命令下发失败,${data.Status}`,
|
||
icon: 'none'
|
||
})
|
||
characteristicValueCallback({
|
||
code: -10,
|
||
message: `命令下发失败,${data.Status}`
|
||
})
|
||
}
|
||
} else {
|
||
characteristicValueCallback({
|
||
code,
|
||
message
|
||
})
|
||
}
|
||
} else {
|
||
console.log(
|
||
'设备ID:',
|
||
that.currentLockInfo.deviceId,
|
||
'设备名称:',
|
||
that.currentLockInfo.name,
|
||
'私钥:',
|
||
that.currentLockInfo.commKey
|
||
)
|
||
console.log('设备写入数据:', Array.from(binaryData))
|
||
|
||
// 次数
|
||
const count = Math.ceil(binaryData.length / 20)
|
||
for (let i = 0; i < count; i++) {
|
||
const writeData = binaryData.slice(
|
||
i * 20,
|
||
i === count - 1 ? binaryData.length : (i + 1) * 20
|
||
)
|
||
|
||
// #ifdef APP-PLUS
|
||
setTimeout(
|
||
() => {
|
||
uni.writeBLECharacteristicValue({
|
||
deviceId: that.currentLockInfo.deviceId,
|
||
serviceId: that.currentLockInfo.serviceId,
|
||
characteristicId: that.currentLockInfo.writeCharacteristicId,
|
||
value: writeData.buffer,
|
||
fail(res) {
|
||
console.log('写入失败', res)
|
||
}
|
||
})
|
||
},
|
||
(i + 1) * 250
|
||
)
|
||
// #endif
|
||
|
||
// #ifdef MP
|
||
uni.writeBLECharacteristicValue({
|
||
deviceId: that.currentLockInfo.deviceId,
|
||
serviceId: that.currentLockInfo.serviceId,
|
||
characteristicId: that.currentLockInfo.writeCharacteristicId,
|
||
value: writeData.buffer,
|
||
fail(res) {
|
||
console.log('写入失败', res)
|
||
}
|
||
})
|
||
// #endif
|
||
}
|
||
}
|
||
},
|
||
/*
|
||
* 生成包头
|
||
* encryptionType 加密类型 0:明文,1:AES128,2:SM4(事先约定密钥),3:SM4(设备指定密钥)
|
||
* originalLength 原始数据长度
|
||
* */
|
||
createPackageHeader(encryptionType, originalLength) {
|
||
// 头部数据
|
||
let headArray = new Uint8Array(12)
|
||
|
||
// 固定包头
|
||
headArray[0] = 0xef
|
||
headArray[1] = 0x01
|
||
headArray[2] = 0xee
|
||
headArray[3] = 0x02
|
||
|
||
// 包类型 发送
|
||
headArray[4] = 0x01
|
||
|
||
// 包序号
|
||
headArray[5] = this.messageCount / 256
|
||
headArray[6] = this.messageCount % 256
|
||
this.messageCount++
|
||
|
||
// 包标识
|
||
if (encryptionType === 0) {
|
||
headArray[7] = 0x20
|
||
} else if (encryptionType === 2) {
|
||
headArray[7] = 0x22
|
||
} else {
|
||
headArray[7] = 0x23
|
||
}
|
||
console.log('包标识', headArray[7])
|
||
|
||
// 数据长度
|
||
if (encryptionType === 0) {
|
||
headArray[8] = originalLength / 256
|
||
headArray[9] = originalLength % 256
|
||
} else {
|
||
const length = Math.ceil(originalLength / 16) * 16
|
||
headArray[8] = length / 256
|
||
headArray[9] = length % 256
|
||
}
|
||
headArray[10] = originalLength / 256
|
||
headArray[11] = originalLength % 256
|
||
|
||
return headArray
|
||
},
|
||
// 生成包尾 头部数据+内容数据
|
||
createPackageEnd(headArray, contentArray) {
|
||
// 拼接头部和内容
|
||
let mergerArray = new Uint8Array(headArray.length + contentArray.length)
|
||
mergerArray.set(headArray)
|
||
mergerArray.set(contentArray, headArray.length)
|
||
|
||
// crc加密
|
||
const crcResult = crc.crc16kermit(mergerArray)
|
||
|
||
// 拼接crc
|
||
let newArray = new Uint8Array(mergerArray.length + 2)
|
||
newArray.set(mergerArray)
|
||
newArray.set([crcResult / 256, crcResult % 256], mergerArray.length)
|
||
|
||
return newArray
|
||
},
|
||
// 获取公钥
|
||
async getPublicKey(name) {
|
||
// 确认蓝牙状态正常
|
||
if (this.bluetoothStatus !== 0) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (!this.currentLockInfo.connected) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
const headArray = this.createPackageHeader(0, 42)
|
||
const contentArray = new Uint8Array(42)
|
||
|
||
contentArray[0] = cmdIds.getPublicKey / 256
|
||
contentArray[1] = cmdIds.getPublicKey % 256
|
||
|
||
for (let i = 0; i < name.length; i++) {
|
||
contentArray[i + 2] = name.charCodeAt(i)
|
||
}
|
||
|
||
const packageArray = this.createPackageEnd(headArray, contentArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
return this.getResult()
|
||
},
|
||
// 获取私钥
|
||
async getCommKey(name, keyId, authUid, nowTime) {
|
||
// 确认蓝牙状态正常
|
||
if (this.bluetoothStatus !== 0) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (!this.currentLockInfo.connected) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
const length = 2 + 40 + 40 + 20 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(2, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.getCommKey / 256
|
||
contentArray[1] = cmdIds.getCommKey % 256
|
||
|
||
for (let i = 0; i < name.length; i++) {
|
||
contentArray[i + 2] = name.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 42] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < authUid.length; i++) {
|
||
contentArray[i + 82] = authUid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray.set(this.timestampToArray(nowTime), 102)
|
||
|
||
contentArray[106] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
authUid + keyId,
|
||
contentArray.slice(102, 106),
|
||
this.currentLockInfo.publicKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 107)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, contentArray.slice(2, 18), {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
return this.getResult()
|
||
},
|
||
// md5加密
|
||
md5Encrypte(text, token, key) {
|
||
const length = text.length + 4 + 16
|
||
const md5Array = new Uint8Array(length)
|
||
|
||
for (let i = 0; i < text.length; i++) {
|
||
md5Array[i] = text.charCodeAt(i)
|
||
}
|
||
|
||
md5Array.set(token, text.length)
|
||
md5Array.set(key, text.length + 4)
|
||
|
||
const md5Text = md5(md5Array)
|
||
return new Uint8Array(md5Text.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
|
||
},
|
||
// 获取锁状态
|
||
async getLockStatus(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
const { name, uid, nowTime, localTime } = data
|
||
const length = 2 + 40 + 20 + 4 + 4
|
||
const headArray = this.createPackageHeader(3, length)
|
||
|
||
const contentArray = new Uint8Array(length)
|
||
contentArray[0] = cmdIds.getLockStatus / 256
|
||
contentArray[1] = cmdIds.getLockStatus % 256
|
||
for (let i = 0; i < name.length; i++) {
|
||
contentArray[i + 2] = name.charCodeAt(i)
|
||
}
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 42] = uid.charCodeAt(i)
|
||
}
|
||
contentArray.set(this.timestampToArray(nowTime), 62)
|
||
contentArray.set(this.timestampToArray(localTime), 66)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.getLockStatus, data)
|
||
},
|
||
// 获取锁状态
|
||
async getLockStatusInfo(data) {
|
||
// 确认蓝牙状态正常
|
||
if (this.bluetoothStatus !== 0) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (!this.currentLockInfo.connected) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
const { name, uid, nowTime, localTime } = data
|
||
const length = 2 + 40 + 20 + 4 + 4
|
||
const headArray = this.createPackageHeader(3, length)
|
||
|
||
const contentArray = new Uint8Array(length)
|
||
contentArray[0] = cmdIds.getLockStatus / 256
|
||
contentArray[1] = cmdIds.getLockStatus % 256
|
||
for (let i = 0; i < name.length; i++) {
|
||
contentArray[i + 2] = name.charCodeAt(i)
|
||
}
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 42] = uid.charCodeAt(i)
|
||
}
|
||
contentArray.set(this.timestampToArray(nowTime), 62)
|
||
contentArray.set(this.timestampToArray(localTime), 66)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.getLockStatusInfo, data)
|
||
},
|
||
// 获取Wi-Fi列表
|
||
async getWifiList(data) {
|
||
// 确认蓝牙状态正常
|
||
if (this.bluetoothStatus !== 0) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (!this.currentLockInfo.connected) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
const { uid } = data
|
||
const length = 2 + 20
|
||
const headArray = this.createPackageHeader(3, length)
|
||
|
||
const contentArray = new Uint8Array(length)
|
||
contentArray[0] = cmdIds.getWifiList / 256
|
||
contentArray[1] = cmdIds.getWifiList % 256
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 2] = uid.charCodeAt(i)
|
||
}
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.getWifiList, data)
|
||
},
|
||
// 配网
|
||
async distributionNetwork(data) {
|
||
// 确认蓝牙状态正常
|
||
if (this.bluetoothStatus !== 0) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (!this.currentLockInfo.connected) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
const { SSID, password, json } = data
|
||
const length = 2 + 30 + 20 + 2 + json.length
|
||
const headArray = this.createPackageHeader(3, length)
|
||
|
||
const contentArray = new Uint8Array(length)
|
||
contentArray[0] = cmdIds.distributionNetwork / 256
|
||
contentArray[1] = cmdIds.distributionNetwork % 256
|
||
for (let i = 0; i < SSID.length; i++) {
|
||
contentArray[i + 2] = SSID.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < password.length; i++) {
|
||
contentArray[i + 32] = password.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[52] = json.length / 256
|
||
contentArray[53] = json.length % 256
|
||
|
||
for (let i = 0; i < json.length; i++) {
|
||
contentArray[i + 54] = json.charCodeAt(i)
|
||
}
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array',
|
||
padding: length % 16 === 0 ? 'none' : 'pkcs#5'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.distributionNetwork, data)
|
||
},
|
||
// 时间戳转二进制
|
||
timestampToArray(timestamp) {
|
||
const array = new Uint8Array(4)
|
||
array[0] = (timestamp & 0xff000000) >> 24
|
||
array[1] = (timestamp & 0xff0000) >> 16
|
||
array[2] = (timestamp & 0xff00) >> 8
|
||
array[3] = timestamp & 0xff
|
||
return array
|
||
},
|
||
// 二进制转时间戳
|
||
arrayToTimestamp(array) {
|
||
const timestamp = (array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3]
|
||
return timestamp >>> 0
|
||
},
|
||
// 添加用户
|
||
async addLockUser(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
const {
|
||
name,
|
||
authUid,
|
||
uid,
|
||
keyId,
|
||
openMode,
|
||
keyType,
|
||
startDate,
|
||
expireDate,
|
||
useCountLimit,
|
||
isRound,
|
||
weekRound,
|
||
startHour,
|
||
startMin,
|
||
endHour,
|
||
endMin,
|
||
role,
|
||
password
|
||
} = data
|
||
const length =
|
||
2 + 40 + 20 + 40 + 20 + 1 + 1 + 4 + 4 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 20 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.addUser / 256
|
||
contentArray[1] = cmdIds.addUser % 256
|
||
|
||
for (let i = 0; i < name.length; i++) {
|
||
contentArray[i + 2] = name.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < authUid.length; i++) {
|
||
contentArray[i + 42] = authUid.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 62] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 102] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[122] = openMode
|
||
contentArray[123] = keyType
|
||
|
||
contentArray.set(this.timestampToArray(startDate), 124)
|
||
contentArray.set(this.timestampToArray(expireDate), 128)
|
||
|
||
contentArray[132] = useCountLimit / 256
|
||
contentArray[133] = useCountLimit % 256
|
||
|
||
contentArray[134] = isRound
|
||
contentArray[135] = weekRound
|
||
contentArray[136] = startHour
|
||
contentArray[137] = startMin
|
||
contentArray[138] = endHour
|
||
contentArray[139] = endMin
|
||
contentArray[140] = role
|
||
|
||
for (let i = 0; i < password.length; i++) {
|
||
contentArray[i + 141] = password.charCodeAt(i)
|
||
}
|
||
|
||
contentArray.set(this.currentLockInfo.token || this.timestampToArray(startDate), 161)
|
||
|
||
contentArray[165] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
authUid + keyId,
|
||
this.currentLockInfo.token || this.timestampToArray(startDate),
|
||
this.currentLockInfo.publicKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 166)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
this.transportMessage(packageArray, false)
|
||
return this.getResult(this.addLockUser, data)
|
||
},
|
||
// 添加用户
|
||
async bindLock(data) {
|
||
// 确认蓝牙状态正常
|
||
if (this.bluetoothStatus !== 0) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (!this.currentLockInfo.connected) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
const {
|
||
name,
|
||
authUid,
|
||
uid,
|
||
keyId,
|
||
openMode,
|
||
keyType,
|
||
startDate,
|
||
expireDate,
|
||
useCountLimit,
|
||
isRound,
|
||
weekRound,
|
||
startHour,
|
||
startMin,
|
||
endHour,
|
||
endMin,
|
||
role,
|
||
password
|
||
} = data
|
||
const length =
|
||
2 + 40 + 20 + 40 + 20 + 1 + 1 + 4 + 4 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 20 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.addUser / 256
|
||
contentArray[1] = cmdIds.addUser % 256
|
||
|
||
for (let i = 0; i < name.length; i++) {
|
||
contentArray[i + 2] = name.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < authUid.length; i++) {
|
||
contentArray[i + 42] = authUid.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 62] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 102] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[122] = openMode
|
||
contentArray[123] = keyType
|
||
|
||
contentArray.set(this.timestampToArray(startDate), 124)
|
||
contentArray.set(this.timestampToArray(expireDate), 128)
|
||
|
||
contentArray[132] = useCountLimit / 256
|
||
contentArray[133] = useCountLimit % 256
|
||
|
||
contentArray[134] = isRound
|
||
contentArray[135] = weekRound
|
||
contentArray[136] = startHour
|
||
contentArray[137] = startMin
|
||
contentArray[138] = endHour
|
||
contentArray[139] = endMin
|
||
contentArray[140] = role
|
||
|
||
for (let i = 0; i < password.length; i++) {
|
||
contentArray[i + 141] = password.charCodeAt(i)
|
||
}
|
||
|
||
contentArray.set(this.currentLockInfo.token || this.timestampToArray(startDate), 161)
|
||
|
||
contentArray[165] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
authUid + keyId,
|
||
this.currentLockInfo.token || this.timestampToArray(startDate),
|
||
this.currentLockInfo.publicKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 166)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
this.transportMessage(packageArray, false)
|
||
return this.getResult(this.bindLock, data)
|
||
},
|
||
// 获取写入结果
|
||
getResult(request, params) {
|
||
const $user = useUserStore()
|
||
return new Promise(resolve => {
|
||
const getResultTimer = setTimeout(() => {
|
||
log.info({
|
||
code: -1,
|
||
message: `操作失败,蓝牙操作超时`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
resolve({ code: -1 })
|
||
}, 20000)
|
||
characteristicValueCallback = async data => {
|
||
// code 6 token过期,重新获取
|
||
if (data.code === 6) {
|
||
log.info({
|
||
code: 0,
|
||
message: `开门中,更换过期token,开始重试`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
clearTimeout(getResultTimer)
|
||
resolve(await request(params))
|
||
} else {
|
||
clearTimeout(getResultTimer)
|
||
resolve(data)
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 开门
|
||
async openDoor(data) {
|
||
const $user = useUserStore()
|
||
try {
|
||
log.info({
|
||
code: 0,
|
||
message: `开始开门`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
if (this.bluetoothStatus === -1) {
|
||
log.info({
|
||
code: -25,
|
||
message: `开门失败,未知蓝牙状态, ${this.bluetoothStatus}`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else if (this.bluetoothStatus === 1) {
|
||
log.info({
|
||
code: -20,
|
||
message: `开门失败,蓝牙未开启, ${this.bluetoothStatus}`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else if (this.bluetoothStatus === 2) {
|
||
log.info({
|
||
code: -21,
|
||
message: `开门失败,小程序蓝牙权限被禁用, ${this.bluetoothStatus}`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else if (this.bluetoothStatus === 3) {
|
||
log.info({
|
||
code: -26,
|
||
message: `开门失败,蓝牙未开启且小程序蓝牙功能被禁用, ${this.bluetoothStatus}`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
}
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
log.info({
|
||
code: 0,
|
||
message: `开门中,蓝牙权限正常, ${this.bluetoothStatus}`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code === 0) {
|
||
log.info({
|
||
code: searchResult.code,
|
||
message: `开门中,已搜索到设备`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else if (searchResult.code === -1) {
|
||
log.info({
|
||
code: searchResult.code,
|
||
message: `开门失败,搜索失败`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else if (searchResult.code === -2) {
|
||
log.info({
|
||
code: searchResult.code,
|
||
message: `开门失败,锁已被重置`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else if (searchResult.code === -3) {
|
||
log.info({
|
||
code: searchResult.code,
|
||
message: `开门失败,设备已找到但uuid异常`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else if (searchResult.code === -4) {
|
||
log.info({
|
||
code: searchResult.code,
|
||
message: `开门失败,未搜索到操作设备`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else if (searchResult.code === -22) {
|
||
log.info({
|
||
code: searchResult.code,
|
||
message: `开门失败,微信附近设备权限未开启`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else if (searchResult.code === -23) {
|
||
log.info({
|
||
code: searchResult.code,
|
||
message: `开门失败,微信定位权限未开启`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
}
|
||
if (searchResult.code !== 0) {
|
||
return { code: -1 }
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
if (result) {
|
||
log.info({
|
||
code: 0,
|
||
message: `开门中,设备连接成功`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
} else {
|
||
log.info({
|
||
code: -1,
|
||
message: `开门失败,设备连接失败`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
}
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
log.info({
|
||
code: 0,
|
||
message: `开门中,设备已连接`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
log.info({
|
||
code: -1,
|
||
message: `开门失败,用户添加失败`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
log.info({
|
||
code: 0,
|
||
message: `开门中,用户已添加`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
|
||
const { name, uid, openMode, openTime, onlineToken } = data
|
||
const length = 2 + 40 + 20 + 1 + 4 + 4 + 1 + 16 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
|
||
const contentArray = new Uint8Array(length)
|
||
contentArray[0] = cmdIds.openDoor / 256
|
||
contentArray[1] = cmdIds.openDoor % 256
|
||
|
||
for (let i = 0; i < name.length; i++) {
|
||
contentArray[i + 2] = name.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 42] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[62] = openMode
|
||
|
||
contentArray.set(this.timestampToArray(openTime), 63)
|
||
|
||
console.log('开门时token', this.currentLockInfo.token)
|
||
|
||
contentArray.set(this.currentLockInfo.token || this.timestampToArray(openTime), 67)
|
||
|
||
contentArray[71] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
name + uid,
|
||
this.currentLockInfo.token || this.timestampToArray(openTime),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 72)
|
||
|
||
for (let i = 0; i < onlineToken.length; i++) {
|
||
contentArray[i + 88] = onlineToken.charCodeAt(i)
|
||
}
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
log.info({
|
||
code: 0,
|
||
message: `开门中,开始写入`,
|
||
data: {
|
||
lockName: this.currentLockInfo.name,
|
||
lockId: this.currentLockInfo.lockId,
|
||
uid: $user.userInfo.uid,
|
||
nickname: $user.userInfo.nickname,
|
||
mobile: $user.userInfo.mobile,
|
||
email: $user.userInfo.email
|
||
}
|
||
})
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.openDoor, data)
|
||
} catch (e) {
|
||
log.error({
|
||
code: -1,
|
||
error: e,
|
||
message: `开门失败,未知错误`
|
||
})
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
},
|
||
// 清理用户
|
||
async cleanLockUser(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
const { name, authUid, keyId, uid, userNoList } = data
|
||
const length = 2 + 40 + 20 + 40 + 20 + 2 + userNoList.length + 4 + 1 + 16
|
||
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.cleanUser / 256
|
||
contentArray[1] = cmdIds.cleanUser % 256
|
||
|
||
for (let i = 0; i < name.length; i++) {
|
||
contentArray[i + 2] = name.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < authUid.length; i++) {
|
||
contentArray[i + 42] = authUid.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 62] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 102] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[122] = userNoList.length / 256
|
||
contentArray[123] = userNoList.length % 256
|
||
|
||
for (let i = 0; i < userNoList.length; i++) {
|
||
contentArray[i + 124] = userNoList[i]
|
||
}
|
||
|
||
contentArray.set(
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
124 + userNoList.length
|
||
)
|
||
|
||
contentArray[128 + userNoList.length] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
authUid + keyId,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.publicKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 129 + userNoList.length)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.cleanLockUser, data)
|
||
},
|
||
// 恢复出厂设置
|
||
async resetDevice(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
const { name, authUid } = data
|
||
const length = 2 + 40 + 20 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.resetDevice / 256
|
||
contentArray[1] = cmdIds.resetDevice % 256
|
||
|
||
for (let i = 0; i < name.length; i++) {
|
||
contentArray[i + 2] = name.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < authUid.length; i++) {
|
||
contentArray[i + 42] = authUid.charCodeAt(i)
|
||
}
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 62)
|
||
contentArray[66] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
name,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.publicKey
|
||
)
|
||
contentArray.set(md5Array, 67)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.resetDevice, data)
|
||
},
|
||
// 重置开锁密码
|
||
async resetLockPassword(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
const { keyId, uid } = data
|
||
const length = 2 + 1 + 1 + 40 + 20 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.expandCmd / 256
|
||
contentArray[1] = cmdIds.expandCmd % 256
|
||
|
||
// 子命令
|
||
contentArray[2] = subCmdIds.resetLockPassword
|
||
|
||
contentArray[3] = length - 4
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 4] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 44] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 64)
|
||
|
||
contentArray[68] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
keyId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 69)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.resetLockPassword, data)
|
||
},
|
||
// 设置密码
|
||
async setLockPassword(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
const { keyId, uid, pwdNo, operate, isAdmin, pwd, userCountLimit, startTime, endTime } = data
|
||
const length = 2 + 1 + 1 + 40 + 20 + 2 + 1 + 1 + 20 + 2 + 4 + 4 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.expandCmd / 256
|
||
contentArray[1] = cmdIds.expandCmd % 256
|
||
|
||
// 子命令
|
||
contentArray[2] = subCmdIds.setLockPassword
|
||
|
||
contentArray[3] = length - 3
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 4] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 44] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[64] = pwdNo / 256
|
||
contentArray[65] = pwdNo % 256
|
||
|
||
contentArray[66] = operate
|
||
contentArray[67] = isAdmin
|
||
|
||
for (let i = 0; i < pwd.length; i++) {
|
||
contentArray[i + 68] = pwd.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[88] = userCountLimit / 256
|
||
contentArray[89] = userCountLimit % 256
|
||
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 90)
|
||
|
||
contentArray.set(this.timestampToArray(startTime), 94)
|
||
contentArray.set(this.timestampToArray(endTime), 98)
|
||
|
||
contentArray[102] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
keyId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 103)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.setLockPassword, data)
|
||
},
|
||
// 微信票据
|
||
async weChatTickets(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
const { keyId, uid, openId, snTicket } = data
|
||
const length = 2 + 1 + 1 + 40 + 20 + 4 + 2 + openId.length + 2 + snTicket.length + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.expandCmd / 256
|
||
contentArray[1] = cmdIds.expandCmd % 256
|
||
|
||
contentArray[2] = subCmdIds.weChatTickets
|
||
|
||
contentArray[3] = length - 3
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 4] = keyId.charCodeAt(i)
|
||
}
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 44] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 64)
|
||
|
||
contentArray[68] = openId.length / 256
|
||
contentArray[69] = openId.length % 256
|
||
|
||
for (let i = 0; i < openId.length; i++) {
|
||
contentArray[i + 70] = openId.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[70 + openId.length] = snTicket.length / 256
|
||
contentArray[71 + openId.length] = snTicket.length % 256
|
||
|
||
for (let i = 0; i < snTicket.length; i++) {
|
||
contentArray[i + 72 + openId.length] = snTicket.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[72 + openId.length + snTicket.length] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
keyId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 73 + openId.length + snTicket.length)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.weChatTickets, data)
|
||
},
|
||
parseTimeToList(timeString) {
|
||
let timeList = [0, 0, 0, 0]
|
||
|
||
if (timeString.includes(':')) {
|
||
let timeParts = timeString.split(':')
|
||
timeList[2] = parseInt(timeParts[0], 10)
|
||
timeList[3] = parseInt(timeParts[1], 10)
|
||
}
|
||
|
||
return new Uint8Array(timeList)
|
||
},
|
||
// 注册身份认证
|
||
async registerAuthentication(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -21
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
let {
|
||
type,
|
||
keyId,
|
||
uid,
|
||
no,
|
||
operate,
|
||
isAdmin,
|
||
userCountLimit,
|
||
isForce,
|
||
isRound,
|
||
weekDays,
|
||
startDate,
|
||
endDate,
|
||
startTime,
|
||
endTime
|
||
} = data
|
||
|
||
startDate = Math.floor(startDate / 1000)
|
||
endDate = Math.floor(endDate / 1000)
|
||
|
||
const length = 2 + 1 + 1 + 40 + 20 + 2 + 2 + 1 + 1 + 1 + 4 + 1 + 1 + 4 + 4 + 4 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.expandCmd / 256
|
||
contentArray[1] = cmdIds.expandCmd % 256
|
||
|
||
// 子命令
|
||
if (type === 'card') {
|
||
contentArray[2] = subCmdIds.registerCard
|
||
} else if (type === 'fingerprint') {
|
||
contentArray[2] = subCmdIds.registerFingerprint
|
||
} else if (type === 'face') {
|
||
contentArray[2] = subCmdIds.registerFace
|
||
} else if (type === 'remote') {
|
||
contentArray[2] = subCmdIds.registerRemote
|
||
} else if (type === 'palmVein') {
|
||
contentArray[2] = subCmdIds.registerPalmVein
|
||
}
|
||
|
||
contentArray[3] = length - 3
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 4] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 44] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[64] = (no || 0) / 256
|
||
contentArray[65] = (no || 0) % 256
|
||
|
||
contentArray[66] = (userCountLimit || 0xffff) / 256
|
||
contentArray[67] = (userCountLimit || 0xffff) % 256
|
||
|
||
contentArray[68] = operate
|
||
contentArray[69] = isAdmin || 0
|
||
contentArray[70] = isForce || 0
|
||
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 71)
|
||
|
||
contentArray[75] = isRound
|
||
contentArray[76] = this.convertWeekdaysToNumber(weekDays)
|
||
|
||
contentArray.set(this.timestampToArray(startDate), 77)
|
||
contentArray.set(this.timestampToArray(endDate), 81)
|
||
|
||
if (isRound) {
|
||
contentArray.set(this.parseTimeToList(startTime), 85)
|
||
contentArray.set(this.parseTimeToList(endTime), 89)
|
||
} else {
|
||
contentArray.set(new Uint8Array([0, 0, 0, 0]), 85)
|
||
contentArray.set(new Uint8Array([0, 0, 0, 0]), 89)
|
||
}
|
||
|
||
contentArray[93] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
keyId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 94)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.registerAuthentication, data)
|
||
},
|
||
// 注册身份认证取消
|
||
async registerAuthenticationCancel(data) {
|
||
const { type, keyId, uid } = data
|
||
|
||
const length = 2 + 1 + 1 + 40 + 20 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.expandCmd / 256
|
||
contentArray[1] = cmdIds.expandCmd % 256
|
||
|
||
// 子命令
|
||
if (type === 'card') {
|
||
contentArray[2] = subCmdIds.registerCardCancel
|
||
} else if (type === 'fingerprint') {
|
||
contentArray[2] = subCmdIds.registerFingerprintCancel
|
||
} else if (type === 'face') {
|
||
contentArray[2] = subCmdIds.registerFaceCancel
|
||
} else if (type === 'remote') {
|
||
contentArray[2] = subCmdIds.registerRemoteCancel
|
||
} else if (type === 'palmVein') {
|
||
contentArray[2] = subCmdIds.registerPalmVeinCancel
|
||
}
|
||
|
||
contentArray[3] = length - 3
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 4] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 44] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 64)
|
||
|
||
contentArray[68] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
keyId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 69)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.registerAuthenticationCancel, data)
|
||
},
|
||
// 获取操作记录
|
||
async syncRecord(params) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
const { uid, keyId } = params
|
||
|
||
const { code, data, message } = await this.syncSingleRecord({
|
||
uid,
|
||
keyId
|
||
})
|
||
|
||
if (code === 0) {
|
||
if (data?.count === 10) {
|
||
return await this.syncSingleRecord({
|
||
uid,
|
||
keyId
|
||
})
|
||
}
|
||
return { code, data, message }
|
||
}
|
||
return { code, data, message }
|
||
},
|
||
// 获取单次操作记录
|
||
async syncSingleRecord(data) {
|
||
const { keyId, uid } = data
|
||
|
||
const logsCount = 10
|
||
|
||
const timeResult = await getLastRecordTimeRequest({
|
||
lockId: this.currentLockInfo.lockId
|
||
})
|
||
|
||
if (timeResult.code !== 0) {
|
||
return timeResult
|
||
}
|
||
|
||
const operateDate = Math.ceil(timeResult.data.operateDate / 1000)
|
||
const currentDate = Math.ceil(timeResult.data.currentDate / 1000)
|
||
|
||
const length = 2 + 1 + 1 + 40 + 20 + 2 + 4 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
|
||
const contentArray = new Uint8Array(length)
|
||
contentArray[0] = cmdIds.expandCmd / 256
|
||
contentArray[1] = cmdIds.expandCmd % 256
|
||
|
||
// 子命令
|
||
contentArray[2] = subCmdIds.syncRecord
|
||
|
||
contentArray[3] = length - 3
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 4] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 44] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[64] = logsCount / 256
|
||
contentArray[65] = logsCount % 256
|
||
|
||
contentArray.set(this.timestampToArray(operateDate), 66)
|
||
contentArray.set(this.timestampToArray(currentDate), 70)
|
||
|
||
contentArray[74] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
uid + keyId,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.publicKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 75)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.syncSingleRecord, data)
|
||
},
|
||
// 更新管理员密码
|
||
async updateAdminPassword(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -21
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
let { keyId, uid, adminPwd, userCountLimit, startDate, endDate } = data
|
||
|
||
const length = 2 + 1 + 1 + 40 + 20 + 2 + 20 + 2 + 4 + 4 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.expandCmd / 256
|
||
contentArray[1] = cmdIds.expandCmd % 256
|
||
|
||
contentArray[2] = subCmdIds.updateAdminPassword
|
||
|
||
contentArray[3] = length - 3
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 4] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 44] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[64] = 1 / 256
|
||
contentArray[65] = 1 % 256
|
||
|
||
for (let i = 0; i < adminPwd.length; i++) {
|
||
contentArray[i + 66] = adminPwd.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[86] = (userCountLimit || 0xffff) / 256
|
||
contentArray[87] = (userCountLimit || 0xffff) % 256
|
||
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 88)
|
||
|
||
contentArray.set(this.timestampToArray(startDate), 92)
|
||
contentArray.set(this.timestampToArray(endDate), 96)
|
||
|
||
contentArray[100] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
keyId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 101)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.updateAdminPassword, data)
|
||
},
|
||
// 更新设置
|
||
async updateSetting(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -21
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
let { keyId, uid, featureBit, featureEnable, withParams, params } = data
|
||
|
||
let length = 2 + 1 + 1 + 40 + 20 + 4 + 1 + 16
|
||
if (withParams) {
|
||
length += 2 + params.length
|
||
} else {
|
||
length += 2
|
||
}
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.expandCmd / 256
|
||
contentArray[1] = cmdIds.expandCmd % 256
|
||
|
||
contentArray[2] = withParams ? subCmdIds.updateSettingWithParams : subCmdIds.updateSetting
|
||
|
||
contentArray[3] = length - 3
|
||
|
||
for (let i = 0; i < keyId.length; i++) {
|
||
contentArray[i + 4] = keyId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 44] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray[64] = featureBit
|
||
|
||
if (withParams) {
|
||
contentArray[65] = params.length
|
||
contentArray.set(new Uint8Array(params), 66)
|
||
} else {
|
||
contentArray[65] = featureEnable
|
||
}
|
||
|
||
contentArray.set(
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
withParams ? 66 + params.length : 66
|
||
)
|
||
|
||
contentArray[withParams ? 70 + params.length : 70] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
keyId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, withParams ? 71 + params.length : 71)
|
||
console.log('加密前:', Array.from(contentArray))
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.updateSetting, data)
|
||
},
|
||
// 校准时间
|
||
async calibrationTime(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
let { lockId, uid, nowTime } = data
|
||
const length = 2 + 40 + 20 + 4 + 4 + 1 + 16
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
contentArray[0] = cmdIds.calibrationTime / 256
|
||
contentArray[1] = cmdIds.calibrationTime % 256
|
||
|
||
for (let i = 0; i < lockId.length; i++) {
|
||
contentArray[i + 2] = lockId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 42] = uid.charCodeAt(i)
|
||
}
|
||
|
||
contentArray.set(this.timestampToArray(nowTime), 62)
|
||
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 66)
|
||
contentArray[70] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
lockId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 71)
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.calibrationTime, data)
|
||
},
|
||
// 获取锁数据列表
|
||
async getLockDataList(data) {
|
||
// 确认蓝牙状态正常
|
||
if (
|
||
this.bluetoothStatus !== 0 &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
console.log('写入未执行', this.bluetoothStatus)
|
||
this.getBluetoothStatus()
|
||
return {
|
||
code: -21
|
||
}
|
||
}
|
||
|
||
// 确认设备连接正常
|
||
if (
|
||
!this.currentLockInfo.connected &&
|
||
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
|
||
) {
|
||
const searchResult = await this.searchAndConnectDevice()
|
||
if (searchResult.code !== 0) {
|
||
return searchResult
|
||
}
|
||
this.updateCurrentLockInfo({
|
||
...this.currentLockInfo,
|
||
deviceId: searchResult.data.deviceId
|
||
})
|
||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||
const result = await this.connectBluetoothDevice()
|
||
console.log('连接结果', result)
|
||
if (!result) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查是否已添加为用户
|
||
const checkResult = await this.checkLockUser()
|
||
if (!checkResult) {
|
||
return {
|
||
code: -1
|
||
}
|
||
}
|
||
|
||
let { lockId, uid, page, countReq, type } = data
|
||
let length = 2 + 40 + 20 + 4 + 1 + 16
|
||
if (type !== 'setting') {
|
||
length += 2
|
||
}
|
||
const headArray = this.createPackageHeader(3, length)
|
||
const contentArray = new Uint8Array(length)
|
||
|
||
let id
|
||
|
||
if (type === 'password') {
|
||
id = cmdIds.lockPasswordList
|
||
} else if (type === 'card') {
|
||
id = cmdIds.lockCardList
|
||
} else if (type === 'fingerprint') {
|
||
id = cmdIds.lockFingerprintList
|
||
} else if (type === 'face') {
|
||
id = cmdIds.lockFaceList
|
||
} else if (type === 'remote') {
|
||
id = cmdIds.lockRemoteList
|
||
} else if (type === 'palmVein') {
|
||
id = cmdIds.lockPalmVeinList
|
||
} else if (type === 'setting') {
|
||
id = cmdIds.lockSettingList
|
||
}
|
||
|
||
contentArray[0] = id / 256
|
||
contentArray[1] = id % 256
|
||
|
||
for (let i = 0; i < lockId.length; i++) {
|
||
contentArray[i + 2] = lockId.charCodeAt(i)
|
||
}
|
||
|
||
for (let i = 0; i < uid.length; i++) {
|
||
contentArray[i + 42] = uid.charCodeAt(i)
|
||
}
|
||
|
||
if (type !== 'setting') {
|
||
contentArray[62] = page
|
||
contentArray[63] = countReq
|
||
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 64)
|
||
contentArray[68] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
lockId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 69)
|
||
} else {
|
||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 62)
|
||
contentArray[66] = 16
|
||
|
||
const md5Array = this.md5Encrypte(
|
||
lockId + uid,
|
||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||
this.currentLockInfo.signKey
|
||
)
|
||
|
||
contentArray.set(md5Array, 67)
|
||
}
|
||
|
||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||
mode: 'ecb',
|
||
output: 'array'
|
||
})
|
||
|
||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||
this.transportMessage(packageArray)
|
||
|
||
return this.getResult(this.getLockDataList, data)
|
||
}
|
||
}
|
||
})
|