From e9efe4dfab517dae1521f0ae997a1b0e7f004e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=83=E9=B9=8F?= Date: Tue, 8 Apr 2025 18:12:52 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E9=94=81=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/addDevice/bindLock.vue | 8 +-- stores/bluetooth.js | 116 +++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/pages/addDevice/bindLock.vue b/pages/addDevice/bindLock.vue index 089cd87..6a5a722 100644 --- a/pages/addDevice/bindLock.vue +++ b/pages/addDevice/bindLock.vue @@ -9,7 +9,7 @@ placeholder-class="input-placeholder" @input="updateName" /> - 确定 + 确定 @@ -39,7 +39,7 @@ }, methods: { ...mapActions(useBluetoothStore, [ - 'addLockUser', + 'bindLock', 'closeBluetoothConnection', 'updateBindedDeviceName', 'closeAllBluetooth', @@ -50,7 +50,7 @@ updateName(data) { this.name = data.detail.value }, - async bindLock() { + async bindLockOperation() { if (this.name === '') { uni.showToast({ title: '请输入名称', @@ -69,7 +69,7 @@ this.updateBindedDeviceName(this.currentLockInfo.name) const timestamp = parseInt(new Date().getTime() / 1000, 10) const password = (Math.floor(Math.random() * 900000) + 100000).toString() - const { code: addUserCode } = await this.addLockUser({ + const { code: addUserCode } = await this.bindLock({ name: this.currentLockInfo.name, keyId: this.keyId, authUid: this.userInfo.uid.toString(), diff --git a/stores/bluetooth.js b/stores/bluetooth.js index 1302e11..71a91a2 100644 --- a/stores/bluetooth.js +++ b/stores/bluetooth.js @@ -1841,6 +1841,122 @@ export const useBluetoothStore = defineStore('ble', { await this.writeBLECharacteristicValue(packageArray, false) return this.getWriteResult(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) + await this.writeBLECharacteristicValue(packageArray, false) + return this.getWriteResult(this.bindLock, data) + }, // 获取写入结果 getWriteResult(request, params) { const $user = useUserStore() From a1b36ccff5cd7b32ddaca42bddecba92ddba11e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=83=E9=B9=8F?= Date: Wed, 9 Apr 2025 18:04:26 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E4=BA=91?= =?UTF-8?q?=E5=AD=98=E7=9B=B8=E5=85=B3UI+=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.cjs | 22 ++++++++++++++++++---- api/sdk.js | 18 ++++++++++++++++++ pages.json | 18 ++++++++++++++++++ pages/main/lockDetail.vue | 2 +- stores/basic.js | 15 +++++++++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 3128e38..27c8944 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -25,8 +25,7 @@ module.exports = { extends: [ 'plugin:vue/vue3-recommended', // 使用插件支持vue3 'airbnb-base', - 'plugin:prettier/recommended', - './.eslintrc-auto-import.json' + 'plugin:prettier/recommended' ], ignorePatterns: ['utils/log.js', 'unpackage/**/*'], /** @@ -45,11 +44,26 @@ module.exports = { 'no-use-before-define': 'off', // 禁止在 函数/类/变量 定义之前使用它们 'no-irregular-whitespace': 'off', // 禁止不规则的空白 'no-undef': 'error', // 禁止使用未声明的变量 - 'no-unused-vars': 'error', // 禁止出现未使用过的变量 + 'no-unused-vars': [ + 'error', + { + vars: 'all', + args: 'after-used', + ignoreRestSiblings: false, + caughtErrors: 'all' + } + ], // 禁止出现未使用过的变量 'vue/script-setup-uses-vars': 'error', // 确保script setup中的变量必须正确定义 'vue/no-undef-components': 'off', // 关闭组件未定义的检查 'vue/no-undef-properties': 'off', // 关闭属性未定义的检查 - 'vue/no-unused-vars': 'error', // 禁止Vue组件中出现未使用的变量 + 'vue/no-unused-vars': [ + 'error', + { + ignorePattern: '' + } + ], // 禁止Vue组件中出现未使用的变量 + 'vue/no-unused-refs': 'error', // 禁止定义但未使用的ref + 'vue/require-component-is': 'error', // 禁止模板中未使用的组件 'import/no-unused-modules': 'off', // 关闭模块导出检查 'import/no-cycle': 0, 'no-nested-ternary': 0, diff --git a/api/sdk.js b/api/sdk.js index 5ec215c..c4dc3f4 100644 --- a/api/sdk.js +++ b/api/sdk.js @@ -10,3 +10,21 @@ export function passthrough(data) { data }) } + +// 获取视频列表 +export function getVideoList(data) { + return request({ + url: '/lockCloudStorage/list', + method: 'POST', + data + }) +} + +// 删除视频 +export function deleteVideo(data) { + return request({ + url: '/lockCloudStorage/delete', + method: 'POST', + data + }) +} diff --git a/pages.json b/pages.json index fbe944f..6107d0d 100644 --- a/pages.json +++ b/pages.json @@ -31,6 +31,24 @@ "navigationBarTitleText": "微信授权", "disableScroll": true } + }, + { + "path": "videoDetail", + "style": { + "navigationBarTitleText": "视频播放" + } + }, + { + "path": "videoLog", + "style": { + "navigationBarTitleText": "云存" + } + }, + { + "path": "videoEdit", + "style": { + "navigationBarTitleText": "视频编辑" + } } ], "plugins": { diff --git a/pages/main/lockDetail.vue b/pages/main/lockDetail.vue index b2a3cee..fd85034 100644 --- a/pages/main/lockDetail.vue +++ b/pages/main/lockDetail.vue @@ -202,7 +202,7 @@ Date: Wed, 9 Apr 2025 18:05:03 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E4=BA=91?= =?UTF-8?q?=E5=AD=98=E7=9B=B8=E5=85=B3UI+=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/p2p/VideoList.vue | 219 ++++++++++++++++++++++++++++++++++++++ pages/p2p/videoDetail.vue | 38 +++++++ pages/p2p/videoEdit.vue | 145 +++++++++++++++++++++++++ pages/p2p/videoLog.vue | 51 +++++++++ 4 files changed, 453 insertions(+) create mode 100644 pages/p2p/VideoList.vue create mode 100644 pages/p2p/videoDetail.vue create mode 100644 pages/p2p/videoEdit.vue create mode 100644 pages/p2p/videoLog.vue diff --git a/pages/p2p/VideoList.vue b/pages/p2p/VideoList.vue new file mode 100644 index 0000000..e352ded --- /dev/null +++ b/pages/p2p/VideoList.vue @@ -0,0 +1,219 @@ + + + + + diff --git a/pages/p2p/videoDetail.vue b/pages/p2p/videoDetail.vue new file mode 100644 index 0000000..22ed03f --- /dev/null +++ b/pages/p2p/videoDetail.vue @@ -0,0 +1,38 @@ + + + diff --git a/pages/p2p/videoEdit.vue b/pages/p2p/videoEdit.vue new file mode 100644 index 0000000..3c255eb --- /dev/null +++ b/pages/p2p/videoEdit.vue @@ -0,0 +1,145 @@ + + + diff --git a/pages/p2p/videoLog.vue b/pages/p2p/videoLog.vue new file mode 100644 index 0000000..578a84d --- /dev/null +++ b/pages/p2p/videoLog.vue @@ -0,0 +1,51 @@ + + + From baecc976eed564bd4f9a17afb1a005c12ffa1a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=83=E9=B9=8F?= Date: Thu, 10 Apr 2025 16:34:00 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E8=93=9D?= =?UTF-8?q?=E7=89=99=E9=80=8F=E4=BC=A0=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= =?UTF-8?q?+=E8=A2=AB=E5=8F=AB=E6=97=B6=E6=9F=A5=E8=AF=A2=E9=94=81?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.cjs | 3 +- App.vue | 10 +- constant/transportType.js | 7 + pages/addDevice/searchDevice.vue | 7 +- pages/main/customBox.vue | 47 +++-- pages/p2p/authorizeWechat.vue | 23 ++- stores/bluetooth.js | 334 +++++++++++++++++++++++-------- 7 files changed, 324 insertions(+), 107 deletions(-) create mode 100644 constant/transportType.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 27c8944..e29e48e 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -9,7 +9,8 @@ module.exports = { uni: 'writable', getApp: 'writable', wx: 'writable', - getCurrentPages: 'writable' + getCurrentPages: 'writable', + requirePlugin: 'writable' }, // 指定如何解析语法 parser: 'vue-eslint-parser', diff --git a/App.vue b/App.vue index 6b24e74..18c5e7f 100644 --- a/App.vue +++ b/App.vue @@ -16,6 +16,7 @@ appid: '', // 小程序版本 envVersion: '', + sn: '', // 获取环境配置 getEnvConfig() { const envVersionStorage = getStorage('envVersion') @@ -84,6 +85,13 @@ key: 'Call', routeType: 'switchTab' }) + + wmpfVoip.onVoipEvent(event => { + if (event.eventName === 'callPageOnShow') { + const query = wmpfVoip.getPluginOnloadOptions() + getApp().globalData.sn = query.callerId + } + }) }, // 强制升级 updateMiniProgram() { @@ -104,5 +112,5 @@ diff --git a/constant/transportType.js b/constant/transportType.js new file mode 100644 index 0000000..7effc3f --- /dev/null +++ b/constant/transportType.js @@ -0,0 +1,7 @@ +export const transportType = { + TRANSPORT_BLUETOOTH: 0, + TRANSPORT_OFFLINE: 10, + TRANSPORT_GATEWAY: 20, + TRANSPORT_WIFI: 30, + TRANSPORT_TENCENT_YUN: 40 +} diff --git a/pages/addDevice/searchDevice.vue b/pages/addDevice/searchDevice.vue index abdb58f..b1f0689 100644 --- a/pages/addDevice/searchDevice.vue +++ b/pages/addDevice/searchDevice.vue @@ -67,7 +67,7 @@ 'getCommKey', 'connectBluetoothDevice', 'updateServerTimestamp', - 'getLockStatus' + 'getLockStatusInfo' ]), ...mapActions(useBasicStore, ['getDeviceInfo', 'routeJump', 'getNetworkType']), async connect(device) { @@ -123,7 +123,7 @@ } const date = new Date() const timestamp = this.serverTimestamp - date.getTimezoneOffset() * 60 - const { code } = await this.getLockStatus({ + const { code } = await this.getLockStatusInfo({ name: this.currentLockInfo.name, uid: this.userInfo.uid.toString(), nowTime: this.serverTimestamp, @@ -148,7 +148,8 @@ icon: 'none' }) } - } catch (res) { + } catch (error) { + console.log('连接失败', error) uni.hideLoading() uni.showToast({ title: '连接失败,请靠近设备并保持设备处于唤醒状态', diff --git a/pages/main/customBox.vue b/pages/main/customBox.vue index 2249512..c616fe2 100644 --- a/pages/main/customBox.vue +++ b/pages/main/customBox.vue @@ -1,5 +1,5 @@