feat: 完成twcall相关UI+逻辑
This commit is contained in:
parent
920e5f3c33
commit
1c93dc914b
20
App.vue
20
App.vue
@ -39,6 +39,8 @@
|
||||
this.updateMiniProgram()
|
||||
// 监听蓝牙开关状态
|
||||
this.onBluetoothState()
|
||||
// 设置voip配置
|
||||
this.setVoipConfig()
|
||||
// 检查蓝牙权限
|
||||
const checkResult = await this.checkSetting()
|
||||
console.log(checkResult)
|
||||
@ -65,6 +67,24 @@
|
||||
'initAndListenBluetooth'
|
||||
]),
|
||||
...mapActions(useUserStore, ['updateLoginStatus']),
|
||||
// voip设置
|
||||
setVoipConfig() {
|
||||
const wmpfVoip = requirePlugin('wmpf-voip').default
|
||||
wmpfVoip.setUIConfig({
|
||||
btnText: '去开门',
|
||||
customBoxHeight: '75vh',
|
||||
listenerUI: {
|
||||
cameraRotation: 270,
|
||||
objectFit: 'fill',
|
||||
enableToggleCamera: false
|
||||
}
|
||||
})
|
||||
wmpfVoip.setVoipEndPagePath({
|
||||
url: '/pages/main/home',
|
||||
key: 'Call',
|
||||
routeType: 'switchTab'
|
||||
})
|
||||
},
|
||||
// 强制升级
|
||||
updateMiniProgram() {
|
||||
const updateManager = uni.getUpdateManager()
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import request from '../utils/request'
|
||||
|
||||
// p2p 模块
|
||||
// sdk 模块
|
||||
|
||||
// 获取p2pInfo
|
||||
export function getP2pInfo(data) {
|
||||
// 透传
|
||||
export function passthrough(data) {
|
||||
return request({
|
||||
url: '/passthrough',
|
||||
method: 'POST',
|
||||
@ -29,6 +29,15 @@
|
||||
"version": "latest",
|
||||
"provider": "wx1319af22356934bf",
|
||||
"export": "exportForXp2pPlugin.js"
|
||||
},
|
||||
"wmpf-voip": {
|
||||
"version": "latest",
|
||||
"provider": "wxf830863afde621eb",
|
||||
"genericsImplementation": {
|
||||
"call-page-plugin": {
|
||||
"custombox": "pages/main/customBox"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -38,10 +38,6 @@
|
||||
"version": "latest",
|
||||
"provider": "wx9e8fbc98ceac2628",
|
||||
"export": "exportForPlayerPlugin.js"
|
||||
},
|
||||
"wmpf-voip": {
|
||||
"version": "latest",
|
||||
"provider": "wxf830863afde621eb"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -579,6 +575,9 @@
|
||||
{
|
||||
"path": "pages/main/mine"
|
||||
},
|
||||
{
|
||||
"path": "pages/main/customBox"
|
||||
},
|
||||
{
|
||||
"path": "pages/main/notificationList",
|
||||
"style": {
|
||||
|
||||
185
pages/main/customBox.vue
Normal file
185
pages/main/customBox.vue
Normal file
@ -0,0 +1,185 @@
|
||||
<template>
|
||||
<view class="dialog">
|
||||
<image
|
||||
class="top-background"
|
||||
src="https://oss-lock.xhjcn.ltd/mp/background_main.jpg"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="switch" @click="openDoorOperate">
|
||||
<SwitchLoading :size="220" ref="sLoading"></SwitchLoading>
|
||||
</view>
|
||||
<view class="switch-text">点击开锁</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import SwitchLoading from '@/components/SwitchLoading/SwitchLoading.vue'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { getLockDetailRequest, getLockNetTokenRequest } from '@/api/lock'
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $basic = useBasicStore()
|
||||
const $user = useUserStore()
|
||||
|
||||
const sLoading = ref(null)
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
const lockInfo = ref(null)
|
||||
|
||||
const onlineToken = ref('0')
|
||||
|
||||
const lockId = ref(19335)
|
||||
|
||||
const time = ref(0)
|
||||
|
||||
onMounted(async () => {
|
||||
const { code, data, message } = await getLockDetailRequest({
|
||||
lockId: lockId.value
|
||||
})
|
||||
if (code === 0) {
|
||||
lockInfo.value = data
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
await getServeTime()
|
||||
})
|
||||
|
||||
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 (lockInfo.value.appUnlockOnline) {
|
||||
const result = await getNetToken()
|
||||
if (!result) {
|
||||
sLoading.value.close()
|
||||
pending.value = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
uni.vibrateLong()
|
||||
pending.value = true
|
||||
sLoading.value.open()
|
||||
const openMode = lockInfo.value.appUnlockOnline ? 1 : 0
|
||||
|
||||
const { code } = await $bluetooth.openDoor({
|
||||
name: lockInfo.value.name,
|
||||
uid: $user.userInfo.uid.toString(),
|
||||
openMode,
|
||||
openTime: parseInt(new Date().getTime() / 1000, 10) + time.value,
|
||||
onlineToken: onlineToken.value
|
||||
})
|
||||
|
||||
$bluetooth
|
||||
.syncRecord({
|
||||
keyId: lockInfo.value.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'
|
||||
})
|
||||
}
|
||||
sLoading.value.close()
|
||||
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
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dialog {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 75vh;
|
||||
background-color: #f3f3f3;
|
||||
|
||||
.top-background {
|
||||
position: absolute;
|
||||
width: 686rpx;
|
||||
height: 464rpx;
|
||||
border-radius: 32rpx;
|
||||
}
|
||||
|
||||
.switch {
|
||||
z-index: 99;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 250rpx;
|
||||
height: 250rpx;
|
||||
margin-top: 20rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 8rpx 36rpx 0 rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.switch-text {
|
||||
z-index: 99;
|
||||
margin-top: 10rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -223,7 +223,7 @@
|
||||
</view>
|
||||
<view
|
||||
class="menu-main-view transform-scale-105"
|
||||
@click="$basic.routeJump({ name: 'p2pPlayer' })"
|
||||
@click="$basic.routeJump({ name: 'authorizeWechat' })"
|
||||
>
|
||||
<image
|
||||
class="menu-main-image"
|
||||
|
||||
@ -1,13 +1,149 @@
|
||||
<template>
|
||||
<view>
|
||||
<view>授权微信</view>
|
||||
<view class="mt-10 text-center text-base font-bold text-[#999]">授权后,设备可呼叫该微信</view>
|
||||
<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"
|
||||
@click="handleAuthorize"
|
||||
>
|
||||
授权
|
||||
</view>
|
||||
<view v-else>
|
||||
<view v-if="!reject" class="text-center text-lg font-bold mt-4">您已授权</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="bg-[#63b8af] text-white rounded-full text-center leading-88rpx h-88rpx w-686 mx-4 mt-10"
|
||||
@click="openSetting"
|
||||
>
|
||||
打开设置
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { passthrough } from '@/api/sdk'
|
||||
import { ref } from 'vue'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
|
||||
onLoad(() => {
|
||||
console.log(11111111)
|
||||
const $bluetooth = useBluetoothStore()
|
||||
|
||||
const requestFinish = ref(false)
|
||||
|
||||
const isAuthorized = ref(false)
|
||||
const list = ref([])
|
||||
|
||||
const reject = ref(false)
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
onShow(() => {
|
||||
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.model_id === result.data.WXIoTDeviceInfo.ModelId
|
||||
)
|
||||
if (data) {
|
||||
if (data.status === 1) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
const openSetting = () => {
|
||||
uni.openSetting({
|
||||
success: res => {
|
||||
console.log(res)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getInfo = async () => {
|
||||
const result = await passthrough({
|
||||
request_method: 'GET',
|
||||
request_uri: '/api/v1/tencentYun/getWechatDeviceTicket',
|
||||
post_args: {
|
||||
lockId: $bluetooth.currentLockInfo.lockId
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
const handleAuthorize = async () => {
|
||||
if (pending.value) return
|
||||
pending.value = true
|
||||
uni.showLoading({
|
||||
title: '授权中...'
|
||||
})
|
||||
const result = await getInfo()
|
||||
if (result.code === 0) {
|
||||
wx.requestDeviceVoIP({
|
||||
sn: result.data.WXIoTDeviceInfo.SN,
|
||||
snTicket: result.data.WXIoTDeviceInfo.SNTicket,
|
||||
modelId: result.data.WXIoTDeviceInfo.ModelId,
|
||||
deviceName: '智能',
|
||||
success() {
|
||||
isAuthorized.value = true
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
uni.showToast({
|
||||
title: '授权成功',
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
fail() {
|
||||
isAuthorized.value = true
|
||||
reject.value = true
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
uni.showToast({
|
||||
title: '授权失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
uni.showToast({
|
||||
title: result.message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -123,7 +123,7 @@
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { onUnload } from '@dcloudio/uni-app'
|
||||
import { getP2pInfo } from '@/api/p2p'
|
||||
import { passthrough } from '@/api/sdk'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $basic = useBasicStore()
|
||||
@ -148,7 +148,7 @@
|
||||
onMounted(async () => {
|
||||
buttonInfo.value = await $basic.getButtonInfo()
|
||||
|
||||
const { code, data, message } = await getP2pInfo({
|
||||
const { code, data, message } = await passthrough({
|
||||
request_method: 'GET',
|
||||
request_uri: '/api/v1/tencentYun/getDeviceDetailData',
|
||||
post_args: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user