import { defineStore } from 'pinia' import { buildNumber, configs, version } from '@/starCloud/env' import { addCustomPassword, getLockDetail, getLockNetTokenRequest, getOfflinePassword, getServerDatetime, getStarCloudToken, getUserNoListRequest, starCloudCreateUser, updateLockUserNoRequest, updatePassword } from '@/starCloud/api' import { getStorage, setStorage } from '@/starCloud/storage' import { closeBLEConnection, onBLECharacteristicValueChange, Result, searchAndConnectDevice, writeBLECharacteristicValue } from '@/starCloud/basic' import { arrayToTimestamp, convertWeekdaysToNumber, createPackageEnd, md5Encrypt, timestampToArray, uint8ArrayToString } from '@/starCloud/format' import { sm4 } from 'sm-crypto' /** * 锁信息 * @typedef {Object} lockInfo * @property {Number} keyId - 钥匙ID * @property {Number} lockId - 锁ID * @property {String} lockName - 锁名称 * @property {String} lockAlias - 锁别名 * @property {Number} electricQuantity - 电量 * @property {Number} electricQuantityStandby - 备用电量 * @property {Number} electricQuantityDate - 电量更新时间 * @property {String} fwVersion - 固件版本 * @property {String} hwVersion - 硬件版本 * @property {Number} keyType - 钥匙类型 * @property {Number} passageMode - 常开模式 * @property {Number} userType - 用户类型 * @property {Number} startDate - 有效期开始时间 * @property {Number} endDate - 有效期结束时间 * @property {Object} weekDays - 循环周期 * @property {Number} remoteEnable - 是否支持远程开锁:0-未知,1-是,2-否 * @property {Number} faceAuthentication - 是否实名认证:0-未知,1-是,2-否 * @property {Number} lastFaceValidateTime - 最后一次人脸验证时间 * @property {Number} nextFaceValidateTime - 下次人脸验证时间 * @property {Number} keyRight - 是否授权管理员钥匙: 0-未知,1-是,2-否 * @property {Number} keyStatus - 钥匙状态 * @property {Object} bluetooth - 蓝牙 * @property {Number} sendDate - 发送时间 * @property {Number} isLockOwner - 是否是锁主 * @property {Object} lockFeature - 锁特征 * @property {Object} lockSetting - 锁设置 * @property {Number} lockUserNo - 用户编号 * @property {Number} senderUserId - 发送者用户ID * @property {Number} isOnlyManageSelf - 如果是授权管理员此字段区分是否仅管理自己发的钥匙 * @property {Number} restoreCount - 重置次数 * @property {String} model - 模式 */ /** * 锁蓝牙信息 * @typedef {Object} bluetooth * @property {String} bluetoothDeviceId - 设备ID * @property {String} bluetoothDeviceName - 设备名称 * @property {String} publicKey - 公钥 * @property {String} privateKey - 私钥 * @property {String} signKey - 签名密钥 * @property {String} passwordKey - 密码密钥 */ /** * 锁设置信息 * @typedef {Object} lockSetting * @property {Number} appUnlockOnline - 开门是否需要联网 */ /** * 请求返回数据 * @typedef {Object} requestData * @property {String} userNos - 设备ID */ // 命令ID const cmdIds = { // 获取公钥 getPublicKey: 0x3090, // 获取私钥 getCommKey: 0x3091, // 获取锁状态 getLockStatus: 0x3040, // 新增用户 addUser: 0x3001, // 开门 openDoor: 0x3005, // 重置设备 resetDevice: 0x3004, // 清理用户 cleanUser: 0x300C, // 扩展命令 expandCmd: 0x3030 } // 子命令ID const subCmdIds = { // 设置开锁密码 setLockPassword: 3, // 重置开锁密码 resetLockPassword: 19 } // 特性值回调 let characteristicValueCallback = null // 完整数据 let completeArray // 完整内容数据长度 let length // 请求参数 let requestParams = null export const useStarCloudStore = defineStore('starCloud', { state() { return { // 环境 env: null, // 客户端Id clientId: null, // 客户端密码 clientSecret: null, // 星云是否登录 loginStarCloud: false, // 星云用户信息 userInfo: null, // 账户信息 accountInfo: null, // 锁信息 lockInfo: null, // 消息序号 messageCount: 1, // 服务器时间 serverTimestamp: 0, // 时间差 timeDifference: 0, // 小程序环境 envVersion: '' } }, actions: { // 初始化星云 initStarCloud(clientId, clientSecret, env = 'XHJ') { const appInfo = uni.getAccountInfoSync() this.envVersion = appInfo.miniProgram.envVersion this.env = env this.clientId = clientId this.clientSecret = clientSecret // 监听特性值变化 onBLECharacteristicValueChange(this.listenCharacteristicValue) }, // 注册星云 async register() { const { code, data, message } = await starCloudCreateUser({ clientId: this.clientId, clientSecret: this.clientSecret }) return new Result(code, data, message) }, // 登录星云 async login(username, password) { this.accountInfo = { username, password } const token = getStorage('starCloudToken') if (token) { this.userInfo = getStorage('starCloudUser') this.loginStarCloud = true // 获取服务器时间 this.getServerTimestamp() .then(() => {}) return Result.Success } console.log('登录星云', username, password) const { code, data: userInfo, message } = await getStarCloudToken({ username: username, password: password, clientId: this.clientId, clientSecret: this.clientSecret }) if (code === Result.Success.code) { this.userInfo = userInfo setStorage('starCloudToken', userInfo.access_token) setStorage('starCloudUser', userInfo) this.loginStarCloud = true // 获取服务器时间 this.getServerTimestamp() .then(() => {}) } return new Result(code, {}, message) }, // 选择锁 async selectLock(lockId) { const { code, data, message } = await getLockDetail({ lockId }) if (code === Result.Success.code) { const lockList = getStorage('lockList') if(lockList) { const index = lockList.findIndex(item => item.lockId === lockId) if (index === -1) { lockList.push(data) } else { lockList[index] = data } setStorage('lockList', lockList) } else { setStorage('lockList', [data]) } this.lockInfo = data } else { const lockList = getStorage('lockList') console.log('锁列表', lockList) if(lockList) { const index = lockList.findIndex(item => item.lockId === lockId) if (index !== -1) { this.lockInfo = lockList[index] return new Result(Result.Success.code, this.lockInfo) } } } return new Result(code, data, message) }, // 清理用户 async cleanLockUser(disconnect = false) { // 确认设备连接正常 const searchResult = await searchAndConnectDevice(this.lockInfo.bluetooth.bluetoothDeviceName) if (searchResult.code !== Result.Success.code) { return searchResult } this.updateLockInfo(searchResult.data) // 获取并处理锁信息 let { uid: authUid, keyId, token, bluetooth } = this.lockInfo let { uid } = this.userInfo authUid = authUid.toString() uid = uid.toString() keyId = keyId.toString() const name = bluetooth.bluetoothDeviceName // 获取用户列表 const { code: requestCode, data: requestData } = await getUserNoListRequest({ lockId: this.lockInfo.lockId }) console.log('获取用户列表请求结果', requestCode, requestData) if (requestCode !== 0) return Result.Fail const userNoList = requestData.userNos // 组装发送数据 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(token || new Uint8Array([0, 0, 0, 0]), 124 + userNoList.length) contentArray[128 + userNoList.length] = 16 const md5Array = md5Encrypt(authUid + keyId, token || new Uint8Array([0, 0, 0, 0]), bluetooth.publicKey) contentArray.set(md5Array, 129 + userNoList.length) const cebArray = sm4.encrypt(contentArray, bluetooth.privateKey, { mode: 'ecb', output: 'array' }) const packageArray = createPackageEnd(headArray, cebArray) const writeResult = await writeBLECharacteristicValue(this.lockInfo.deviceId, this.lockInfo.serviceId, this.lockInfo.writeCharacteristicId, packageArray) if (writeResult.code !== Result.Success.code) { return writeResult } return this.getWriteResult(this.cleanLockUser, disconnect) }, // 开门 async openDoor(type = 'open', disconnect) { // 确认设备连接正常 const searchResult = await searchAndConnectDevice(this.lockInfo.bluetooth.bluetoothDeviceName) if (searchResult.code !== Result.Success.code) { return searchResult } this.updateLockInfo(searchResult.data) // 检查是否已添加为用户 const checkResult = await this.checkLockUser() if (checkResult.code !== Result.Success.code) { return checkResult } // 是否需要联网 let onlineToken = '' if (this.lockInfo.lockSetting.appUnlockOnline) { const result = await this.getNetToken() if (result.code === Result.Success.code) { onlineToken = result.data.token } else { return result } } // 开门方式 let openMode if (type === 'close') { openMode = this.lockInfo.lockSetting.appUnlockOnline ? 33 : 32 } else { openMode = this.lockInfo.lockSetting.appUnlockOnline ? 1 : 0 } const name = this.lockInfo.bluetooth.bluetoothDeviceName const uid = this.userInfo.uid.toString() const openTime = Math.ceil(new Date() .getTime() / 1000) + this.timeDifference 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(timestampToArray(openTime), 63) console.log('开门时token', this.lockInfo.token) contentArray.set(this.lockInfo.token || timestampToArray(openTime), 67) contentArray[71] = 16 const md5Array = md5Encrypt(name + uid, this.lockInfo.token || timestampToArray(openTime), this.lockInfo.bluetooth.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.lockInfo.bluetooth.privateKey, { mode: 'ecb', output: 'array' }) const packageArray = createPackageEnd(headArray, cebArray) const writeResult = await writeBLECharacteristicValue(this.lockInfo.deviceId, this.lockInfo.serviceId, this.lockInfo.writeCharacteristicId, packageArray) if (writeResult.code !== Result.Success.code) { return writeResult } return this.getWriteResult(this.openDoor, disconnect) }, // 获取离线密码 async getOfflinePassword(password) { return await getOfflinePassword({ ...password, lockId: this.lockInfo.lockId }) }, // 自定义密码 async customPassword(password, disconnect) { // 确认设备连接正常 const searchResult = await searchAndConnectDevice(this.lockInfo.bluetooth.bluetoothDeviceName) if (searchResult.code !== Result.Success.code) { return searchResult } this.updateLockInfo(searchResult.data) // 检查是否已添加为用户 const checkResult = await this.checkLockUser() if (checkResult.code !== Result.Success.code) { return checkResult } requestParams = password let { pwdNo, operate, keyboardPwd, startDate, endDate, pwdRight } = password const uid = this.userInfo.uid.toString() const keyId = this.lockInfo.keyId.toString() const isAdmin = pwdRight const userCountLimit = 0xFFFF startDate = Math.floor(startDate / 1000) endDate = Math.floor(endDate / 1000) keyboardPwd = keyboardPwd.toString() if(!pwdNo) { pwdNo = 0 } 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 < keyboardPwd.length; i++) { contentArray[i + 68] = keyboardPwd.charCodeAt(i) } contentArray[88] = userCountLimit / 256 contentArray[89] = userCountLimit % 256 contentArray.set(this.lockInfo.token || new Uint8Array([0, 0, 0, 0]), 90) contentArray.set(timestampToArray(startDate), 94) contentArray.set(timestampToArray(endDate), 98) contentArray[102] = 16 const md5Array = md5Encrypt(keyId + uid, this.lockInfo.token || new Uint8Array([0, 0, 0, 0]), this.lockInfo.bluetooth.signKey) contentArray.set(md5Array, 103) const cebArray = sm4.encrypt(contentArray, this.lockInfo.bluetooth.privateKey, { mode: 'ecb', output: 'array' }) const packageArray = createPackageEnd(headArray, cebArray) const writeResult = await writeBLECharacteristicValue(this.lockInfo.deviceId, this.lockInfo.serviceId, this.lockInfo.writeCharacteristicId, packageArray) if (writeResult.code !== Result.Success.code) { return writeResult } return this.getWriteResult(this.customPassword, disconnect, password) }, // 获取联网token async getNetToken() { const { code, data, message } = await getLockNetTokenRequest({ lockId: this.lockInfo.lockId }) return new Result(code, data, message) }, // 获取服务器时间 async getServerTimestamp() { const { code, data, message } = await getServerDatetime({}) if (code === Result.Success.code) { this.serverTimestamp = Math.ceil(data.date / 1000) this.timeDifference = Math.ceil((data.date - new Date() .getTime()) / 1000) } return new Result(code, data, message) }, // 添加用户 async addLockUser(data, disconnect = false) { // 确认设备连接正常 const searchResult = await searchAndConnectDevice(this.lockInfo.bluetooth.bluetoothDeviceName) if (searchResult.code !== Result.Success.code) { return searchResult } this.updateLockInfo(searchResult.data) 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(timestampToArray(startDate), 124) contentArray.set(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.lockInfo.token || timestampToArray(startDate), 161) contentArray[165] = 16 const md5Array = md5Encrypt(authUid + keyId, this.lockInfo.token || timestampToArray(startDate), this.lockInfo.bluetooth.publicKey) contentArray.set(md5Array, 166) const cebArray = sm4.encrypt(contentArray, this.lockInfo.bluetooth.privateKey, { mode: 'ecb', output: 'array' }) const packageArray = createPackageEnd(headArray, cebArray) const writeResult = await writeBLECharacteristicValue(this.lockInfo.deviceId, this.lockInfo.serviceId, this.lockInfo.writeCharacteristicId, packageArray) if (writeResult.code !== Result.Success.code) { return writeResult } return this.getWriteResult(this.addLockUser, disconnect, data) }, // 获取写入结果 getWriteResult(request, disconnect = false, params) { return new Promise(resolve => { const getWriteResultTimer = setTimeout(() => { resolve(Result.Fail) }, 20000) characteristicValueCallback = async (data) => { // code 6 token过期,重新获取 if (data.code === Result.NotTokenLock.code) { resolve(await request(params)) } else if (data.code === Result.NotRegisteredLock.code) { const checkResult = await this.checkLockUser(true) if (checkResult.code === Result.Success.code) { resolve(await request(params)) } else { clearTimeout(getWriteResultTimer) resolve(checkResult) } } else { clearTimeout(getWriteResultTimer) if(disconnect) { await this.disconnectDevice() } console.log('写入结果', data, request, params) resolve(data) } } }) }, // 检查是否已添加为用户 async checkLockUser(forceAdd = false) { if (this.lockInfo.lockUserNo === 0 || forceAdd) { const timestamp = Math.floor(new Date() .getTime() / 1000) const password = (Math.floor(Math.random() * 900000) + 100000) .toString() console.log('用户未添加,开始添加用户') const addUserParams = { name: this.lockInfo.bluetooth.bluetoothDeviceName, keyId: this.lockInfo.keyId.toString(), authUid: this.lockInfo.uid.toString(), uid: this.userInfo.uid.toString(), openMode: 1, keyType: 0, startDate: this.lockInfo.startDate === 0 ? timestamp : Math.floor(this.lockInfo.startDate / 1000), expireDate: this.lockInfo.endDate === 0 ? 0xffffffff : Math.floor(this.lockInfo.endDate / 1000), useCountLimit: this.lockInfo.keyType === 3 ? 1 : 0xffff, isRound: this.lockInfo.keyType === 4 ? 1 : 0, weekRound: this.lockInfo.keyType === 4 ? convertWeekdaysToNumber(this.lockInfo.weekDays) : 0, startHour: this.lockInfo.keyType === 4 ? new Date(this.lockInfo.startDate) .getHours() : 0, startMin: this.lockInfo.keyType === 4 ? new Date(this.lockInfo.startDate) .getMinutes() : 0, endHour: this.lockInfo.keyType === 4 ? new Date(this.lockInfo.endDate) .getHours() : 0, endMin: this.lockInfo.keyType === 4 ? new Date(this.lockInfo.endDate) .getMinutes() : 0, role: 0, password } const addUserResult = await this.addLockUser(addUserParams) console.log('添加用户蓝牙结果', addUserResult) if (addUserResult.code === Result.Success.code) { const { code } = await updateLockUserNoRequest({ keyId: this.lockInfo.keyId, lockUserNo: this.lockInfo.lockUserNo }) console.log('添加用户请求结果', code) return Result.Success } else if (addUserResult.code === Result.NotMoreKeyLock.code) { console.log('用户达上限,开始清理用户') const { code: cleanCode } = await this.cleanLockUser() console.log('清理用户蓝牙结果', cleanCode) if (cleanCode === Result.Success.code) { return await this.checkLockUser() } else { return Result.Fail } } else if (addUserResult.code === Result.ReadyHasKeyLock.code) { return Result.Success } else { return Result.Fail } } else { return Result.Success } }, // 更新锁信息 updateLockInfo(lockInfo) { this.lockInfo = { ...this.lockInfo, ...lockInfo } }, // 特征值变化回调 listenCharacteristicValue(res) { if (res.deviceId === this.lockInfo.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 { this.parsingCharacteristicValue(binaryData).then(() => {}) } } 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) { this.parsingCharacteristicValue(completeArray).then(() => {}) completeArray = null } } } } }, // 解析特征值 async parsingCharacteristicValue (binaryData) { // 0x20 明文 0x22 SM4(事先约定密钥) 0x23 SM4(设备指定密钥) if (binaryData[7] === 0x20) { if (binaryData[12] * 256 + binaryData[13] === cmdIds.getPublicKey) { if (binaryData[14] === Result.Success.code) { this.updateLockInfo({ bluetooth: { ...this.lockInfo.bluetooth, publicKey: [...binaryData.slice(15, 31)] } }) } characteristicValueCallback(new Result(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 < this.lockInfo.bluetooth.bluetoothDeviceName.length; i++) { key[i] = this.lockInfo.bluetooth.bluetoothDeviceName.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] === Result.Success.code) { this.updateLockInfo({ bluetooth: { ...this.lockInfo.bluetooth, privateKey: decrypted.slice(3, 19), signKey: decrypted.slice(19, 35), pwdTimestamp: arrayToTimestamp(decrypted.slice(35, 39)) * 1000 } }) console.log('privateKey', Array.from(this.lockInfo.bluetooth.privateKey)) console.log('signKey', Array.from(this.lockInfo.signKey)) } characteristicValueCallback(new Result(decrypted[2])) } } else { const cebBinaryData = binaryData.slice(12, binaryData.length - 2) const decrypted = sm4.decrypt(cebBinaryData, this.lockInfo.bluetooth.privateKey, { mode: 'ecb', output: 'array' }) console.log('ecb解密后的数据', decrypted) const cmdId = decrypted[0] * 256 + decrypted[1] switch (cmdId) { case cmdIds.getLockStatus: if (decrypted[2] === Result.Success.code) { const lockConfig = { vendor: uint8ArrayToString(decrypted.slice(3, 23)), product: decrypted[23], model: uint8ArrayToString(decrypted.slice(24, 44)), fwVersion: uint8ArrayToString(decrypted.slice(44, 64)), hwVersion: uint8ArrayToString(decrypted.slice(64, 84)), serialNum0: uint8ArrayToString(decrypted.slice(84, 100)), serialNum1: uint8ArrayToString(decrypted.slice(100, 116)), btDeviceName: uint8ArrayToString(decrypted.slice(116, 132)), electricQuantity: decrypted[132], electricQuantityStandby: decrypted[133], restoreCount: decrypted[134] * 256 + decrypted[135], restoreDate: arrayToTimestamp(decrypted.slice(136, 140)), icPartNo: uint8ArrayToString(decrypted.slice(140, 150)), indate: arrayToTimestamp(decrypted.slice(150, 154)), mac: uint8ArrayToString(decrypted.slice(154, 174)), timezoneOffset: new Date() .getTimezoneOffset() * 60 } this.updateLockInfo({ featureValue: uint8ArrayToString(decrypted.slice(175, 175 + decrypted[ 174])), featureSettingValue: 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 }) console.log('获取锁状态成功', this.lockInfo.lockConfig) } characteristicValueCallback(new Result(decrypted[2])) break case cmdIds.addUser: this.updateLockInfo({ token: decrypted.slice(42, 46) }) if (decrypted[46] === Result.Success.code) { this.updateLockInfo({ lockUserNo: decrypted[47] * 256 + decrypted[48] }) } console.log('添加用户结果', decrypted[46], this.lockInfo.token) characteristicValueCallback(new Result(decrypted[46])) break case cmdIds.expandCmd: const subCmdId = decrypted[3] switch (subCmdId) { case subCmdIds.resetLockPassword: this.updateLockInfo({ token: decrypted.slice(5, 9) }) characteristicValueCallback(new Result(decrypted[4])) break case subCmdIds.setLockPassword: this.updateLockInfo({ token: decrypted.slice(5, 9) }) if (decrypted[2] === Result.Success.code) { if(decrypted[11] === Result.Success.code) { const pwdNo = decrypted[9] * 256 + decrypted[10] if (requestParams.operate === 0) { const addResult = await addCustomPassword({ ...requestParams, pwdUserNo: pwdNo, lockId: this.lockInfo.lockId }) if (addResult.code === Result.Success.code) { characteristicValueCallback(new Result(addResult.code, { pwdNo: pwdNo, keyboardPwdId: addResult.data.keyboardPwdId, keyboardPwd: addResult.data.keyboardPwd })) } else { characteristicValueCallback(new Result(addResult.code, addResult.data, addResult.message)) } } else if (requestParams.operate === 1) { const updateResult = await updatePassword({ ...requestParams, keyboardPwdId: this.lockInfo.keyboardPwdId }) if (updateResult.code === Result.Success.code) { characteristicValueCallback(new Result(updateResult.code)) } else { characteristicValueCallback(new Result(updateResult.code, updateResult.data, updateResult.message)) } } } else { characteristicValueCallback(new Result(decrypted[11])) } } else { characteristicValueCallback(new Result(decrypted[2])) } break } break case cmdIds.openDoor: this.updateLockInfo({ token: decrypted.slice(2, 6) }) console.log('开门', decrypted[6], this.lockInfo.token) characteristicValueCallback(new Result(decrypted[6])) break default: this.updateLockInfo({ token: decrypted.slice(2, 6) }) console.log('默认结果', decrypted[6], this.lockInfo.token) characteristicValueCallback(new Result(decrypted[6])) break } } }, // 获取配置 getConfig() { let config = configs[this.env] return { ...config, version, buildNumber } }, /* * 生成包头 * 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 } // 数据长度 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 }, // 断开与设备的连接 async disconnectDevice() { return await closeBLEConnection(this.lockInfo.deviceId) }, } })