fix: 修改订阅设备逻辑

This commit is contained in:
fanpeng 2025-06-06 09:05:03 +08:00
parent 34e3a49d53
commit 1e04659c79
2 changed files with 271 additions and 70 deletions

View File

@ -11,15 +11,27 @@
<view v-else>
<view v-if="!reject" class="text-center text-2xl font-bold">您已授权</view>
<view v-else>
<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 v-if="weChatTicketsFlag">
<view class="text-center text-lg font-bold mt-6"> 授权失败 </view>
<view class="text-center text-lg font-bold mt-4"> 请保证设备一直处于在线状态 </view>
<view
class="bg-[#63b8af] text-white rounded-full text-center leading-88rpx h-88rpx w-686 mx-4 mt-10"
@click="retry"
>
重试
</view>
</view>
<view
class="bg-[#63b8af] text-white rounded-full text-center leading-88rpx h-88rpx w-686 mx-4 mt-10"
@click="openSetting"
>
打开设置
<view v-else>
<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"
>
打开设置
</view>
</view>
</view>
</view>
@ -52,57 +64,76 @@
const pending = ref(false)
onShow(() => {
const weChatTicketsFlag = ref(false)
onShow(async () => {
uni.showLoading({
title: '加载中...'
})
wx.getDeviceVoIPList({
async success(res) {
list.value = res.list
if (res.list.length > 0) {
const result = await getInfo()
if (result.code === 0) {
const data = list.value.find(item => item.sn === result.data.WXIoTDeviceInfo.SN)
if (data) {
if (data.status === 1) {
if (reject.value) {
passthrough({
request_method: 'POST',
request_uri: '/api/v1/tencentYun/reportWechatAuthSuccess',
post_args: {
lockId: $bluetooth.currentLockInfo.lockId,
wxOpenid: getStorage('openid'),
wxDeviceSn: result.data.WXIoTDeviceInfo.SNTicket
}
})
}
reject.value = false
} else if (data.status === 0) {
reject.value = true
}
isAuthorized.value = true
requestFinish.value = true
uni.hideLoading()
} else {
requestFinish.value = true
uni.hideLoading()
}
} else {
uni.showToast({
title: result.message,
icon: 'none'
})
requestFinish.value = true
uni.hideLoading()
}
} else {
requestFinish.value = true
uni.hideLoading()
}
const resultList = await Promise.all([getDeviceVoIPList(), getAuthResult()])
list.value = resultList[0]
const authResult = resultList[1]
const data = list.value.find(item => item.sn === authResult.data.wxDeviceSn)
if (authResult?.code === 0 && authResult?.data?.wxOpenid === getStorage('openid') && data) {
isAuthorized.value = true
requestFinish.value = true
if (data.status === 1) {
reject.value = false
} else if (data.status === 0) {
reject.value = true
weChatTicketsFlag.value = true
}
})
uni.hideLoading()
} else {
requestFinish.value = true
uni.hideLoading()
}
})
const getDeviceVoIPList = async () => {
return new Promise(resolve => {
wx.getDeviceVoIPList({
success: res => {
resolve(res.list)
}
})
})
}
const retry = async () => {
if (pending.value) return
uni.showLoading({
title: '授权中...'
})
pending.value = true
const ticketsResult = await weChatTickets()
pending.value = false
if (ticketsResult?.code === 0) {
passthrough({
request_method: 'POST',
request_uri: '/api/v1/tencentYun/reportWechatAuthSuccess',
post_args: {
lockId: $bluetooth.currentLockInfo.lockId,
wxOpenid: getStorage('openid'),
wxDeviceSn: ticketsResult.data.wxDeviceSn
}
})
uni.hideLoading()
isAuthorized.value = true
} else {
uni.hideLoading()
uni.showToast({
title: '授权失败',
icon: 'none'
})
}
}
const openSetting = () => {
uni.openSetting({
success: res => {
@ -111,6 +142,18 @@
})
}
const getAuthResult = async () => {
const result = await passthrough({
request_method: 'GET',
request_uri: '/api/v1/tencentYun/checkWechatAuth',
post_args: {
lockId: $bluetooth.currentLockInfo.lockId,
wxOpenid: getStorage('openid')
}
})
return result
}
const getInfo = async () => {
const result = await passthrough({
request_method: 'GET',
@ -122,6 +165,29 @@
return result
}
const weChatTickets = async (snTicket, sn) => {
let ticket = snTicket
let snResult = sn
if (!snTicket) {
const result = await getInfo()
ticket = result.data.WXIoTDeviceInfo.SNTicket
snResult = result.data.WXIoTDeviceInfo.SN
}
const result = await $bluetooth.weChatTickets({
keyId: $bluetooth.currentLockInfo.keyId.toString(),
uid: $bluetooth.currentLockInfo.uid.toString(),
openId: getStorage('openid'),
snTicket: ticket
})
return {
code: result.code,
data: {
wxDeviceSn: snResult
}
}
}
const handleAuthorize = async () => {
if (pending.value) return
pending.value = true
@ -136,22 +202,39 @@
modelId: result.data.WXIoTDeviceInfo.ModelId,
deviceName: await env[await getApp().globalData.getEnvConfig()].appName,
async success() {
isAuthorized.value = true
uni.hideLoading()
pending.value = false
passthrough({
request_method: 'POST',
request_uri: '/api/v1/tencentYun/reportWechatAuthSuccess',
post_args: {
lockId: $bluetooth.currentLockInfo.lockId,
wxOpenid: getStorage('openid'),
wxDeviceSn: result.data.WXIoTDeviceInfo.SNTicket
}
})
uni.showToast({
title: '授权成功',
icon: 'none'
})
const ticketsResult = await weChatTickets(
result.data.WXIoTDeviceInfo.SNTicket,
result.data.WXIoTDeviceInfo.SN
)
if (ticketsResult?.code === 0) {
isAuthorized.value = true
uni.hideLoading()
pending.value = false
passthrough({
request_method: 'POST',
request_uri: '/api/v1/tencentYun/reportWechatAuthSuccess',
post_args: {
lockId: $bluetooth.currentLockInfo.lockId,
wxOpenid: getStorage('openid'),
wxDeviceSn: result.data.WXIoTDeviceInfo.SN
}
})
uni.showToast({
title: '授权成功',
icon: 'none'
})
} else {
isAuthorized.value = true
uni.hideLoading()
pending.value = false
reject.value = true
weChatTicketsFlag.value = true
uni.showToast({
title: '授权失败',
icon: 'none'
})
}
},
fail() {
isAuthorized.value = true

View File

@ -116,7 +116,9 @@ const subCmdIds = {
// 修改设置
updateSetting: 70,
// 修改设置带参数
updateSettingWithParams: 72
updateSettingWithParams: 72,
// 微信票据
weChatTickets: 55
}
export const useBluetoothStore = defineStore('ble', {
@ -482,6 +484,21 @@ export const useBluetoothStore = defineStore('ble', {
}
})
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:
@ -2861,6 +2878,107 @@ export const useBluetoothStore = defineStore('ble', {
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]