wx-starlock/pages/lockDetail/lockDetail.vue
2024-09-02 17:18:14 +08:00

353 lines
9.3 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="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="/static/images/icon_power.png" 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>
</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
}
},
computed: {
...mapState(useBluetoothStore, ['currentLockInfo', 'keyId']),
...mapState(useUserStore, ['userInfo']),
...mapState(useLockStore, ['lockSearch']),
},
components: {
SwitchLoading
},
onLoad() {
uni.setNavigationBarTitle({
title: this.currentLockInfo.lockAlias
})
this.getServeTime()
},
methods: {
...mapActions(useLockStore, ['getRole', 'updateLockSearch', 'getLockList']),
...mapActions(useBluetoothStore, ['openDoor', 'updateServerTimestamp']),
...mapActions(useBasicStore, ['routeJump', 'backAndToast']),
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
}
uni.vibrateLong()
this.pending = true
this.$refs.loading.open()
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
})
if(code === 0) {
uni.showToast({
title: `${type === 'close' ? '关' : '开'}锁成功`,
icon: 'none'
})
} else if(code === 13) {
uni.showToast({
title: `只能在循环时间内操作门锁`,
icon: 'none'
})
} else {
uni.showToast({
title: `${type === 'close' ? '关' : '开'}锁失败,请保证在锁附近`,
icon: 'none'
})
}
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)
}
}
this.$refs.loading.close()
this.pending = false
}
}
}
</script>
<style lang="scss" scoped>
.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: 50rpx;
}
.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>