范鹏 f9669c8d2c 1. 完成锁密码相关功能
2. 完成锁电子钥匙相关功能
2024-08-28 16:55:11 +08:00

386 lines
11 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 v-if="!penging">
<view v-if="isLogin">
<scroll-view v-if="deviceInfo" scroll-y="true" :style="{ height: deviceInfo.windowHeight + 'px' }"
lower-threshold="100" @refresherrefresh="refresherList" :refresher-enabled="true" @scrolltolower="nextPage"
:refresher-triggered="refresherTriggered">
<view class="search">
<up-search :searchIconSize="48" :inputStyle="{ fontSize: '32rpx' }" @focus="getFocus" @blur="getBlur"
:height="80" placeholder="搜索" :clearabled="false" @change="changeSearch"
v-model="search.searchStr" bgColor="#ffffff" :showAction="false" maxlength="20"></up-search>
</view>
<view class="lock-list" v-if="!penging">
<view v-if="lockList.length === 0 && search.searchStr === '' && !focus">
<image src="/static/images/icon_add_round.png" mode="aspectFill" class="button-add-big"
@click="toSearchDevice"></image>
<view class="text">填加锁时手机必须在锁旁边</view>
</view>
<view v-else>
<view class="group" v-for="group in lockList" :key="group.groupId">
<view class="group-name">
<view class="group-name-text">{{group.groupName}}</view>
<view class="group-name-line"></view>
</view>
<view class="lock" v-for="lock in group.lockList" :key="lock.lockId" @click="toLockDeatil(lock)">
<view class="lock-top">
<image class="lock-image-lock" src="/static/images/icon_lock.png"></image>
<view class="lock-top-right">
<view class="lock-top-right-power">
<image class="lock-top-right-power-image" src="/static/images/icon_power.png"></image>
<view class="lock-top-right-power-text">{{lock.electricQuantity}}%</view>
</view>
<view>{{getRole(lock.userType)}}</view>
</view>
</view>
<view class="lock-name">{{lock.lockAlias}}</view>
<view class="lock-time">
<view v-if="lock.keyType === 1" style="font-size: 32rpx">{{ getTimeLimit(lock.keyType) }}</view>
<view v-else>
<view>{{ timeFormat(lock.startDate, 'yyyy-mm-dd h:M') }}</view>
<view>{{ timeFormat(lock.endDate, 'yyyy-mm-dd h:M ') + getTimeLimit(lock.keyType) }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<image v-if="lockList.length !== 0" src="/static/images/icon_add_round.png" mode="aspectFill"
class="button-add" @click="toSearchDevice"></image>
</view>
<view v-else>
<label for="phone">
<view class="button-login">登录</view>
</label>
</view>
</view>
<button open-type="getPhoneNumber" style="display:none" id="phone" @getphonenumber="getphonenumber"></button>
</view>
</template>
<script>
import { timeFormat } from 'uview-plus'
import { getUserInfoRequest, loginRequest } from '@/api/user'
import { useUserStore } from '@/stores/user'
import { useLockStore } from '@/stores/lock'
import { useBluetoothStore } from '@/stores/bluetooth'
import { useBasicStore } from '@/stores/basic'
import { mapState, mapActions } from 'pinia'
export default {
data() {
return {
search: {
pageNo: 1,
pageSize: 50,
searchStr: ''
},
refresherTriggered: false,
focus: false,
penging: true,
deviceInfo: null
}
},
computed: {
...mapState(useUserStore, ['userInfo', 'isLogin']),
...mapState(useLockStore, ['lockList', 'lockTotal']),
...mapState(useBluetoothStore, ['bluetoothStatus', 'isInitBluetooth']),
},
async onLoad() {
uni.showLoading({
title: '加载中'
})
const accountInfo = wx.getAccountInfoSync()
getApp().globalData.appid = accountInfo.miniProgram.appId
this.deviceInfo = await this.getDeviceInfo()
const token = uni.getStorageSync('token')
if(token) {
await this.getUserInfo()
await this.getLockList(this.search)
} else {
await this.homeLogin()
}
this.penging = false
uni.hideLoading()
},
methods: {
timeFormat,
...mapActions(useUserStore, ['updateUserInfo', 'updateLoginStatus', 'phoneLogin', 'getUserInfo']),
...mapActions(useLockStore, ['getLockList', 'getRole', 'getTimeLimit']),
...mapActions(useBluetoothStore, ['getBluetoothStatus', 'initAndListenBluetooth', 'updateCurrentLockInfo',
'checkSetting', 'updateKeyId']),
...mapActions(useBasicStore, ['routeJump', 'getDeviceInfo']),
homeLogin() {
const that = this
return new Promise((resolve) => {
uni.login({
provider: 'weixin',
success: async function (loginRes) {
const { code, data } = await loginRequest({
js_code: loginRes.code
})
if(code === 0) {
uni.setStorageSync('openid', data.openid)
if(data.accessToken) {
uni.setStorageSync('token', data.accessToken)
that.getUserInfo()
that.getLockList(that.search)
that.updateLoginStatus(true)
resolve(true)
} else {
that.updateLoginStatus(false)
resolve(false)
}
} else {
uni.showToast({
title: '登录失败,请重试',
icon: 'none'
})
resolve(false)
}
},
fail: function () {
uni.showToast({
title: '登录失败,请重试',
icon: 'none'
})
resolve(false)
}
})
})
},
async getphonenumber(data) {
if(data.detail.errMsg === 'getPhoneNumber:fail user deny') {
return
}
const result = await this.phoneLogin({
encryptedData: data.detail.encryptedData,
iv: data.detail.iv
})
if(!result) {
uni.showToast({
title: '登录失败,请重试',
icon: 'none'
})
}
},
async nextPage() {
if(this.lockList.length < this.lockTotal) {
this.search.pageNo++
const { code } = await this.getLockList(this.search)
if(code !== 0) {
this.search.pageNo--
}
}
},
async refresherList() {
this.refresherTriggered = true
this.search.pageNo = 1
await this.getLockList(this.search)
uni.showToast({
title: '刷新成功',
icon: 'none'
})
this.refresherTriggered = false
},
async changeSearch(data) {
this.search.searchStr = data
await this.getLockList(this.search)
},
getFocus() {
this.focus = true
},
getBlur() {
this.focus = false
},
async toSearchDevice() {
if(this.bluetoothStatus !== 0) {
this.getBluetoothStatus()
return
}
let result = true
if(!this.isInitBluetooth) {
result = await this.initAndListenBluetooth()
}
if(result) {
this.routeJump({
name: 'searchDevice'
})
} else {
this.checkSetting()
}
},
async toLockDeatil(lock) {
if(this.bluetoothStatus !== 0) {
this.getBluetoothStatus()
return
}
let result = true
if(!this.isInitBluetooth) {
result = await this.initAndListenBluetooth()
}
if(result) {
const data = {
...lock,
name: lock.bluetooth.bluetoothDeviceName,
deviceId: lock.bluetooth.bluetoothDeviceId,
commKey: lock.bluetooth.privateKey,
signKey: lock.bluetooth.signKey,
publicKey: lock.bluetooth.publicKey,
}
this.updateKeyId(lock.keyId.toString())
this.updateCurrentLockInfo(data)
this.routeJump({
name: 'lockDetail'
})
} else {
this.checkSetting()
}
}
}
}
</script>
<style lang="scss">
page {
background-color: $uni-bg-color-grey;
}
</style>
<style scoped lang="scss">
.search {
margin-top: 32rpx;
width: 686rpx !important;
margin-left: 32rpx;
}
.button-login {
margin-top: 40vh;
border-radius: 46rpx;
width: 650rpx;
height: 120rpx;
line-height: 120rpx;
text-align: center;
margin-left: 50rpx;
background: #63b8af;
color: #ffffff;
font-size: 48rpx;
font-weight: bold;
}
.button-add {
width: 120rpx;
height: 120rpx;
position: fixed;
right: 50rpx;
bottom: 50rpx;
border-radius: 50%;
}
.lock-list {
padding-bottom: 32rpx;
width: 672rpx;
margin-left: 39rpx;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.lock {
margin-top: 32rpx;
width: 320rpx;
height: 300rpx;
background: #FFFFFF;
box-shadow: 0 8rpx 36rpx 0 rgba(0,0,0,0.12);
border-radius: 32rpx;
.lock-name {
padding: 0 24rpx;
font-size: 32rpx;
font-weight: bold;
word-break: break-all;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
}
.lock-time {
padding: 12rpx 24rpx 0 24rpx;
font-size: 22rpx;
font-weight: bold;
}
.lock-top {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 24rpx 12rpx 24rpx;
font-size: 22rpx;
.lock-image-lock {
width: 64rpx;
height: 64rpx;
}
.lock-top-right-power {
display: flex;
align-items: center;
.lock-top-right-power-image {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
}
}
}
.group {
width: 672rpx;
margin-top: 32rpx;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.group-name {
width: 672rpx;
display: flex;
align-items: center;
font-size: 32rpx;
font-weight: bold;
}
.group-name-text {
padding: 0 32rpx;
}
.group-name-line {
flex-grow: 1;
height: 3rpx;
background: #E5E5E5;
}
}
}
.button-add-big {
width: 400rpx;
height: 400rpx;
margin-top: 250rpx;
margin-left: 136rpx;
}
.text {
width: 672rpx;
font-size: 32rpx;
color: #999999;
text-align: center;
margin-top: 32rpx;
font-weight: bold;
}
</style>