Merge branch 'fanpeng' into 'develop'

feat: 适配腾讯锁添加发送电子钥匙后在锁板创建用户,开门方式适配wifi锁

See merge request StarlockTeam/wx-starlock!38
This commit is contained in:
范鹏 2025-05-04 06:35:09 +00:00
commit 9581343329
16 changed files with 497 additions and 253 deletions

View File

@ -1,4 +1,9 @@
{
"src/**/*.{vue,js}": ["npm run prettier", "npm run eslint"],
"src/**/*.{vue,scss,css,less}": ["npm run stylelint:out"]
}
"*.{vue,js}": [
"prettier --write",
"eslint --fix"
],
"*.{vue,scss,css,less}": [
"stylelint --fix"
]
}

View File

@ -1,7 +1,13 @@
export const transportType = {
TRANSPORT_BLUETOOTH: 0,
TRANSPORT_OFFLINE: 10,
TRANSPORT_GATEWAY: 20,
TRANSPORT_WIFI: 30,
TRANSPORT_TENCENT_YUN: 40
TRANSPORT_BLUETOOTH: 10,
TRANSPORT_OFFLINE: 20,
TRANSPORT_GATEWAY: 30,
TRANSPORT_WIFI: 40,
TRANSPORT_TENCENT_YUN: 50,
TRANSPORT_WIFI_PRIORITY: 60,
TRANSPORT_BLUETOOTH_PRIORITY: 70
}
export const model = {
TENCENT_YUN_LOCK: 'XB007'
}

View File

@ -32,6 +32,7 @@
"vite-plugin-eslint": "^1.8.1"
},
"scripts": {
"prepare": "husky install",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,vue,json,css,scss}\"",
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,vue,json,css,scss}\"",
"lint": "eslint --fix \"**/*.{js,jsx,ts,tsx,vue}\"",

View File

@ -12,22 +12,12 @@
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
import { useBluetoothStore } from '@/stores/bluetooth'
import { useBasicStore } from '@/stores/basic'
const bluetoothStore = useBluetoothStore()
const basicStore = useBasicStore()
const type = ref('bluetooth')
onLoad(options => {
if (options.type) {
type.value = options.type
}
})
const toSearchDevice = async () => {
if (bluetoothStore.bluetoothStatus !== 0) {
bluetoothStore.getBluetoothStatus()
@ -38,17 +28,10 @@
result = await bluetoothStore.initAndListenBluetooth()
}
if (result) {
if (type.value === 'bluetooth') {
basicStore.routeJump({
type: 'redirectTo',
name: 'searchDevice'
})
} else if (type.value === 'wifi') {
basicStore.routeJump({
type: 'redirectTo',
name: 'distributionNetwork'
})
}
basicStore.routeJump({
type: 'redirectTo',
name: 'searchDevice'
})
} else {
bluetoothStore.checkSetting()
}

View File

@ -13,7 +13,7 @@
>
<view class="flex items-center">
<view class="mr-4">WiFi</view>
<view>{{ wifiList[wifiIndex]?.SSID ?? '搜索中...' }}</view>
<view>{{ wifiList[wifiIndex]?.SSID ?? '请选择WiFi' }}</view>
<view class="ml-a">
<up-icon name="arrow-right" size="24rpx"></up-icon>
</view>
@ -61,12 +61,12 @@
<script setup>
import { onMounted, onUnmounted, ref } from 'vue'
import { useBluetoothStore } from '@/stores/bluetooth'
// import { useUserStore } from '@/stores/user'
import { useUserStore } from '@/stores/user'
import { useBasicStore } from '@/stores/basic'
import { passthrough } from '@/api/sdk'
const $bluetooth = useBluetoothStore()
// const $user = useUserStore()
const $user = useUserStore()
const $basic = useBasicStore()
const wifiList = ref([])
@ -77,42 +77,27 @@
const pending = ref(false)
const requestResult = ref(false)
onMounted(async () => {
uni.showLoading({
title: '搜索中'
title: '搜索中',
mask: true
})
// const result = await $bluetooth.getWifiList({
// uid: $user.userInfo.uid.toString()
// })
// if (result.code !== 0) {
// uni.showModal({
// title: '',
// content: '',
// showCancel: false,
// success: () => {
// uni.navigateBack()
// }
// })
// }
listenEvent()
setTimeout(() => {
uni.hideLoading()
wifiList.value = [
{
SSID: '测试1',
rssi: 10
},
{
SSID: '测试2',
rssi: 20
},
{
SSID: '测试3',
rssi: 30
const result = await $bluetooth.getWifiList({
uid: $user.userInfo.uid.toString()
})
if (result.code !== 0) {
uni.showModal({
title: '提示',
content: '搜索失败,请返回重试',
showCancel: false,
success: () => {
uni.navigateBack()
}
]
wifiIndex.value = 0
}, 2000)
})
}
listenEvent()
})
onUnmounted(() => {
@ -124,6 +109,9 @@
uni.$on('wifiList', async data => {
if (data.status === 0) {
wifiList.value = data.wifiList
if (wifiList.value.length > 0) {
wifiIndex.value = 0
}
uni.hideLoading()
} else {
uni.showModal({
@ -137,6 +125,7 @@
}
})
uni.$on('distributionNetworkResult', async data => {
requestResult.value = false
uni.hideLoading()
pending.value = false
if (data.status === 0) {
@ -192,35 +181,36 @@
if (result.code === 0) {
$bluetooth.updateCurrentLockInfo({
...$bluetooth.currentLockInfo,
tencentYunLock: {
productId: result.data.productId,
deviceName: result.data.deviceName,
devicePsk: result.data.devicePsk
}
tencentYunLock: result.data
})
// const result = await $bluetooth.distributionNetwork({
// SSID: wifiList.value[wifiIndex.value].SSID,
// password: password.value,
// json: JSON.stringify({
// productId: result.data.productId,
// deviceName: result.data.deviceName,
// devicePsk: result.data.devicePsk
// })
// })
// if (result.code !== 0) {
// uni.showToast({
// title: '',
// icon: 'none'
// })
// }
setTimeout(() => {
$basic.routeJump({
type: 'redirectTo',
name: 'selectAddress'
const res = await $bluetooth.distributionNetwork({
SSID: wifiList.value[wifiIndex.value].SSID,
password: password.value,
json: JSON.stringify(result.data)
})
if (res.code === 0) {
requestResult.value = true
setTimeout(() => {
pending.value = false
if (requestResult.value) {
uni.showToast({
title: '配网失败,请检查密码是否正确',
icon: 'none'
})
}
}, 10000)
} else {
pending.value = false
uni.showToast({
title: res.message,
icon: 'none'
})
}, 3000)
}
} else {
uni.hideLoading()
pending.value = false
uni.showToast({
title: result.message,
icon: 'none'

View File

@ -40,6 +40,7 @@
import { useBluetoothStore } from '@/stores/bluetooth'
import { useBasicStore } from '@/stores/basic'
import { useUserStore } from '@/stores/user'
import { model } from '@/constant/transportType'
export default {
data() {
@ -139,7 +140,10 @@
}
this.routeJump({
type: 'redirectTo',
name: false ? 'selectAddress' : 'distributionNetwork'
name:
this.currentLockInfo.lockConfig.model === model.TENCENT_YUN_LOCK
? 'distributionNetwork'
: 'selectAddress'
})
} else {
uni.hideLoading()

View File

@ -103,6 +103,7 @@
import { useBasicStore } from '@/stores/basic'
import { createKeyRequest } from '@/api/key'
import { useBluetoothStore } from '@/stores/bluetooth'
import { transportType } from '@/constant/transportType'
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel()
@ -246,10 +247,32 @@
params.receiverUsername = permanentAccount.value
params.isOnlyManageSelf = permanentManageSelf.value ? 1 : 0
}
const { code, message } = await createKeyRequest(params)
const { code, data, message } = await createKeyRequest(params)
if (code === 0) {
eventChannel.emit('refresherList', {})
$basic.backAndToast('添加成功')
if ($bluetooth.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN) {
$bluetooth.addLockUser({
name: $bluetooth.currentLockInfo.name,
keyId: $bluetooth.keyId,
authUid: $bluetooth.currentLockInfo.uid.toString(),
uid: data.receiverUid.toString(),
openMode: 1,
keyType: params.keyType,
startDate: params.startDate.toString(),
expireDate: params.endDate.toString(),
useCountLimit: params.keyType === '3' ? 1 : 0xffff,
isRound: params.keyType === '4' ? 1 : 0,
weekRound:
params.keyType === '4' ? $bluetooth.convertWeekdaysToNumber(params.weekDays) : 0,
startHour: params.keyType === '4' ? new Date(params.startDate).getHours() : 0,
startMin: params.keyType === '4' ? new Date(params.startDate).getMinutes() : 0,
endHour: params.keyType === '4' ? new Date(params.endDate).getHours() : 0,
endMin: params.keyType === '4' ? new Date(params.endDate).getMinutes() : 0,
role: 1,
password: (Math.floor(Math.random() * 900000) + 100000).toString()
})
}
} else if (code === 425) {
pending.value = false
uni.showModal({
@ -324,23 +347,23 @@
}
.text {
padding: 0 32rpx;
margin-top: 40rpx;
margin-bottom: 50rpx;
color: #262626;
font-size: 26rpx;
padding: 0 32rpx;
color: #262626;
}
.button {
border-radius: 64rpx;
width: 686rpx;
margin-left: 32rpx;
height: 100rpx;
line-height: 100rpx;
text-align: center;
background-color: #63b8af;
color: #fff;
margin-left: 32rpx;
font-size: 32rpx;
font-weight: bold;
line-height: 100rpx;
color: #fff;
text-align: center;
background-color: #63b8af;
border-radius: 64rpx;
}
</style>

View File

@ -127,6 +127,7 @@
import { useUserStore } from '@/stores/user'
import { useBluetoothStore } from '@/stores/bluetooth'
import { checkCardNameRequest } from '@/api/card'
import { transportType } from '@/constant/transportType'
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel()
@ -306,17 +307,29 @@
cardName: params.cardName
})
if (code === 0) {
$basic.routeJump({
name: 'bindCard',
params: {
card: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
if ($bluetooth.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN) {
const { code } = await $bluetooth.registerAuthentication(params)
if (code === 0) {
$basic.backAndToast('请在锁端添加卡片')
} else {
uni.showToast({
title: '添加卡片命令下达失败,请重试',
icon: 'none'
})
}
})
} else {
$basic.routeJump({
name: 'bindCard',
params: {
card: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
}
})
}
} else {
uni.showToast({
title: message,
@ -385,23 +398,23 @@
}
.text {
padding: 0 32rpx;
margin-top: 40rpx;
margin-bottom: 50rpx;
color: #262626;
font-size: 26rpx;
padding: 0 32rpx;
color: #262626;
}
.button {
border-radius: 64rpx;
width: 686rpx;
margin-left: 32rpx;
height: 100rpx;
line-height: 100rpx;
text-align: center;
background-color: #63b8af;
color: #fff;
margin-left: 32rpx;
font-size: 32rpx;
font-weight: bold;
line-height: 100rpx;
color: #fff;
text-align: center;
background-color: #63b8af;
border-radius: 64rpx;
}
</style>

View File

@ -104,6 +104,7 @@
import { useUserStore } from '@/stores/user'
import { useBluetoothStore } from '@/stores/bluetooth'
import { checkFaceNameRequest } from '@/api/face'
import { transportType } from '@/constant/transportType'
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel()
@ -275,17 +276,29 @@
faceName: params.faceName
})
if (code === 0) {
$basic.routeJump({
name: 'bindFace',
params: {
info: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
if ($bluetooth.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN) {
const { code } = await $bluetooth.registerAuthentication(params)
if (code === 0) {
$basic.backAndToast('请在锁端添加人脸')
} else {
uni.showToast({
title: '添加人脸命令下达失败,请重试',
icon: 'none'
})
}
})
} else {
$basic.routeJump({
name: 'bindFace',
params: {
info: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
}
})
}
} else {
uni.showToast({
title: message,
@ -344,23 +357,23 @@
}
.text {
padding: 0 32rpx;
margin-top: 40rpx;
margin-bottom: 50rpx;
color: #262626;
font-size: 26rpx;
padding: 0 32rpx;
color: #262626;
}
.button {
border-radius: 64rpx;
width: 686rpx;
margin-left: 32rpx;
height: 100rpx;
line-height: 100rpx;
text-align: center;
background-color: #63b8af;
color: #fff;
margin-left: 32rpx;
font-size: 32rpx;
font-weight: bold;
line-height: 100rpx;
color: #fff;
text-align: center;
background-color: #63b8af;
border-radius: 64rpx;
}
</style>

View File

@ -127,6 +127,7 @@
import { useUserStore } from '@/stores/user'
import { useBluetoothStore } from '@/stores/bluetooth'
import { checkFingerprintNameRequest } from '@/api/fingerprint'
import { transportType } from '@/constant/transportType'
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel()
@ -306,17 +307,29 @@
fingerprintName: params.fingerprintName
})
if (code === 0) {
$basic.routeJump({
name: 'bindFingerprint',
params: {
info: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
if ($bluetooth.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN) {
const { code } = await $bluetooth.registerAuthentication(params)
if (code === 0) {
$basic.backAndToast('请在锁端添加指纹')
} else {
uni.showToast({
title: '添加指纹命令下达失败,请重试',
icon: 'none'
})
}
})
} else {
$basic.routeJump({
name: 'bindFingerprint',
params: {
info: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
}
})
}
} else {
uni.showToast({
title: message,
@ -385,23 +398,23 @@
}
.text {
padding: 0 32rpx;
margin-top: 40rpx;
margin-bottom: 50rpx;
color: #262626;
font-size: 26rpx;
padding: 0 32rpx;
color: #262626;
}
.button {
border-radius: 64rpx;
width: 686rpx;
margin-left: 32rpx;
height: 100rpx;
line-height: 100rpx;
text-align: center;
background-color: #63b8af;
color: #fff;
margin-left: 32rpx;
font-size: 32rpx;
font-weight: bold;
line-height: 100rpx;
color: #fff;
text-align: center;
background-color: #63b8af;
border-radius: 64rpx;
}
</style>

View File

@ -130,6 +130,7 @@
import { useBluetoothStore } from '@/stores/bluetooth'
import { useLockStore } from '@/stores/lock'
import { createKeyRequest } from '@/api/key'
import { transportType } from '@/constant/transportType'
export default {
components: {
@ -173,7 +174,7 @@
}
},
computed: {
...mapState(useBluetoothStore, ['currentLockInfo']),
...mapState(useBluetoothStore, ['currentLockInfo', 'keyId']),
...mapState(useLockStore, ['keySearch'])
},
async onLoad() {
@ -182,6 +183,7 @@
methods: {
...mapActions(useBasicStore, ['getDeviceInfo', 'backAndToast', 'getNetworkType']),
...mapActions(useLockStore, ['getKeyList', 'updateKeySearch']),
...mapActions(useBluetoothStore, ['addLockUser', 'convertWeekdaysToNumber']),
changeCycle(data) {
this.cycleStartTime = data.startDate
this.cycleEndTime = data.endDate
@ -271,7 +273,7 @@
params.startTime = this.cycleStartTime
params.endTime = this.cycleEndTime
}
const { code, message } = await createKeyRequest(params)
const { code, data, message } = await createKeyRequest(params)
if (code === 0) {
uni.reportEvent('create_key', {})
this.updateKeySearch({
@ -280,6 +282,27 @@
})
this.getKeyList(this.keySearch)
this.backAndToast('钥匙已发送')
if (this.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN) {
this.addLockUser({
name: this.currentLockInfo.name,
keyId: this.keyId,
authUid: this.currentLockInfo.uid.toString(),
uid: data.receiverUid.toString(),
openMode: 1,
keyType: params.keyType,
startDate: params.startDate.toString(),
expireDate: params.endDate.toString(),
useCountLimit: params.keyType === '3' ? 1 : 0xffff,
isRound: params.keyType === '4' ? 1 : 0,
weekRound: params.keyType === '4' ? this.convertWeekdaysToNumber(params.weekDays) : 0,
startHour: params.keyType === '4' ? new Date(params.startDate).getHours() : 0,
startMin: params.keyType === '4' ? new Date(params.startDate).getMinutes() : 0,
endHour: params.keyType === '4' ? new Date(params.endDate).getHours() : 0,
endMin: params.keyType === '4' ? new Date(params.endDate).getMinutes() : 0,
role: 0,
password: (Math.floor(Math.random() * 900000) + 100000).toString()
})
}
} else if (code === 425) {
this.pending = false
uni.showModal({
@ -350,21 +373,21 @@
}
.text {
color: #262626;
font-size: 26rpx;
padding: 0 32rpx;
font-size: 26rpx;
color: #262626;
}
.button {
border-radius: 64rpx;
width: 686rpx;
margin-left: 32rpx;
height: 100rpx;
line-height: 100rpx;
text-align: center;
background-color: #63b8af;
color: #fff;
margin-left: 32rpx;
font-size: 32rpx;
font-weight: bold;
line-height: 100rpx;
color: #fff;
text-align: center;
background-color: #63b8af;
border-radius: 64rpx;
}
</style>

View File

@ -128,6 +128,7 @@
import { useUserStore } from '@/stores/user'
import { useBluetoothStore } from '@/stores/bluetooth'
import { checkPalmVeinNameRequest } from '@/api/palmVein'
import { transportType } from '@/constant/transportType'
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel()
@ -307,17 +308,29 @@
palmVeinName: params.palmVeinName
})
if (code === 0) {
$basic.routeJump({
name: 'bindPalmVein',
params: {
info: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
if ($bluetooth.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN) {
const { code } = await $bluetooth.registerAuthentication(params)
if (code === 0) {
$basic.backAndToast('请在锁端添加掌静脉')
} else {
uni.showToast({
title: '添加掌静脉命令下达失败,请重试',
icon: 'none'
})
}
})
} else {
$basic.routeJump({
name: 'bindPalmVein',
params: {
info: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
}
})
}
} else {
uni.showToast({
title: message,
@ -386,23 +399,23 @@
}
.text {
padding: 0 32rpx;
margin-top: 40rpx;
margin-bottom: 50rpx;
color: #262626;
font-size: 26rpx;
padding: 0 32rpx;
color: #262626;
}
.button {
border-radius: 64rpx;
width: 686rpx;
margin-left: 32rpx;
height: 100rpx;
line-height: 100rpx;
text-align: center;
background-color: #63b8af;
color: #fff;
margin-left: 32rpx;
font-size: 32rpx;
font-weight: bold;
line-height: 100rpx;
color: #fff;
text-align: center;
background-color: #63b8af;
border-radius: 64rpx;
}
</style>

View File

@ -83,6 +83,7 @@
import { useUserStore } from '@/stores/user'
import { useBluetoothStore } from '@/stores/bluetooth'
import { checkRemoteNameRequest } from '@/api/remote'
import { transportType } from '@/constant/transportType'
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel()
@ -248,17 +249,29 @@
remoteName: params.remoteName
})
if (code === 0) {
$basic.routeJump({
name: 'bindRemote',
params: {
info: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
if ($bluetooth.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN) {
const { code } = await $bluetooth.registerAuthentication(params)
if (code === 0) {
$basic.backAndToast('请在锁端添加远程')
} else {
uni.showToast({
title: '添加远程命令下达失败,请重试',
icon: 'none'
})
}
})
} else {
$basic.routeJump({
name: 'bindRemote',
params: {
info: JSON.stringify(params)
},
events: {
refresherList() {
eventChannel.emit('refresherList', {})
}
}
})
}
} else {
uni.showToast({
title: message,
@ -307,23 +320,23 @@
}
.text {
padding: 0 32rpx;
margin-top: 40rpx;
margin-bottom: 50rpx;
color: #262626;
font-size: 26rpx;
padding: 0 32rpx;
color: #262626;
}
.button {
border-radius: 64rpx;
width: 686rpx;
margin-left: 32rpx;
height: 100rpx;
line-height: 100rpx;
text-align: center;
background-color: #63b8af;
color: #fff;
margin-left: 32rpx;
font-size: 32rpx;
font-weight: bold;
line-height: 100rpx;
color: #fff;
text-align: center;
background-color: #63b8af;
border-radius: 64rpx;
}
</style>

View File

@ -1,19 +1,20 @@
<template>
<view>
<view class="mt-10 text-center text-base font-bold text-[#999]">授权后设备可呼叫该微信</view>
<view class="flex flex-col justify-center items-center pt-[30vh]">
<view v-if="requestFinish">
<view
v-if="!isAuthorized"
class="bg-[#63b8af] text-white rounded-full text-center leading-88rpx h-88rpx w-686 mx-4 mt-10"
class="bg-[#63b8af] text-white rounded-full text-center leading-88rpx h-88rpx w-686 mx-4"
@click="handleAuthorize"
>
授权
</view>
<view v-else>
<view v-if="!reject" class="text-center text-lg font-bold mt-4">您已授权</view>
<view v-if="!reject" class="text-center text-2xl font-bold">您已授权</view>
<view v-else>
<view class="text-center text-lg font-bold mt-4"> 您已拒绝授权请去设置中 </view>
<view class="text-center text-lg font-bold mt-4"> 打开语音视频通话提醒开关 </view>
<view class="text-center text-lg font-bold mt-6"> 您已拒绝授权请去设置中 </view>
<view class="text-center text-lg font-bold mt-4">
打开<text class="text-red">语音视频通话提醒</text>开关
</view>
<view
class="bg-[#63b8af] text-white rounded-full text-center leading-88rpx h-88rpx w-686 mx-4 mt-10"
@click="openSetting"
@ -23,6 +24,12 @@
</view>
</view>
</view>
<view v-if="requestFinish" class="mt-10 text-center text-base font-bold text-[#999]">
授权后在设备上按下门铃按钮
</view>
<view v-if="requestFinish" class="mt-4 text-center text-base font-bold text-[#999]">
微信会收到视频通话请求
</view>
</view>
</template>

View File

@ -54,9 +54,9 @@
<view
v-if="isVideoLoaded"
class="fixed bottom-[calc(32rpx+env(safe-area-inset-bottom))] bg-[rgba(0,0,0,0.3)] rounded-xl p-4 shadow-lg mx-4 w-622"
class="fixed bottom-[calc(32rpx+env(safe-area-inset-bottom))] bg-[rgba(0,0,0,0.3)] rounded-xl p-4 shadow-lg left-1/2 -translate-x-1/2 w-622"
>
<view class="flex items-center justify-around mx-10">
<view class="flex items-center justify-around mx-15">
<image
@click="isMute = !isMute"
:src="
@ -72,7 +72,7 @@
class="w-48 h-48 p-2"
></image>
</view>
<view class="flex items-center justify-around text-white mt-2">
<view class="flex items-center justify-between text-white mt-2 px-10">
<view class="flex flex-col items-center" @longpress="startVoice" @touchend="stopVoice">
<view class="bg-white w-80 h-80 rounded-full flex items-center justify-center">
<image
@ -84,13 +84,13 @@
class="w-55 h-55"
></image>
</view>
<view class="mt-2">长按说话</view>
<view class="mt-2 text-center whitespace-nowrap text-xs">长按说话</view>
</view>
<view class="flex flex-col items-center" @click="handleHangUp">
<view class="bg-[#eb292b] w-80 h-80 rounded-full flex items-center justify-center">
<image src="https://oss-lock.xhjcn.ltd/mp/icon_hang_up.png" class="w-60 h-60"></image>
</view>
<view class="mt-2">挂断</view>
<view class="mt-2 text-center whitespace-nowrap text-xs">挂断</view>
</view>
<view class="flex flex-col items-center" @click="handleLock">
<view class="bg-[#63b8af] w-80 h-80 rounded-full flex items-center justify-center">
@ -99,7 +99,7 @@
class="w-60 h-60"
></image>
</view>
<view class="mt-2">开锁</view>
<view class="mt-2 text-center whitespace-nowrap text-xs">开锁</view>
</view>
</view>
</view>
@ -123,13 +123,23 @@
import { onUnload } from '@dcloudio/uni-app'
import { useBluetoothStore } from '@/stores/bluetooth'
import { useBasicStore } from '@/stores/basic'
import { useUserStore } from '@/stores/user'
import { passthrough } from '@/api/sdk'
import { getLockNetTokenRequest } from '@/api/lock'
const $bluetooth = useBluetoothStore()
const $basic = useBasicStore()
const $user = useUserStore()
const buttonInfo = ref(null)
const onlineToken = ref('0')
const lockId = ref()
const time = ref(0)
const pending = ref(false)
const index = ref(1)
const range = ref([
{ name: '标清', value: 'standard' },
@ -166,6 +176,8 @@
} else {
$basic.backAndToast(message)
}
await getServeTime()
})
onUnload(() => {
@ -213,7 +225,110 @@
}
const handleLock = () => {
console.log('handleLock')
uni.showModal({
title: '提示',
content: '是否确认开锁?',
success: res => {
if (res.confirm) {
openDoorOperate()
}
}
})
}
const getServeTime = async () => {
const { code, data } = await $bluetooth.updateServerTimestamp()
if (code === 0) {
time.value = parseInt((data.date - new Date().getTime()) / 1000, 10)
}
}
const openDoorOperate = async () => {
const timestamp = new Date().getTime()
if (pending.value) {
return
}
const netWork = await $basic.getNetworkType()
if (!netWork) {
return
}
if ($bluetooth.currentLockInfo.appUnlockOnline) {
const result = await getNetToken()
if (!result) {
pending.value = false
return
}
}
uni.showLoading({
title: '开锁中'
})
uni.vibrateLong()
pending.value = true
const openMode = $bluetooth.currentLockInfo.appUnlockOnline ? 1 : 0
const { code } = await $bluetooth.openDoor({
name: $bluetooth.currentLockInfo.lockName,
uid: $user.userInfo.uid.toString(),
openMode,
openTime: parseInt(new Date().getTime() / 1000, 10) + time.value,
onlineToken: onlineToken.value
})
$bluetooth
.syncRecord({
keyId: $bluetooth.keyId.toString(),
uid: $user.userInfo.uid.toString()
})
.then(() => {
$bluetooth.closeBluetoothConnection()
})
uni.reportEvent('open_door', {
result: code,
duration: new Date().getTime() - timestamp
})
if (code === 0) {
uni.showToast({
title: `开门成功`,
icon: 'none'
})
} else if (code === 7) {
uni.showToast({
title: `钥匙过期`,
icon: 'none'
})
} else if (code === 13) {
uni.showToast({
title: `钥匙当前不可用`,
icon: 'none'
})
} else if (code === -1) {
uni.showToast({
title: `开锁失败`,
icon: 'none'
})
}
uni.hideLoading()
pending.value = false
}
const getNetToken = async () => {
const { code, data, message } = await getLockNetTokenRequest({
lockId: lockId.value
})
if (code === 0) {
onlineToken.value = data.token
return true
}
uni.showToast({
title: message,
icon: 'none'
})
return false
}
const startVoice = () => {

View File

@ -353,7 +353,8 @@ export const useBluetoothStore = defineStore('ble', {
const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
const decrypted = sm4.decrypt(cebBinaryData, that.currentLockInfo.commKey, {
mode: 'ecb',
output: 'array'
output: 'array',
padding: 'none'
})
const length = binaryData[10] * 256 + binaryData[11]
console.log('ecb解密后的数据', decrypted)
@ -1275,7 +1276,7 @@ export const useBluetoothStore = defineStore('ble', {
this.currentLockInfo.keyType === 4
? new Date(this.currentLockInfo.endDate).getMinutes()
: 0,
role: 0,
role: Number(this.currentLockInfo.keyRight),
password
}
const { code: addUserCode } = await this.addLockUser(addUserParams)
@ -1313,22 +1314,37 @@ export const useBluetoothStore = defineStore('ble', {
}
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.transport_type === transportType.TRANSPORT_TENCENT_YUN) {
if (that.currentLockInfo.transportType === transportType.TRANSPORT_TENCENT_YUN) {
const content = that.uint8ArrayToHex(binaryData)
const { code, data, message } = await passthrough({
request_method: 'GET',
request_uri: '/api/v1/tencentYun/getTencentTriple',
request_method: 'POST',
request_uri: '/api/v1/tencentYun/CallDeviceActionSync',
post_args: {
lockId: that.currentLockInfo.lockId,
data: binaryData
actionId: 'starcloud_action',
len: content.length,
content
}
})
if (code === 0) {
that.parsingCharacteristicValue(data)
if (code === 0 && data.outputParams) {
that.parsingCharacteristicValue(that.hexToArray(data.outputParams))
} else {
characteristicValueCallback({
code,
@ -1336,10 +1352,14 @@ export const useBluetoothStore = defineStore('ble', {
})
}
} else {
console.log('设备ID', that.currentLockInfo.deviceId)
console.log('设备名称:', that.currentLockInfo.name)
console.log('设备主服务:', that.currentLockInfo.serviceId)
console.log('设备写入特征值:', that.currentLockInfo.writeCharacteristicId)
console.log(
'设备ID',
that.currentLockInfo.deviceId,
'设备名称:',
that.currentLockInfo.name,
'私钥:',
that.currentLockInfo.commKey
)
console.log('设备写入数据:', Array.from(binaryData))
// 次数
@ -1393,6 +1413,7 @@ export const useBluetoothStore = defineStore('ble', {
} else {
headArray[7] = 0x23
}
console.log('包标识', headArray[7])
// 数据长度
if (encryptionType === 0) {
@ -1563,7 +1584,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -1575,7 +1596,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -1765,7 +1786,7 @@ export const useBluetoothStore = defineStore('ble', {
}
const { SSID, password, json } = data
const length = 2 + 30 + 20 + json.length
const length = 2 + 30 + 20 + 2 + json.length
const headArray = this.createPackageHeader(3, length)
const contentArray = new Uint8Array(length)
@ -1788,7 +1809,8 @@ export const useBluetoothStore = defineStore('ble', {
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
mode: 'ecb',
output: 'array'
output: 'array',
padding: 'none'
})
const packageArray = this.createPackageEnd(headArray, cebArray)
@ -1816,7 +1838,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -1828,7 +1850,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -2111,7 +2133,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -2189,7 +2211,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code === 0) {
@ -2449,7 +2471,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -2461,7 +2483,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -2544,7 +2566,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -2556,7 +2578,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -2625,7 +2647,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -2637,7 +2659,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -2714,7 +2736,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -2726,7 +2748,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -2830,7 +2852,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -2842,7 +2864,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -3029,7 +3051,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -3041,7 +3063,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -3156,7 +3178,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -3168,7 +3190,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -3258,7 +3280,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -3270,7 +3292,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -3365,7 +3387,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -3377,7 +3399,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {
@ -3449,7 +3471,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认蓝牙状态正常
if (
this.bluetoothStatus !== 0 &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
@ -3461,7 +3483,7 @@ export const useBluetoothStore = defineStore('ble', {
// 确认设备连接正常
if (
!this.currentLockInfo.connected &&
this.currentLockInfo.transport_type !== transportType.TRANSPORT_TENCENT_YUN
this.currentLockInfo.transportType !== transportType.TRANSPORT_TENCENT_YUN
) {
const searchResult = await this.searchAndConnectDevice()
if (searchResult.code !== 0) {