1. 完成锁密码相关功能
2. 完成锁电子钥匙相关功能
This commit is contained in:
parent
2fc7ad7ed7
commit
f9669c8d2c
4
App.vue
4
App.vue
@ -10,7 +10,9 @@
|
||||
// 更新登录状态
|
||||
updateIsLogin(isLogin) {
|
||||
useUserStore().updateLoginStatus(isLogin)
|
||||
}
|
||||
},
|
||||
// 账号信息
|
||||
appid: ''
|
||||
},
|
||||
computed: {
|
||||
...mapState(useBluetoothStore, ['bluetoothStatus']),
|
||||
|
||||
39
api/key.js
Normal file
39
api/key.js
Normal file
@ -0,0 +1,39 @@
|
||||
import request from '../utils/request'
|
||||
|
||||
// key 电子钥匙模块
|
||||
|
||||
// 获取电子钥匙列表
|
||||
export function getKeyListRequest(data) {
|
||||
return request({
|
||||
url: '/key/listUser',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 重置电子钥匙
|
||||
export function resetKeyRequest(data) {
|
||||
return request({
|
||||
url: '/key/reset',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 创建电子钥匙
|
||||
export function createKeyRequest(data) {
|
||||
return request({
|
||||
url: '/v2/key/send',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除电子钥匙
|
||||
export function deleteKeyRequest(data) {
|
||||
return request({
|
||||
url: '/key/delete',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
39
api/keyboardPwd.js
Normal file
39
api/keyboardPwd.js
Normal file
@ -0,0 +1,39 @@
|
||||
import request from '../utils/request'
|
||||
|
||||
// keyboardPwd 锁密码模块
|
||||
|
||||
// 获取密码列表
|
||||
export function getPsaawordListRequest(data) {
|
||||
return request({
|
||||
url: '/keyboardPwd/listSendRecords',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
export function resetPsaawordListRequest(data) {
|
||||
return request({
|
||||
url: '/keyboardPwd/reset',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 创建密码
|
||||
export function createPsaawordRequest(data) {
|
||||
return request({
|
||||
url: '/keyboardPwd/get',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除密码
|
||||
export function deletePsaawordRequest(data) {
|
||||
return request({
|
||||
url: '/keyboardPwd/delete',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
75
components/LockDatetimePicker/LockDatetimePicker.vue
Normal file
75
components/LockDatetimePicker/LockDatetimePicker.vue
Normal file
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<view>
|
||||
<view @click="changeShow" class="name">
|
||||
<view class="name-text">{{ title }}</view>
|
||||
<view class="picker">
|
||||
{{ timeFormat(time, 'yyyy-mm-dd h:M') }}
|
||||
</view>
|
||||
</view>
|
||||
<up-datetime-picker itemHeight="60" :minDate="minDate" :title="placeholder" :show="show" v-model="time"
|
||||
mode="datetime" @confirm="confirm" :closeOnClickOverlay="true"
|
||||
@close="close"></up-datetime-picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { timeFormat } from 'uview-plus'
|
||||
|
||||
export default {
|
||||
name: 'LockDatetimePicker',
|
||||
props: {
|
||||
title: String,
|
||||
value: Number,
|
||||
minDate: Number,
|
||||
placeholder: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
time: 0,
|
||||
show: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.time = this.value
|
||||
},
|
||||
methods: {
|
||||
timeFormat,
|
||||
changeShow() {
|
||||
this.show = !this.show
|
||||
},
|
||||
close() {
|
||||
this.show = false
|
||||
},
|
||||
confirm(e) {
|
||||
this.show = false
|
||||
this.$emit('changeTime', e.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.name {
|
||||
height: 100rpx;
|
||||
width: 750rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #ffffff;
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
|
||||
.name-text {
|
||||
width: 168rpx;
|
||||
margin-left: 32rpx;
|
||||
line-height: 100rpx;
|
||||
}
|
||||
|
||||
.picker {
|
||||
margin-right: 32rpx;
|
||||
text-align: right;
|
||||
width: 518rpx;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
60
components/LockInput/LockInput.vue
Normal file
60
components/LockInput/LockInput.vue
Normal file
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="name">
|
||||
<view class="name-text">{{ title }}</view>
|
||||
<input :value="value" class="name-input" :placeholder="placeholder" placeholder-class="placeholder-class"
|
||||
maxlength="16" @input="changeInput"></input>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'LockInput',
|
||||
props:{
|
||||
title: String,
|
||||
placeholder: String,
|
||||
value: String
|
||||
},
|
||||
methods: {
|
||||
changeInput(e) {
|
||||
this.$emit('changeInput', e.detail.value)
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.name {
|
||||
height: 100rpx;
|
||||
width: 750rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #ffffff;
|
||||
|
||||
.name-text {
|
||||
width: 168rpx;
|
||||
margin-left: 32rpx;
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
line-height: 100rpx;
|
||||
}
|
||||
|
||||
.name-input {
|
||||
margin-right: 32rpx;
|
||||
text-align: right;
|
||||
width: 518rpx;
|
||||
height: 100rpx;
|
||||
font-size: 32rpx;
|
||||
line-height: 100rpx;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder-class {
|
||||
text-align: right;
|
||||
font-size: 32rpx;
|
||||
line-height: 100rpx;
|
||||
}
|
||||
</style>
|
||||
16
pages.json
16
pages.json
@ -112,14 +112,30 @@
|
||||
{
|
||||
"path": "pages/passwordList/passwordList",
|
||||
"style": {
|
||||
"disableScroll": true,
|
||||
"navigationBarTitleText": "密码"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/createPassword/createPassword",
|
||||
"style": {
|
||||
"disableScroll": true,
|
||||
"navigationBarTitleText": "获取密码"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/passwordDetail/passwordDetail",
|
||||
"style": {
|
||||
"disableScroll": true,
|
||||
"navigationBarTitleText": "密码详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/keyDetail/keyDetail",
|
||||
"style": {
|
||||
"disableScroll": true,
|
||||
"navigationBarTitleText": "钥匙详情"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
@ -1,17 +1,236 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
<view class="tabs">
|
||||
<up-tabs :list="tabs" lineWidth="40rpx" lineHeight="5rpx" :current="currnetIndex" lineColor="#63b8af"
|
||||
@click="clickTab" :inactiveStyle="{color:'#a3a3a3', fontSize: '32rpx', fontWeight: 'bold'}"
|
||||
:activeStyle="{color:'#63b8af', fontSize: '32rpx', fontWeight: 'bold'}">
|
||||
</up-tabs>
|
||||
</view>
|
||||
<swiper :style="{height: deviceInfo.screenHeight - deviceInfo.safeArea.top - 44 + 'px'}" v-if="deviceInfo"
|
||||
:list="tabs" :autoplay="false"
|
||||
:circular="true" :current="currnetIndex" @change="changeSwiper">
|
||||
<swiper-item>
|
||||
<LockInput :value="permanentAccount" title="接收者账号" placeholder="请输入手机号或邮箱"
|
||||
@changeInput="changePermanentAccountInput"></LockInput>
|
||||
<LockInput :value="permanentName" title="钥匙名称" placeholder="请输入钥匙名称"
|
||||
@changeInput="changePermanentNmaeInput"></LockInput>
|
||||
<view class="text">接收者可使用此小程序开关锁</view>
|
||||
<view class="button" @click="createKey('permanent')">发送钥匙</view>
|
||||
</swiper-item>
|
||||
<swiper-item :style="{height: deviceInfo.windowHeight - 44 + 'px'}">
|
||||
<LockInput :value="temporaryAccount" title="接收者账号" placeholder="请输入手机号或邮箱"
|
||||
@changeInput="changeTemporaryAccountInput"></LockInput>
|
||||
<LockInput :value="temporaryName" title="钥匙名称" placeholder="请输入钥匙名称"
|
||||
@changeInput="changeTemporaryNameInput"></LockInput>
|
||||
<view style="margin-top: 20rpx">
|
||||
<LockDatetimePicker title="生效时间" :value="temporaryValidTime" :minDate="minDate"
|
||||
placeholder="请选择失效时间" @changeTime="changeTemporaryValidTime"></LockDatetimePicker>
|
||||
<LockDatetimePicker title="失效时间" :value="temporaryInvalidTime" :minDate="minDate"
|
||||
placeholder="请选择失效时间" @changeTime="changeTemporaryInvalidTime"></LockDatetimePicker>
|
||||
</view>
|
||||
<view class="text">接收者在有效期内可以不限次数使用</view>
|
||||
<view class="button" @click="createKey('temporary')">发送钥匙</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapActions, mapState } from 'pinia'
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
import LockInput from '@/components/LockInput/LockInput.vue'
|
||||
import LockDatetimePicker from '@/components/LockDatetimePicker/LockDatetimePicker.vue'
|
||||
import { createPsaawordRequest } from '@/api/keyboardPwd'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { useLockStore } from '@/stores/lock'
|
||||
import { test } from 'uview-plus'
|
||||
import { createKeyRequest } from '@/api/key'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
return {
|
||||
tabs: [{
|
||||
name: '永久'
|
||||
}, {
|
||||
name: '限时'
|
||||
}],
|
||||
permanentName: '',
|
||||
permanentAccount: '',
|
||||
temporaryName: '',
|
||||
temporaryAccount: '',
|
||||
temporaryValidTime: Number(new Date()),
|
||||
temporaryInvalidTime: Number(new Date()),
|
||||
minDate: Number(new Date()),
|
||||
currnetIndex: 0,
|
||||
deviceInfo: null,
|
||||
pending: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
LockInput,
|
||||
LockDatetimePicker
|
||||
},
|
||||
computed: {
|
||||
...mapState(useBluetoothStore, ['currentLockInfo']),
|
||||
...mapState(useLockStore, ['keySearch']),
|
||||
},
|
||||
async onLoad () {
|
||||
this.deviceInfo = await this.getDeviceInfo()
|
||||
this.temporaryInvalidTime = this.setTime()
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useBasicStore, ['getDeviceInfo']),
|
||||
...mapActions(useLockStore, ['getKeyList', 'updateKeySearch']),
|
||||
setTime () {
|
||||
const now = new Date()
|
||||
now.setMinutes(0, 0, 0)
|
||||
now.setDate(now.getDate() + 3)
|
||||
|
||||
return now.getTime()
|
||||
},
|
||||
async createKey (type, createUser = false) {
|
||||
|
||||
if ((type === 'temporary' && !(test.email(this.temporaryAccount) || test.mobile(this.temporaryAccount))) ||
|
||||
(type === 'permanent' && !(test.email(this.permanentAccount) || test.mobile(this.permanentAccount)))) {
|
||||
uni.showToast({
|
||||
title: '请输入格式正确的手机号或邮箱',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if ((type === 'temporary' && this.temporaryName === '') || (type === 'permanent' && this.permanentName === '')) {
|
||||
uni.showToast({
|
||||
title: '名称不能为空',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if(type === 'temporary' && this.temporaryValidTime >= this.temporaryInvalidTime) {
|
||||
uni.showToast({
|
||||
title: '失效时间必须大于生效时间',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (this.pending) {
|
||||
return
|
||||
}
|
||||
this.pending = true
|
||||
|
||||
let params = {
|
||||
faceAuthentication: '2',
|
||||
isRemoteUnlock: '2',
|
||||
lockId: this.currentLockInfo.lockId,
|
||||
keyRight: '0',
|
||||
remarks: '',
|
||||
countryCode: '86',
|
||||
createUser: '0'
|
||||
}
|
||||
if(createUser) {
|
||||
params.createUser = '1'
|
||||
params.usernameType = test.mobile(this.temporaryAccount) ? '1' : '2'
|
||||
}
|
||||
if (type === 'temporary') {
|
||||
params.keyNameForAdmin = this.temporaryName
|
||||
params.endDate = this.temporaryInvalidTime.toString()
|
||||
params.keyType = '2'
|
||||
params.receiverUsername = this.temporaryAccount
|
||||
params.startDate = this.temporaryValidTime.toString()
|
||||
} else {
|
||||
params.keyNameForAdmin = this.permanentName
|
||||
params.startDate = new Date().getTime().toString()
|
||||
params.endDate = '0'
|
||||
params.keyType = '1'
|
||||
params.receiverUsername = this.permanentAccount
|
||||
}
|
||||
const { code, message } = await createKeyRequest(params)
|
||||
if (code === 0) {
|
||||
this.updateKeySearch({
|
||||
...this.keySearch,
|
||||
pageNo: 1
|
||||
})
|
||||
this.getKeyList(this.keySearch)
|
||||
uni.navigateBack({
|
||||
complete: () => {
|
||||
uni.showToast({
|
||||
title: '钥匙已发送',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else if(code === 425) {
|
||||
this.pending = false
|
||||
await this.createKey(type, true)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
this.pending = false
|
||||
},
|
||||
changePermanentAccountInput (e) {
|
||||
this.permanentAccount = e
|
||||
},
|
||||
changePermanentNmaeInput (e) {
|
||||
this.permanentName = e
|
||||
},
|
||||
changeTemporaryNameInput (e) {
|
||||
this.temporaryName = e
|
||||
},
|
||||
changeTemporaryAccountInput (e) {
|
||||
this.temporaryAccount = e
|
||||
},
|
||||
changeTemporaryValidTime (e) {
|
||||
this.temporaryValidTime = e
|
||||
},
|
||||
changeTemporaryInvalidTime (e) {
|
||||
this.temporaryInvalidTime = e
|
||||
},
|
||||
clickTab (data) {
|
||||
this.currnetIndex = data.index
|
||||
},
|
||||
changeSwiper (e) {
|
||||
this.currnetIndex = e.detail.current
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tabs {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-top: 40rpx;
|
||||
margin-bottom: 50rpx;
|
||||
color: #262626;
|
||||
font-size: 26rpx;
|
||||
padding: 0 32rpx;
|
||||
}
|
||||
|
||||
.button {
|
||||
border-radius: 64rpx;
|
||||
width: 686rpx;
|
||||
margin-left: 32rpx;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
text-align: center;
|
||||
background-color: #63b8af;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,17 +1,207 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
<view class="tabs">
|
||||
<up-tabs :list="tabs" lineWidth="40rpx" lineHeight="5rpx" :current="currnetIndex" lineColor="#63b8af"
|
||||
@click="clickTab" :inactiveStyle="{color:'#a3a3a3', fontSize: '32rpx', fontWeight: 'bold'}"
|
||||
:activeStyle="{color:'#63b8af', fontSize: '32rpx', fontWeight: 'bold'}">
|
||||
</up-tabs>
|
||||
</view>
|
||||
<swiper :style="{height: deviceInfo.screenHeight - deviceInfo.safeArea.top - 44 + 'px'}" v-if="deviceInfo"
|
||||
:list="tabs" :autoplay="false"
|
||||
:circular="true" :current="currnetIndex" @change="changeSwiper">
|
||||
<swiper-item>
|
||||
<LockInput :value="permanentName" title="名称" placeholder="给密码命名"
|
||||
@changeInput="changePermanentInput"></LockInput>
|
||||
<view class="text">{{ text }}</view>
|
||||
<view class="button" @click="createPassword('permanent')">获取密码</view>
|
||||
</swiper-item>
|
||||
<swiper-item :style="{height: deviceInfo.windowHeight - 44 + 'px'}">
|
||||
<LockInput :value="temporaryName" title="名称" placeholder="给密码命名"
|
||||
@changeInput="changeTemporaryInput"></LockInput>
|
||||
<view style="margin-top: 20rpx">
|
||||
<LockDatetimePicker title="失效时间" :value="temporaryTime" :minDate="minDate"
|
||||
placeholder="请选择失效时间" @changeTime="changeTemporaryTime"></LockDatetimePicker>
|
||||
</view>
|
||||
<view class="text">{{ text }}</view>
|
||||
<view class="button" @click="createPassword('temporary')">获取密码</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapActions, mapState } from 'pinia'
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
import LockInput from '@/components/LockInput/LockInput.vue'
|
||||
import LockDatetimePicker from '@/components/LockDatetimePicker/LockDatetimePicker.vue'
|
||||
import { createPsaawordRequest } from '@/api/keyboardPwd'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { useLockStore } from '@/stores/lock'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
return {
|
||||
tabs: [{
|
||||
name: '永久'
|
||||
}, {
|
||||
name: '限时'
|
||||
}],
|
||||
permanentName: '',
|
||||
temporaryName: '',
|
||||
temporaryTime: Number(new Date()),
|
||||
minDate: Number(new Date()),
|
||||
currnetIndex: 0,
|
||||
deviceInfo: null,
|
||||
pending: false,
|
||||
text: '密码生成后,请在当日23:59前使用一次进行激活,否则过点后未激活则失效。密码激活后,有效期内不限次数使用。'
|
||||
}
|
||||
},
|
||||
components: {
|
||||
LockInput,
|
||||
LockDatetimePicker
|
||||
},
|
||||
computed: {
|
||||
...mapState(useBluetoothStore, ['currentLockInfo']),
|
||||
},
|
||||
async onLoad() {
|
||||
this.deviceInfo = await this.getDeviceInfo()
|
||||
this.temporaryTime = this.setTime()
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useBasicStore, ['getDeviceInfo']),
|
||||
...mapActions(useLockStore, ['getPasswordList']),
|
||||
setTime() {
|
||||
const now = new Date()
|
||||
now.setMinutes(0, 0, 0)
|
||||
now.setDate(now.getDate() + 1)
|
||||
|
||||
return now.getTime()
|
||||
},
|
||||
async createPassword(type) {
|
||||
if((type === 'temporary' && this.temporaryName === '') || (type === 'permanent' && this.permanentName === '')) {
|
||||
uni.showToast({
|
||||
title: '名称不能为空',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if(this.pending) {
|
||||
return
|
||||
}
|
||||
this.pending = true
|
||||
|
||||
let params = {
|
||||
lockId: this.currentLockInfo.lockId,
|
||||
isCoerced: 2,
|
||||
pwdRight: 0
|
||||
}
|
||||
if(type === 'temporary') {
|
||||
params.keyboardPwdName = this.temporaryName
|
||||
params.keyboardPwdType = 3
|
||||
params.startDate = new Date().getTime()
|
||||
params.endDate = this.temporaryTime
|
||||
params.hoursStart = 0
|
||||
params.hoursEnd = 0
|
||||
} else {
|
||||
params.startDate = 0
|
||||
params.endDate = 0
|
||||
params.keyboardPwdName = this.permanentName
|
||||
params.keyboardPwdType = 2
|
||||
params.hoursStart = 0
|
||||
params.hoursEnd = 0
|
||||
}
|
||||
const { code, data, message } = await createPsaawordRequest(params)
|
||||
if(code === 0) {
|
||||
const search = {
|
||||
lockStatus: this.currentLockInfo.lockStatus,
|
||||
lockId: this.currentLockInfo.lockId,
|
||||
pageNo: 1,
|
||||
pageSize: 50
|
||||
}
|
||||
this.getPasswordList(search)
|
||||
uni.showModal({
|
||||
title: '密码生成成功',
|
||||
content: `密码:${data.keyboardPwd}`,
|
||||
cancelText: '复制',
|
||||
success: (res) => {
|
||||
if(res.confirm) {
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
uni.setClipboardData({
|
||||
data: data.keyboardPwd,
|
||||
success: () => {
|
||||
uni.navigateBack({
|
||||
complete: () => {
|
||||
uni.showToast({
|
||||
title: '复制成功',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
this.pending = false
|
||||
},
|
||||
changePermanentInput(e) {
|
||||
this.permanentName = e
|
||||
},
|
||||
changeTemporaryInput(e) {
|
||||
this.temporaryName = e
|
||||
},
|
||||
changeTemporaryTime(e) {
|
||||
this.temporaryTime = e
|
||||
},
|
||||
clickTab(data) {
|
||||
this.currnetIndex = data.index
|
||||
},
|
||||
changeSwiper(e) {
|
||||
this.currnetIndex = e.detail.current
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tabs {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-top: 40rpx;
|
||||
margin-bottom: 50rpx;
|
||||
color: #262626;
|
||||
font-size: 26rpx;
|
||||
padding: 0 32rpx;
|
||||
}
|
||||
|
||||
.button {
|
||||
border-radius: 64rpx;
|
||||
width: 686rpx;
|
||||
margin-left: 32rpx;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
text-align: center;
|
||||
background-color: #63b8af;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -91,6 +91,8 @@
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
})
|
||||
const accountInfo = wx.getAccountInfoSync()
|
||||
getApp().globalData.appid = accountInfo.miniProgram.appId
|
||||
this.deviceInfo = await this.getDeviceInfo()
|
||||
|
||||
const token = uni.getStorageSync('token')
|
||||
|
||||
70
pages/keyDetail/keyDetail.vue
Normal file
70
pages/keyDetail/keyDetail.vue
Normal file
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="item">
|
||||
<view class="item-title">名称</view>
|
||||
<view class="item-content">{{ currentKeyInfo.nickname }}</view>
|
||||
</view>
|
||||
<view class="item" style="margin-top: 2rpx">
|
||||
<view class="item-title">有效期</view>
|
||||
<view v-if="currentKeyInfo.keyType === 1">永久</view>
|
||||
<view v-else>
|
||||
<view class="item-content">{{ timeFormat(currentKeyInfo.startDate, 'yyyy-mm-dd h:M') }}</view>
|
||||
<view class="item-content">{{ timeFormat(currentKeyInfo.endDate, 'yyyy-mm-dd h:M') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item" style="margin-top: 20rpx">
|
||||
<view class="item-title">接收者</view>
|
||||
<view class="item-content">{{ currentKeyInfo.username }}</view>
|
||||
</view>
|
||||
<view class="item" style="margin-top: 2rpx">
|
||||
<view class="item-title">发送人</view>
|
||||
<view class="item-content">{{ currentKeyInfo.senderUsername }}</view>
|
||||
</view>
|
||||
<view class="item" style="margin-top: 2rpx">
|
||||
<view class="item-title">发送时间</view>
|
||||
<view class="item-content">{{ timeFormat(currentKeyInfo.sendDate, 'yyyy-mm-dd h:M') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'pinia'
|
||||
import { useLockStore } from '@/stores/lock'
|
||||
import { timeFormat } from 'uview-plus'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useLockStore, ['currentKeyInfo']),
|
||||
},
|
||||
methods: {
|
||||
timeFormat
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
padding: 24rpx 32rpx;
|
||||
background-color: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tips {
|
||||
padding: 24rpx 32rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
||||
@ -1,17 +1,297 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
<scroll-view v-if="deviceInfo" scroll-y="true" :style="{height: deviceInfo.screenHeight - deviceInfo.safeArea.top + 'px'}" lower-threshold="100"
|
||||
@refresherrefresh="refresherList" :refresher-enabled="true" @scrolltolower="nextPage"
|
||||
:refresher-triggered="refresherTriggered">
|
||||
<view class="search">
|
||||
<up-search shape="square" :searchIconSize="48" :inputStyle="{ fontSize: '32rpx' }" :height="80" placeholder="搜索"
|
||||
:clearabled="false" @change="changeSearch"
|
||||
v-model="keySearch.searchStr" bgColor="#ffffff" :showAction="false" maxlength="20"></up-search>
|
||||
</view>
|
||||
<view style="padding: 32rpx 0 calc(env(safe-area-inset-bottom) + 250rpx) 0">
|
||||
<view v-if="keyList.length === 0 && requestFinished">
|
||||
<image class="empty-list" src="/static/images/background_empty_list.png" mode="aspectFill"></image>
|
||||
<view class="empty-list-text">暂无数据</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<up-swipe-action>
|
||||
<up-swipe-action-item ref="swipeItem" :options="options" v-for="(key, index) in keyList"
|
||||
:key="key.keyboardPwdId" :threshold="50" @click="deleteKey(key)">
|
||||
<view class="key" @click="toKeyDetail(key)">
|
||||
<image class="key-left" :src="key.headUrl" mode="aspectFill"></image>
|
||||
<view class="key-right">
|
||||
<view class="key-right-top">{{ key.keyName }}</view>
|
||||
<view class="key-right-bottom">{{ key.timeText }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
</up-swipe-action-item>
|
||||
</up-swipe-action>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="button">
|
||||
<view class="button-reset" @click="resetKey">重置钥匙</view>
|
||||
<view class="button-create" @click="toCreateKey">发送钥匙</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
import { mapActions, mapState } from 'pinia'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { useLockStore } from '@/stores/lock'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { deletePsaawordRequest, resetPsaawordListRequest } from '@/api/keyboardPwd'
|
||||
import { deleteKeyRequest, resetKeyRequest } from '@/api/key'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
return {
|
||||
deviceInfo: null,
|
||||
refresherTriggered: false,
|
||||
requestFinished: false,
|
||||
options: [{
|
||||
text: '删除',
|
||||
style: {
|
||||
backgroundColor: '#f56c6c'
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, ['userInfo']),
|
||||
...mapState(useBluetoothStore, ['currentLockInfo', 'keyId']),
|
||||
...mapState(useLockStore, ['keyTotal', 'keyList', 'keySearch']),
|
||||
},
|
||||
async onLoad() {
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
})
|
||||
this.deviceInfo = await this.getDeviceInfo()
|
||||
this.updateKeySearch({
|
||||
...this.keySearch,
|
||||
lockId: this.currentLockInfo.lockId
|
||||
})
|
||||
const { code, meesage } = await this.getKeyList(this.keySearch)
|
||||
this.requestFinished = true
|
||||
uni.hideLoading()
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useBasicStore, ['routeJump', 'getDeviceInfo']),
|
||||
...mapActions(useLockStore, ['getKeyList', 'updateCurrentKeyInfo', 'updateKeySearch']),
|
||||
toKeyDetail(key) {
|
||||
this.updateCurrentKeyInfo(key)
|
||||
this.routeJump({
|
||||
name: 'keyDetail'
|
||||
})
|
||||
},
|
||||
async deleteKey(data) {
|
||||
const key = data
|
||||
const that = this
|
||||
let index = this.keyList.findIndex(item => item.keyId === key.keyId)
|
||||
that.$refs.swipeItem[index].closeHandler()
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要删除该钥匙',
|
||||
async success(res) {
|
||||
if(res.confirm) {
|
||||
uni.showLoading({
|
||||
title: '删除中',
|
||||
mask: true
|
||||
})
|
||||
const { code: requestCode, message } = await deleteKeyRequest({
|
||||
keyId: key.keyId
|
||||
})
|
||||
if(requestCode === 0) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'none'
|
||||
})
|
||||
that.updateKeySearch({
|
||||
...that.keySearch,
|
||||
pageNo: 1
|
||||
})
|
||||
await that.getKeyList(that.keySearch)
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
async resetKey() {
|
||||
const that = this
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要重置钥匙,该锁的所有钥匙都将被删除',
|
||||
async success(res) {
|
||||
if(res.confirm) {
|
||||
const { code: requestCode, message } = await resetKeyRequest({
|
||||
lockId: that.currentLockInfo.lockId,
|
||||
})
|
||||
console.log('重置钥匙返回', requestCode, message)
|
||||
if(requestCode === 0) {
|
||||
uni.showToast({
|
||||
title: '重置钥匙成功',
|
||||
icon: 'none'
|
||||
})
|
||||
that.updateKeySearch({
|
||||
...that.keySearch,
|
||||
pageNo: 1
|
||||
})
|
||||
await that.getKeyList(that.keySearch)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
toCreateKey() {
|
||||
this.routeJump({
|
||||
name: 'createKey'
|
||||
})
|
||||
},
|
||||
async refresherList() {
|
||||
this.refresherTriggered = true
|
||||
this.updateKeySearch({
|
||||
...this.keySearch,
|
||||
pageNo: 1
|
||||
})
|
||||
const { code, meesage } = await this.getKeyList(this.keySearch)
|
||||
if(code === 0) {
|
||||
uni.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
this.refresherTriggered = false
|
||||
},
|
||||
async nextPage() {
|
||||
if(this.keyTotal <= this.keySearch.pageNo * this.keySearch.pageSize) {
|
||||
return
|
||||
}
|
||||
const pageNo = this.keySearch.pageNo + 1
|
||||
const params = {
|
||||
...this.keySearch,
|
||||
pageNo
|
||||
}
|
||||
const { code, meesage } = await this.getKeyList(params)
|
||||
if(code === 0) {
|
||||
this.updateKeySearch({
|
||||
...this.keySearch,
|
||||
pageNo
|
||||
})
|
||||
}
|
||||
},
|
||||
async changeSearch(data) {
|
||||
this.keySearch.searchStr = data
|
||||
const { code, meesage } = await this.getKeyList(this.keySearch)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search {
|
||||
margin-top: 32rpx;
|
||||
width: 686rpx !important;
|
||||
margin-left: 32rpx;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
bottom: calc(env(safe-area-inset-bottom) + 48rpx);
|
||||
font-weight: bold;
|
||||
|
||||
.button-reset {
|
||||
margin-left: 50rpx;
|
||||
width: 300rpx;
|
||||
height: 88rpx;
|
||||
background-color: #df282d;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
}
|
||||
|
||||
.button-create {
|
||||
margin-left: 50rpx;
|
||||
width: 300rpx;
|
||||
height: 88rpx;
|
||||
background-color: #63b8af;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.key {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
height: 120rpx;
|
||||
width: 750rpx;
|
||||
|
||||
.key-left {
|
||||
margin-left: 32rpx;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.key-right {
|
||||
margin-left: 32rpx;
|
||||
margin-right: 32rpx;
|
||||
|
||||
.key-right-top {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
padding-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.key-right-bottom {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 2rpx;
|
||||
background: #EBEBEB;
|
||||
}
|
||||
|
||||
.empty-list {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
margin: 300rpx auto 20rpx 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.empty-list-text {
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
<view>功能</view>
|
||||
</view>
|
||||
<view class="menu-main">
|
||||
<view v-if="currentLockInfo.lockFeature.bluetoothRemoteControl || currentLockInfo.userType === 110301"
|
||||
<view v-if="currentLockInfo.userType === 110301"
|
||||
class="menu-main-view" @click="routeJump({ name: 'keyList' })">
|
||||
<image class="menu-main-image" src="/static/images/tabbar_key_select.png"></image>
|
||||
<view>电子钥匙</view>
|
||||
|
||||
71
pages/passwordDetail/passwordDetail.vue
Normal file
71
pages/passwordDetail/passwordDetail.vue
Normal file
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="item">
|
||||
<view class="item-title">密码</view>
|
||||
<view class="item-content">{{ currentPasswordInfo.keyboardPwd }}</view>
|
||||
</view>
|
||||
<view class="item" style="margin-top: 2rpx">
|
||||
<view class="item-title">名称</view>
|
||||
<view class="item-content">{{ currentPasswordInfo.keyboardPwdName }}</view>
|
||||
</view>
|
||||
<view class="item" style="margin-top: 2rpx">
|
||||
<view class="item-title">有效期</view>
|
||||
<view v-if="currentPasswordInfo.keyboardPwdType === 2">永久</view>
|
||||
<view v-else>
|
||||
<view class="item-content">{{ timeFormat(currentPasswordInfo.startDate, 'yyyy-mm-dd h:M') }}</view>
|
||||
<view class="item-content">{{ timeFormat(currentPasswordInfo.endDate, 'yyyy-mm-dd h:M') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item" style="margin-top: 20rpx">
|
||||
<view class="item-title">发送人</view>
|
||||
<view class="item-content">{{ currentPasswordInfo.senderUsername }}</view>
|
||||
</view>
|
||||
<view class="item" style="margin-top: 2rpx">
|
||||
<view class="item-title">发送时间</view>
|
||||
<view class="item-content">{{ timeFormat(currentPasswordInfo.sendDate, 'yyyy-mm-dd h:M') }}</view>
|
||||
</view>
|
||||
<view class="tips">密码生成后,请在当日23:59前使用一次进行激活,否则过0点后未激活则失效。</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'pinia'
|
||||
import { useLockStore } from '@/stores/lock'
|
||||
import { timeFormat } from 'uview-plus'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useLockStore, ['currentPasswordInfo']),
|
||||
},
|
||||
methods: {
|
||||
timeFormat
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
padding: 24rpx 32rpx;
|
||||
background-color: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tips {
|
||||
padding: 24rpx 32rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
||||
@ -1,17 +1,320 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
<scroll-view v-if="deviceInfo" scroll-y="true" :style="{height: deviceInfo.screenHeight - deviceInfo.safeArea.top + 'px'}" lower-threshold="100"
|
||||
@refresherrefresh="refresherList" :refresher-enabled="true" @scrolltolower="nextPage"
|
||||
:refresher-triggered="refresherTriggered">
|
||||
<view class="search">
|
||||
<up-search shape="square" :searchIconSize="48" :inputStyle="{ fontSize: '32rpx' }" :height="80" placeholder="搜索"
|
||||
:clearabled="false" @change="changeSearch"
|
||||
v-model="search.searchStr" bgColor="#ffffff" :showAction="false" maxlength="20"></up-search>
|
||||
</view>
|
||||
<view style="padding: 32rpx 0 calc(env(safe-area-inset-bottom) + 250rpx) 0">
|
||||
<view v-if="passwordList.length === 0 && requestFinished">
|
||||
<image class="empty-list" src="/static/images/background_empty_list.png" mode="aspectFill"></image>
|
||||
<view class="empty-list-text">暂无数据</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<up-swipe-action>
|
||||
<up-swipe-action-item ref="swipeItem" :options="options" v-for="(password, index) in passwordList"
|
||||
:key="password.keyboardPwdId" :threshold="50" @click="deletePassword(password)">
|
||||
<view class="password" @click="toPasswordDetail(password)">
|
||||
<image class="password-left" src="/static/images/icon_lock_transparent.png" mode="aspectFill"></image>
|
||||
<view class="password-right">
|
||||
<view class="password-right-top">{{ password.keyboardPwdName }}</view>
|
||||
<view class="password-right-bottom">{{ password.timeText }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
</up-swipe-action-item>
|
||||
</up-swipe-action>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="button">
|
||||
<view class="button-reset" @click="resetPassword">重置密码</view>
|
||||
<view class="button-create" @click="toCreatePassword">获取密码</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
import { mapActions, mapState } from 'pinia'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { useLockStore } from '@/stores/lock'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { deletePsaawordRequest, resetPsaawordListRequest } from '@/api/keyboardPwd'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
return {
|
||||
search: {
|
||||
pageNo: 1,
|
||||
pageSize: 50,
|
||||
searchStr: ''
|
||||
},
|
||||
deviceInfo: null,
|
||||
refresherTriggered: false,
|
||||
requestFinished: false,
|
||||
options: [{
|
||||
text: '删除',
|
||||
style: {
|
||||
backgroundColor: '#f56c6c'
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, ['userInfo']),
|
||||
...mapState(useBluetoothStore, ['currentLockInfo', 'keyId']),
|
||||
...mapState(useLockStore, ['passwordTotal', 'passwordList']),
|
||||
},
|
||||
async onLoad() {
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
})
|
||||
this.deviceInfo = await this.getDeviceInfo()
|
||||
this.search.lockStatus = this.currentLockInfo.lockStatus
|
||||
this.search.lockId = this.currentLockInfo.lockId
|
||||
const { code, meesage } = await this.getPasswordList(this.search)
|
||||
this.requestFinished = true
|
||||
uni.hideLoading()
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useBasicStore, ['routeJump', 'getDeviceInfo']),
|
||||
...mapActions(useLockStore, ['getPasswordList', 'updateCurrentPasswordInfo']),
|
||||
...mapActions(useBluetoothStore, ['resetLockPassword', 'setLockPassword']),
|
||||
toPasswordDetail(password) {
|
||||
this.updateCurrentPasswordInfo(password)
|
||||
this.routeJump({
|
||||
name: 'passwordDetail'
|
||||
})
|
||||
},
|
||||
async deletePassword(data) {
|
||||
const password = data
|
||||
const that = this
|
||||
let index = this.passwordList.findIndex(item => item.keyboardPwdId === password.keyboardPwdId)
|
||||
that.$refs.swipeItem[index].closeHandler()
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要删除该密码',
|
||||
async success(res) {
|
||||
if(res.confirm) {
|
||||
uni.showLoading({
|
||||
title: '删除中',
|
||||
mask: true
|
||||
})
|
||||
const timestamp = parseInt(new Date().getTime() / 1000)
|
||||
const { code } = await that.setLockPassword({
|
||||
keyId: that.keyId.toString(),
|
||||
uid: that.userInfo.uid.toString(),
|
||||
pwdNo: password.pwdUserNo,
|
||||
operate: 3,
|
||||
isAdmin: password.pwdRight,
|
||||
pwd: password.keyboardPwd,
|
||||
userCountLimit: 0xFFFF,
|
||||
startTime: timestamp,
|
||||
endTime: timestamp
|
||||
})
|
||||
if(code === 0) {
|
||||
const { code: requestCode, message } = await deletePsaawordRequest({
|
||||
lockId: that.currentLockInfo.lockId,
|
||||
keyboardPwdId: password.keyboardPwdId,
|
||||
deleteType: 1
|
||||
})
|
||||
if(requestCode === 0) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'none'
|
||||
})
|
||||
that.search.pageNo = 1
|
||||
await that.getPasswordList(that.search)
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '删除失败,请保持在锁附近',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
async resetPassword() {
|
||||
const that = this
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要重置密码,该锁的所有密码都将被删除',
|
||||
async success(res) {
|
||||
if(res.confirm) {
|
||||
const { code } = await that.resetLockPassword({
|
||||
uid: that.userInfo.uid.toString(),
|
||||
keyId: that.currentLockInfo.keyId.toString()
|
||||
})
|
||||
if(code === 0) {
|
||||
const { code: requestCode, message } = await resetPsaawordListRequest({
|
||||
lockId: that.currentLockInfo.lockId,
|
||||
passwordKey: that.currentLockInfo.bluetooth.passwordKey
|
||||
})
|
||||
console.log('重置密码返回', requestCode, message)
|
||||
if(requestCode === 0) {
|
||||
uni.showToast({
|
||||
title: '重置密码成功',
|
||||
icon: 'none'
|
||||
})
|
||||
that.search.pageNo = 1
|
||||
that.getPasswordList(that.search)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '重置密码失败,请保持在锁附近',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
toCreatePassword() {
|
||||
this.routeJump({
|
||||
name: 'createPassword'
|
||||
})
|
||||
},
|
||||
async refresherList() {
|
||||
this.refresherTriggered = true
|
||||
this.search.pageNo = 1
|
||||
const { code, meesage } = await this.getPasswordList(this.search)
|
||||
if(code === 0) {
|
||||
uni.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
this.refresherTriggered = false
|
||||
},
|
||||
async nextPage() {
|
||||
if(this.passwordTotal <= this.search.pageNo * this.search.pageSize) {
|
||||
return
|
||||
}
|
||||
const pageNo = this.search.pageNo + 1
|
||||
const params = {
|
||||
...this.search,
|
||||
pageNo
|
||||
}
|
||||
const { code, meesage } = await this.getPasswordList(params)
|
||||
if(code === 0) {
|
||||
this.search.pageNo = pageNo
|
||||
}
|
||||
},
|
||||
async changeSearch(data) {
|
||||
this.search.searchStr = data
|
||||
const { code, meesage } = await this.getPasswordList(this.search)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search {
|
||||
margin-top: 32rpx;
|
||||
width: 686rpx !important;
|
||||
margin-left: 32rpx;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
bottom: calc(env(safe-area-inset-bottom) + 48rpx);
|
||||
font-weight: bold;
|
||||
|
||||
.button-reset {
|
||||
margin-left: 50rpx;
|
||||
width: 300rpx;
|
||||
height: 88rpx;
|
||||
background-color: #df282d;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
}
|
||||
|
||||
.button-create {
|
||||
margin-left: 50rpx;
|
||||
width: 300rpx;
|
||||
height: 88rpx;
|
||||
background-color: #63b8af;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.password {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
height: 120rpx;
|
||||
width: 750rpx;
|
||||
|
||||
.password-left {
|
||||
margin-left: 32rpx;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
|
||||
.password-right {
|
||||
margin-right: 32rpx;
|
||||
|
||||
.password-right-top {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
padding-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.password-right-bottom {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 2rpx;
|
||||
background: #EBEBEB;
|
||||
}
|
||||
|
||||
.empty-list {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
margin: 300rpx auto 20rpx 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.empty-list-text {
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -86,7 +86,8 @@ export default {
|
||||
})
|
||||
return
|
||||
}
|
||||
const timestamp = parseInt(new Date().getTime() / 1000)
|
||||
const date = new Date()
|
||||
const timestamp = parseInt(date.getTime() / 1000) - date.getTimezoneOffset() * 60
|
||||
const { code } = await this.getLockStatus({
|
||||
name: this.currentLockInfo.name,
|
||||
uid: this.userInfo.uid,
|
||||
|
||||
BIN
static/images/background_empty_list.png
Normal file
BIN
static/images/background_empty_list.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@ -96,6 +96,16 @@ const pages = [
|
||||
name: 'createPassword',
|
||||
path: '/pages/createPassword/createPassword',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'passwordDetail',
|
||||
path: '/pages/passwordDetail/passwordDetail',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'keyDetail',
|
||||
path: '/pages/keyDetail/keyDetail',
|
||||
tabBar: false
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@ -978,11 +978,11 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
conentArray[i + 44] = uid.charCodeAt(i)
|
||||
}
|
||||
|
||||
conentArray.set(this.currentLockInfo.token, 64)
|
||||
conentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 64)
|
||||
|
||||
conentArray[68] = 16
|
||||
|
||||
const md5Array = this.md5Encrypte(keyId + uid, this.currentLockInfo.token, this.currentLockInfo.signKey)
|
||||
const md5Array = this.md5Encrypte(keyId + uid, this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), this.currentLockInfo.signKey)
|
||||
|
||||
conentArray.set(md5Array, 69)
|
||||
|
||||
@ -1035,14 +1035,14 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
conentArray[88] = userCountLimit / 256
|
||||
conentArray[89] = userCountLimit % 256
|
||||
|
||||
conentArray.set(this.currentLockInfo.token, 90)
|
||||
conentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 90)
|
||||
|
||||
conentArray.set(this.timestampToArray(startTime), 94)
|
||||
conentArray.set(this.timestampToArray(endTime), 98)
|
||||
|
||||
conentArray[102] = 16
|
||||
|
||||
const md5Array = this.md5Encrypte(keyId + uid, this.currentLockInfo.token, this.currentLockInfo.signKey)
|
||||
const md5Array = this.md5Encrypte(keyId + uid, this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), this.currentLockInfo.signKey)
|
||||
|
||||
conentArray.set(md5Array, 103)
|
||||
|
||||
|
||||
@ -3,6 +3,9 @@
|
||||
*/
|
||||
import { defineStore } from 'pinia'
|
||||
import { getLockListRequest } from '@/api/lock'
|
||||
import { getPsaawordListRequest } from '@/api/keyboardPwd'
|
||||
import { timeFormat } from 'uview-plus'
|
||||
import { getKeyListRequest } from '@/api/key'
|
||||
|
||||
export const useLockStore = defineStore('lock', {
|
||||
state() {
|
||||
@ -10,10 +13,41 @@ export const useLockStore = defineStore('lock', {
|
||||
// 锁列表
|
||||
lockList: [],
|
||||
// 锁总数
|
||||
lockTotal: 0
|
||||
lockTotal: 0,
|
||||
// 密码列表
|
||||
passwordList: [],
|
||||
// 密码总数
|
||||
passwordTotal: 0,
|
||||
// 当前密码详情
|
||||
currentPasswordInfo: {},
|
||||
// 电子钥匙总数
|
||||
keyTotal: 0,
|
||||
// 电子钥匙列表
|
||||
keyList: [],
|
||||
// 当前电子钥匙详情
|
||||
currentKeyInfo: {},
|
||||
// 电子钥匙列表搜索数据
|
||||
keySearch: {
|
||||
pageNo: 1,
|
||||
pageSize: 50,
|
||||
searchStr: '',
|
||||
endDate: '0',
|
||||
startDate: '0',
|
||||
keyStatus: [110401,110402],
|
||||
keyRight: 0
|
||||
},
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
updateKeySearch(search) {
|
||||
this.keySearch = search
|
||||
},
|
||||
updateCurrentKeyInfo(info) {
|
||||
this.currentKeyInfo = info
|
||||
},
|
||||
updateCurrentPasswordInfo(info) {
|
||||
this.currentPasswordInfo = info
|
||||
},
|
||||
getRole(userType) {
|
||||
if(userType === 110301) {
|
||||
return '超级管理员'
|
||||
@ -49,6 +83,56 @@ export const useLockStore = defineStore('lock', {
|
||||
})
|
||||
return { code, message }
|
||||
}
|
||||
},
|
||||
async getPasswordList(params) {
|
||||
const { code, data, message } = await getPsaawordListRequest(params)
|
||||
if(code === 0) {
|
||||
this.passwordTotal = data.total
|
||||
for(let i = 0; i < data.list.length; i++) {
|
||||
if(data.list[i].keyboardPwdType === 2) {
|
||||
data.list[i].timeText = `${timeFormat(new Date(data.list[i].created_at), 'yyyy-mm-dd h:M')} 永久`
|
||||
} else if(data.list[i].keyboardPwdType === 3) {
|
||||
data.list[i].timeText = `${data.list[i].validTimeStr} 限时`
|
||||
}
|
||||
}
|
||||
if(params.pageNo === 1) {
|
||||
this.passwordList = data.list
|
||||
} else {
|
||||
this.passwordList = this.passwordList.concat(data.list)
|
||||
}
|
||||
return { code }
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
return { code, message }
|
||||
}
|
||||
},
|
||||
async getKeyList(params) {
|
||||
const { code, data, message } = await getKeyListRequest(params)
|
||||
if(code === 0) {
|
||||
this.keyTotal = data.total
|
||||
for(let i = 0; i < data.list.length; i++) {
|
||||
if(data.list[i].keyType === 2) {
|
||||
data.list[i].timeText = `${timeFormat(new Date(data.list[i].startDate), 'yyyy-mm-dd h:M')} - ${timeFormat(new Date(data.list[i].endDate), 'yyyy-mm-dd h:M')} 限时`
|
||||
} else {
|
||||
data.list[i].timeText = `${timeFormat(new Date(data.list[i].startDate), 'yyyy-mm-dd h:M')} 永久`
|
||||
}
|
||||
}
|
||||
if(params.pageNo === 1) {
|
||||
this.keyList = data.list
|
||||
} else {
|
||||
this.keyList = this.keyList.concat(data.list)
|
||||
}
|
||||
return { code }
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
return { code, message }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
4
uni.scss
4
uni.scss
@ -77,3 +77,7 @@ $uni-color-subtitle: #555555; // 二级标题颜色
|
||||
$uni-font-size-subtitle:26px;
|
||||
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||
$uni-font-size-paragraph:15px;
|
||||
|
||||
.u-picker__view {
|
||||
height: 500rpx !important;
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ const request = (config) => {
|
||||
return new Promise((resolve) => {
|
||||
const token = config?.token ? config.token : uni.getStorageSync('token')
|
||||
const headerDefault = {
|
||||
appid: getApp().globalData.appid,
|
||||
version: baseConfig.version,
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user