wx-starlock/pages/lockDetail/lockDetail.vue
范鹏 f39916214b 1. 修改断开设备连接位置
2. ios添加未打开微信定位权限引导
2024-09-05 18:28:56 +08:00

443 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<view class="days" v-if="currentLockInfo.days">钥匙将在{{ currentLockInfo.days }}天后失效</view>
<view class="lock-name">{{ currentLockInfo.lockAlias }}</view>
<view class="top">
<image class="top-background" src="/static/images/background_main.jpg" mode="aspectFill"></image>
<view style="width: 100%;height: 50rpx">
<view class="power" @click="powerTip">
<image class="power-icon" :src="getPowerIcon(currentLockInfo.electricQuantity)" mode="aspectFill"></image>
<view class="power-text">{{ currentLockInfo.electricQuantity }}%</view>
<image class="power-tips" src="/static/images/icon_tips.png" mode="aspectFill"></image>
</view>
</view>
<view class="switch" @click="openDoorOperate('open')" @longpress="openDoorOperate('close')">
<SwitchLoading :size="220" ref="loading"></SwitchLoading>
</view>
<view class="switch-text">点击开锁长按闭锁</view>
<view class="bottom">
<view class="bottom-side">
<image class="bottom-icon" src="/static/images/icon_role.png" mode="aspectFill"></image>
<view>{{ getRole(currentLockInfo.userType, currentLockInfo.keyRight) }}</view>
</view>
<view class="bottom-side">
<image class="bottom-icon" :src=" currentLockInfo.lockSetting.appUnlockOnline ?
'/static/images/icon_cloud_active.png' : '/static/images/icon_cloud.png' "
mode="aspectFill" style="width: 40rpx;height: 40rpx;"></image>
<view :style="{color: currentLockInfo.lockSetting.appUnlockOnline ? '#63b8af' : '#a3a3a3'}">手机需联网</view>
</view>
</view>
</view>
<view class="menu" v-if="currentLockInfo.keyRight === 1">
<view class="menu-title">
<image class="menu-image" src="/static/images/icon_menu.png"></image>
<view>功能</view>
</view>
<view class="menu-main">
<view v-if="currentLockInfo.keyRight === 1"
class="menu-main-view" @click="routeJump({ name: 'keyList' })">
<image class="menu-main-image" src="/static/images/tabbar_key_select.png"></image>
<view>电子钥匙</view>
</view>
<view v-if="currentLockInfo.lockFeature.password || currentLockInfo.keyRight === 1"
class="menu-main-view" @click="routeJump({ name: 'passwordList' })">
<image class="menu-main-image" src="/static/images/icon_lock_transparent.png"></image>
<view>密码</view>
</view>
</view>
</view>
<view class="setting" @click="routeJump({ name: 'setting' })">
<image class="setting-image" src="/static/images/icon_setting.png"></image>
<view class="setting-text">设置</view>
<image class="setting-arrow" mode="aspectFill" src="/static/images/icon_arrow.png"></image>
</view>
<up-popup :show="show" @close="closePopup" mode="center" :closeOnClickOverlay="true" bgColor="transparent">
<view class="popup" @click="closePopup">
<image class="popup-background" :src="type === 'close' ? '/static/images/background_close_door.png' :
'/static/images/background_open_door.png'"
mode="aspectFill"></image>
<view>
<view class="popup-name">{{ currentLockInfo.lockAlias }}</view>
<view class="popup-time">{{ timeFormat('', 'mm/dd h:M') }}</view>
</view>
</view>
</up-popup>
</view>
</template>
<script>
import { useBluetoothStore } from '@/stores/bluetooth'
import { useBasicStore } from '@/stores/basic'
import { mapState, mapActions } from 'pinia'
import SwitchLoading from '@/components/SwitchLoading/SwitchLoading.vue'
import { useLockStore } from '@/stores/lock'
import { useUserStore } from '@/stores/user'
import { getLockNetTokenRequest } from '@/api/lock'
import { timeFormat } from 'uview-plus'
import { deleteKeyRequest } from '@/api/key'
export default {
data () {
return {
time: 0,
onlineToken: '0',
pending: false,
show: false,
type: ''
}
},
computed: {
...mapState(useBluetoothStore, ['currentLockInfo', 'keyId']),
...mapState(useUserStore, ['userInfo']),
...mapState(useLockStore, ['lockSearch']),
},
components: {
SwitchLoading
},
onLoad() {
this.getServeTime()
},
methods: {
timeFormat,
...mapActions(useLockStore, ['getRole', 'updateLockSearch', 'getLockList', 'getPowerIcon']),
...mapActions(useBluetoothStore, ['openDoor', 'updateServerTimestamp', 'closeBluetoothConnection']),
...mapActions(useBasicStore, ['routeJump', 'backAndToast', 'getNetworkType']),
closePopup() {
this.show = false
},
powerTip() {
const that = this
const time = timeFormat(that.currentLockInfo.electricQuantityDate, 'yyyy-mm-dd h:M')
console.log('更新时间', that.currentLockInfo.electricQuantityDate, time)
uni.showModal({
title: '锁电量更新时间',
content: time,
showCancel: false
})
},
async getNetToken(){
const { code, data, message } = await getLockNetTokenRequest({
lockId: this.currentLockInfo.lockId
})
if(code === 0) {
this.onlineToken = data.token
return true
} else {
uni.showToast({
title: message,
icon: 'none'
})
return false
}
},
async getServeTime() {
const { code, data } = await this.updateServerTimestamp()
if(code === 0) {
this.time = parseInt((data.date - new Date().getTime()) / 1000)
}
},
async openDoorOperate(type) {
if(this.pending) {
return
}
if(this.currentLockInfo.lockSetting.appUnlockOnline) {
const netWork = await this.getNetworkType()
if(!netWork) {
uni.showToast({
title: '网络访问失败,请检查网络是否正常',
icon: 'none'
})
return
}
}
uni.vibrateLong()
this.pending = true
this.$refs.loading.open()
if(type === 'close') {
uni.showToast({
title: `正在尝试闭锁……`,
icon: 'none'
})
}
if(this.currentLockInfo.lockSetting.appUnlockOnline) {
const result = await this.getNetToken()
if(!result) {
this.$refs.loading.close()
this.pending = false
return
}
}
let openMode
if(type === 'close') {
openMode = this.currentLockInfo.lockSetting.appUnlockOnline ? 33 : 32
} else {
openMode = this.currentLockInfo.lockSetting.appUnlockOnline ? 1 : 0
}
const { code } = await this.openDoor({
name: this.currentLockInfo.name,
uid: this.userInfo.uid.toString(),
openMode: openMode,
openTime: parseInt(new Date().getTime() / 1000) + this.time,
onlineToken: this.onlineToken
})
this.closeBluetoothConnection()
if(code === 0) {
this.show = true
this.type = type
setTimeout(() => {
this.show = false
}, 3000)
if(this.currentLockInfo.keyType === 3) {
const { code: deleteKeyCode } = await deleteKeyRequest({
keyId: this.keyId
})
if(deleteKeyCode === 0) {
this.updateLockSearch({
...this.lockSearch,
pageNo: 1
})
this.getLockList(this.lockSearch)
this.backAndToast('单次钥匙已在被使用后删除', 1)
}
}
} else if(code === 13) {
uni.showToast({
title: `只能在循环时间内操作门锁`,
icon: 'none'
})
} else if(code === -1) {
uni.showToast({
title: `${type === 'close' ? '关' : '开'}锁失败,请保证在锁附近`,
icon: 'none'
})
}
this.$refs.loading.close()
this.pending = false
}
}
}
</script>
<style lang="scss" scoped>
.popup {
display: flex;
position: relative;
width: 400rpx;
height: 389rpx;
text-align: center;
flex-wrap: wrap;
.popup-background {
z-index: -1;
width: 400rpx;
height: 389rpx;
position: absolute;
}
.popup-name {
margin-left: 30rpx;
z-index: 9;
margin-top: 180rpx;
color: #676b6d;
width: 340rpx;
max-height: 80rpx;
line-height: 40rpx;
word-break: break-all;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
}
.popup-time {
margin-top: 10rpx;
width: 400rpx;
}
}
.days {
line-height: 60rpx;
background: #faecc9;
color: #bc9839;
text-align: center;
font-size: 32rpx;
width: 750rpx;
height: 60rpx;
}
.lock-name {
text-align: center;
font-size: 32rpx;
padding: 32rpx 32rpx 0 32rpx;
font-weight: bold;
}
.top {
margin-top: 32rpx;
margin-left: 32rpx;
width: 686rpx;
height: 464rpx;
border-radius: 32rpx;
position: relative;
.top-background {
z-index: -1;
position: absolute;
width: 686rpx;
height: 464rpx;
border-radius: 32rpx;
}
.switch {
margin-top: 20rpx;
margin-left: 218rpx;
display: flex;
justify-content: center;
align-items: center;
width: 250rpx;
height: 250rpx;
background: #FFFFFF;
border-radius: 50%;
box-shadow: 0 8rpx 36rpx 0 rgba(0,0,0,0.12);
}
.power {
float: right;
padding-top: 18rpx;
//width: 100%;
display: flex;
align-items: center;
height: 50rpx;
justify-content: flex-end;
.power-icon {
width: 50rpx;
margin-right: 10rpx;
height: 30rpx;
}
.power-text {
font-size: 32rpx;
font-weight: bold;
margin-right: 10rpx;
line-height: 50rpx;
}
.power-tips {
margin-right: 32rpx;
width: 40rpx;
height: 40rpx;
}
}
.switch-text {
margin-top: 10rpx;
text-align: center;
}
}
.bottom {
width: 686rpx;
position: absolute;
bottom: 0;
display: flex;
align-items: center;
background-color: rgba(0, 0, 0, 0.1);
height: 48rpx;
line-height: 48rpx;
font-size: 32rpx;
color: #63b8af;
border-radius: 0 0 32rpx 32rpx;
justify-content: space-around;
.bottom-side {
display: flex;
align-items: center;
}
.bottom-icon {
width: 32rpx;
height: 32rpx;
margin-right: 10rpx;
}
}
.menu {
margin-top: 32rpx;
margin-left: 32rpx;
padding-bottom: 32rpx;
width: 686rpx;
background-color: #ffffff;
border-radius: 32rpx;
box-shadow: 0 8rpx 36rpx 0 rgba(0,0,0,0.12);
font-size: 40rpx;
.menu-title {
padding: 24rpx 32rpx;
display: flex;
align-items: center;
}
.menu-image {
margin-right: 40rpx;
width: 40rpx;
height: 40rpx;
}
.menu-main {
padding-top: 32rpx;
padding-bottom: 32rpx;
display: flex;
align-items: center;
font-size: 32rpx;
flex-wrap: wrap;
text-align: center;
margin-left: 43rpx;
.menu-main-view {
width: 150rpx;
.menu-main-image {
filter: sepia(100%) saturate(10000%) hue-rotate(180deg) brightness(0.1);
margin-bottom: 10rpx;
width: 40rpx;
height: 40rpx;
}
}
}
}
.setting {
padding: 24rpx 0;
margin-top: 32rpx;
margin-left: 32rpx;
display: flex;
align-items: center;
width: 686rpx;
background-color: #ffffff;
border-radius: 32rpx;
box-shadow: 0 8rpx 36rpx 0 rgba(0,0,0,0.12);
font-size: 40rpx;
.setting-text {
margin-left: 32rpx;
}
.setting-arrow {
margin-right: 32rpx;
width: 48rpx;
height: 48rpx;
margin-left: auto;
}
.setting-image {
margin-left: 32rpx;
width: 48rpx;
height: 48rpx;
}
}
</style>