1. 完成除锁升级和消息通知外的全部功能
This commit is contained in:
parent
1d1adaab0c
commit
3840971b9c
@ -1,12 +0,0 @@
|
||||
import request from '../utils/request'
|
||||
|
||||
// lockSetting 锁设置模块
|
||||
|
||||
// 更新锁设置
|
||||
export function updateLockSettingRequest(data) {
|
||||
return request({
|
||||
url: '/lockSetting/updateLockSetting',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
@ -11,6 +11,15 @@ export function getLockSettingRequest(data) {
|
||||
})
|
||||
}
|
||||
|
||||
// 更新锁设置
|
||||
export function updateLockSettingRequest(data) {
|
||||
return request({
|
||||
url: '/lockSetting/updateLockSetting',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新锁名称
|
||||
export function updateLockNameRequest(data) {
|
||||
return request({
|
||||
@ -55,3 +64,12 @@ export function setGroupRequest(data) {
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 上传锁数据
|
||||
export function lockDataUploadRequest(data) {
|
||||
return request({
|
||||
url: '/lockRecords/lockDataUpload',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
42
pages.json
42
pages.json
@ -358,6 +358,48 @@
|
||||
"navigationBarTitleText": "选择分组",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/updateSetting/updateSetting",
|
||||
"style": {
|
||||
"navigationBarTitleText": "设置",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/lockSound/lockSound",
|
||||
"style": {
|
||||
"navigationBarTitleText": "锁声音",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/autoLock/autoLock",
|
||||
"style": {
|
||||
"navigationBarTitleText": "自动闭锁",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/faceSetting/faceSetting",
|
||||
"style": {
|
||||
"navigationBarTitleText": "面容开锁设置",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/lockDate/lockDate",
|
||||
"style": {
|
||||
"navigationBarTitleText": "锁时间",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/uploadLockData/uploadLockData",
|
||||
"style": {
|
||||
"navigationBarTitleText": "上传数据",
|
||||
"disableScroll": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
112
pages/LockDate/LockDate.vue
Normal file
112
pages/LockDate/LockDate.vue
Normal file
@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="text-xl text-center py-10 h-100 line-height-100rpx">
|
||||
<view v-if="show">{{
|
||||
timeFormat($bluetooth.currentLockInfo.lockConfig.indate, 'yyyy-mm-dd hh:MM')
|
||||
}}</view>
|
||||
</view>
|
||||
<view
|
||||
class="bg-#63b8af mt-4 rounded-3xl w-600 h-80 line-height-80rpx text-center mx-75rpx text-white text-xl font-bold"
|
||||
@click="update"
|
||||
>
|
||||
校准
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { timeFormat } from 'uview-plus'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $user = useUserStore()
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
const show = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
})
|
||||
const { code } = await $bluetooth.updateServerTimestamp()
|
||||
if (code === 0) {
|
||||
const date = new Date()
|
||||
const timestamp = $bluetooth.serverTimestamp - date.getTimezoneOffset() * 60
|
||||
const { code: lockStatus } = await $bluetooth.getLockStatus({
|
||||
name: $bluetooth.currentLockInfo.lockId.toString(),
|
||||
uid: $user.userInfo.uid.toString(),
|
||||
nowTime: $bluetooth.serverTimestamp,
|
||||
localTime: timestamp
|
||||
})
|
||||
uni.hideLoading()
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
if (lockStatus === 0) {
|
||||
show.value = true
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '获取锁时间失败,请返回重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '获取锁时间失败,请返回重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const update = async () => {
|
||||
if (pending.value && show.value) return
|
||||
uni.showLoading({
|
||||
title: '更新中'
|
||||
})
|
||||
pending.value = true
|
||||
const { code, message } = await $bluetooth.updateServerTimestamp()
|
||||
if (code === 0) {
|
||||
const { code: lockStatus } = await $bluetooth.calibrationTime({
|
||||
lockId: $bluetooth.currentLockInfo.lockId.toString(),
|
||||
uid: $user.userInfo.uid.toString(),
|
||||
nowTime: $bluetooth.serverTimestamp
|
||||
})
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
if (lockStatus === 0) {
|
||||
$bluetooth.updateCurrentLockInfo({
|
||||
...$bluetooth.currentLockInfo,
|
||||
lockConfig: {
|
||||
...$bluetooth.currentLockInfo.lockConfig,
|
||||
indate: $bluetooth.serverTimestamp * 1000
|
||||
}
|
||||
})
|
||||
uni.showToast({
|
||||
title: '更新成功',
|
||||
icon: 'none'
|
||||
})
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
uni.showToast({
|
||||
title: '更新失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
192
pages/autoLock/autoLock.vue
Normal file
192
pages/autoLock/autoLock.vue
Normal file
@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="py-3 px-4 bg-white !py-2 flex items-center justify-between text-base">
|
||||
<view class="item-title">自动闭锁</view>
|
||||
<switch
|
||||
@click="changeCheck"
|
||||
:checked="check"
|
||||
class="transform-scale-90"
|
||||
:disabled="true"
|
||||
color="#002ce5"
|
||||
/>
|
||||
</view>
|
||||
<view
|
||||
v-if="check"
|
||||
class="py-3 px-4 bg-white !py-2 flex items-center justify-between text-base mt-1"
|
||||
@click="show = true"
|
||||
>
|
||||
<view class="item-title">延迟时间</view>
|
||||
<view class="flex items-center">
|
||||
<view class="mr-2">{{ custom ? '自定义' : value + 's' }}</view>
|
||||
<up-icon name="arrow-right"></up-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt-1" v-if="custom && check">
|
||||
<LockInput
|
||||
:value="text"
|
||||
title="时间"
|
||||
type="number"
|
||||
:maxlength="2"
|
||||
placeholder="请输入时间,范围为5-60"
|
||||
@change-input="changeDuration"
|
||||
></LockInput>
|
||||
</view>
|
||||
<view class="m-4 text-sm">
|
||||
经过以上设定的时间,锁会自动关闭。开启或修改设置后,请先开一次锁,使时间生效。
|
||||
</view>
|
||||
<view
|
||||
:class="[canUpdate ? 'bg-#63b8af' : 'bg-#a3a3a3']"
|
||||
class="mt-4 rounded-3xl w-600 h-80 line-height-80rpx text-center mx-75rpx text-white text-xl font-bold"
|
||||
@click="update"
|
||||
>
|
||||
保存
|
||||
</view>
|
||||
<up-picker
|
||||
:show="show"
|
||||
:columns="columns"
|
||||
:defaultIndex="picker"
|
||||
title="选择时间"
|
||||
keyName="name"
|
||||
:itemHeight="70"
|
||||
:visibleItemCount="5"
|
||||
@close="show = false"
|
||||
@cancel="show = false"
|
||||
@confirm="confirm"
|
||||
></up-picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { updateLockSettingRequest } from '@/api/setting'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $user = useUserStore()
|
||||
const $basic = useBasicStore()
|
||||
|
||||
const check = ref(false)
|
||||
const value = ref(0)
|
||||
const picker = ref([0])
|
||||
|
||||
const text = ref('')
|
||||
|
||||
const show = ref(false)
|
||||
const pending = ref(false)
|
||||
const custom = ref(false)
|
||||
|
||||
const columns = ref([
|
||||
[
|
||||
{ name: '5s', value: 5 },
|
||||
{ name: '10s', value: 10 },
|
||||
{ name: '15s', value: 15 },
|
||||
{ name: '30s', value: 30 },
|
||||
{ name: '60s', value: 60 },
|
||||
{ name: '自定义', value: -1 }
|
||||
]
|
||||
])
|
||||
|
||||
const canUpdate = computed(() => {
|
||||
return (
|
||||
(($bluetooth.currentLockSetting.lockSettingInfo.autoLock === 1) !== check.value ||
|
||||
value.value !== $bluetooth.currentLockSetting.lockSettingInfo.autoLockSecond) &&
|
||||
((check.value && value.value >= 5 && value.value <= 60) || !check.value)
|
||||
)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
check.value = $bluetooth.currentLockSetting.lockSettingInfo.autoLock === 1
|
||||
value.value = $bluetooth.currentLockSetting.lockSettingInfo.autoLockSecond
|
||||
const index = columns.value[0].findIndex(item => item.value === value.value)
|
||||
if (index === -1) {
|
||||
custom.value = true
|
||||
picker.value = [5]
|
||||
text.value = $bluetooth.currentLockSetting.lockSettingInfo.autoLockSecond.toString()
|
||||
} else {
|
||||
picker.value = [index]
|
||||
}
|
||||
})
|
||||
|
||||
const changeDuration = data => {
|
||||
if (custom.value) {
|
||||
value.value = Number(data)
|
||||
}
|
||||
}
|
||||
|
||||
const update = async () => {
|
||||
if (!canUpdate.value) return
|
||||
if (pending.value) return
|
||||
pending.value = true
|
||||
uni.showLoading({
|
||||
title: '保存中'
|
||||
})
|
||||
const featureBit = 29
|
||||
const { code } = await $bluetooth.updateSetting({
|
||||
keyId: $bluetooth.keyId.toString(),
|
||||
uid: $user.userInfo.uid.toString(),
|
||||
featureBit,
|
||||
params: [Number(value.value)],
|
||||
withParams: true
|
||||
})
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
if (code === 0) {
|
||||
const { code, message } = await updateLockSettingRequest({
|
||||
lockId: $bluetooth.currentLockInfo.lockId,
|
||||
autoLock: check.value ? 1 : 0,
|
||||
autoLockSecond: value.value
|
||||
})
|
||||
pending.value = false
|
||||
uni.hideLoading()
|
||||
if (code === 0) {
|
||||
$bluetooth.updateCurrentLockSetting({
|
||||
...$bluetooth.currentLockSetting,
|
||||
lockSettingInfo: {
|
||||
...$bluetooth.currentLockSetting.lockSettingInfo,
|
||||
autoLock: check.value ? 1 : 0,
|
||||
autoLockSecond: value.value
|
||||
}
|
||||
})
|
||||
$basic.backAndToast('更新成功')
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
pending.value = false
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '更新失败,请保持在锁附近',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const confirm = data => {
|
||||
if (data.indexs[0] === 5) {
|
||||
custom.value = true
|
||||
} else {
|
||||
custom.value = false
|
||||
value.value = columns.value[0][data.indexs[0]].value
|
||||
}
|
||||
show.value = false
|
||||
}
|
||||
|
||||
const changeCheck = () => {
|
||||
check.value = !check.value
|
||||
if (!check.value) {
|
||||
value.value = 0
|
||||
} else {
|
||||
value.value = 5
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
200
pages/faceSetting/faceSetting.vue
Normal file
200
pages/faceSetting/faceSetting.vue
Normal file
@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="py-3 px-4 bg-white !py-2 flex items-center justify-between text-base">
|
||||
<view>面容开锁</view>
|
||||
<switch
|
||||
@click="changeCheck"
|
||||
:checked="check"
|
||||
class="transform-scale-90"
|
||||
:disabled="true"
|
||||
color="#002ce5"
|
||||
/>
|
||||
</view>
|
||||
<view
|
||||
class="py-3 px-4 bg-white !py-2 flex items-center justify-between text-base mt-1"
|
||||
@click="showDistance = true"
|
||||
v-if="distance !== null"
|
||||
>
|
||||
<view class="max-w-500">
|
||||
<view>感应距离</view>
|
||||
<view class="text-xs">{{ distanceColumns[0][distanceIndex].text }}</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<view class="mr-2">{{ distanceColumns[0][distanceIndex].name }}</view>
|
||||
<up-icon name="arrow-right"></up-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
@click="showEnErrUnlock = true"
|
||||
class="py-3 px-4 bg-white !py-2 flex items-center justify-between text-base mt-1"
|
||||
v-if="enErrUnlock !== null"
|
||||
>
|
||||
<view class="max-w-500">
|
||||
<view>防误开</view>
|
||||
<view class="text-xs">{{ enErrUnlockColumns[0][enErrUnlock].text }}</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<view class="mr-2">{{ enErrUnlockColumns[0][enErrUnlock].name }}</view>
|
||||
<up-icon name="arrow-right"></up-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="pos-fixed bottom-[calc(env(safe-area-inset-bottom)+48rpx)] mx-3 py-5 px-3 bg-white text-sm rounded-md"
|
||||
>
|
||||
<view class="text-base font-bold mb-3">添加和使用面容开锁时:</view>
|
||||
<view>1、请尽量保持单人在门前操作;</view>
|
||||
<view>2、请站立在门锁正前方约0.5~0.8米,面向门锁;</view>
|
||||
<view>3、请保持脸部无遮挡,露出五官;</view>
|
||||
<view>4、面容识别异常时,可触摸数字键盘任意按键,手动重启人脸识别。</view>
|
||||
</view>
|
||||
<up-picker
|
||||
:show="showDistance"
|
||||
:columns="distanceColumns"
|
||||
:defaultIndex="[distanceIndex]"
|
||||
title="感应距离"
|
||||
keyName="name"
|
||||
:itemHeight="70"
|
||||
:visibleItemCount="5"
|
||||
@close="showDistance = false"
|
||||
@cancel="showDistance = false"
|
||||
@confirm="confirmDistance"
|
||||
></up-picker>
|
||||
<up-picker
|
||||
:show="showEnErrUnlock"
|
||||
:columns="enErrUnlockColumns"
|
||||
:defaultIndex="[enErrUnlock]"
|
||||
title="防误开"
|
||||
keyName="name"
|
||||
:itemHeight="70"
|
||||
:visibleItemCount="5"
|
||||
@close="showEnErrUnlock = false"
|
||||
@cancel="showEnErrUnlock = false"
|
||||
@confirm="confirmEnErrUnlock"
|
||||
></up-picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { updateLockSettingRequest } from '@/api/setting'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $user = useUserStore()
|
||||
|
||||
const showDistance = ref(false)
|
||||
const showEnErrUnlock = ref(false)
|
||||
const distanceIndex = ref(0)
|
||||
|
||||
const check = ref(false)
|
||||
const distance = ref(null)
|
||||
const enErrUnlock = ref(null)
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
const distanceColumns = ref([
|
||||
[
|
||||
{ name: '远距离', value: 3, text: '感应到门前约1.5米有人时,将自动启动面部识别开锁。' },
|
||||
{ name: '中距离', value: 2, text: '感应到门前约0.8米有人时,将自动启动面部识别开锁。' },
|
||||
{ name: '近距离', value: 1, text: '感应到门前约0.5米有人时,将自动启动面部识别开锁。' },
|
||||
{ name: '关闭', value: 0, text: '感应距离已关闭,需手动触摸键盘任意键,进行面部识别开锁。' }
|
||||
]
|
||||
])
|
||||
|
||||
const enErrUnlockColumns = ref([])
|
||||
|
||||
onMounted(() => {
|
||||
const list = []
|
||||
for (let i = 0; i <= 30; i++) {
|
||||
list.push({
|
||||
name: i + '秒',
|
||||
value: i,
|
||||
text:
|
||||
i === 0
|
||||
? '防误开已关闭,关门后仍可使用面容开锁'
|
||||
: `防误开已打开,开锁后${i}秒内不可使用面容开锁`
|
||||
})
|
||||
}
|
||||
enErrUnlockColumns.value = [list]
|
||||
check.value = $bluetooth.currentLockSetting.lockSettingInfo.faceSwitch === 1
|
||||
distance.value = $bluetooth.currentLockSetting.lockSettingInfo.faceInductionDistance
|
||||
distanceIndex.value = distanceColumns.value[0].findIndex(item => item.value === distance.value)
|
||||
enErrUnlock.value = $bluetooth.currentLockSetting.lockSettingInfo.faceEnErrUnlock
|
||||
})
|
||||
|
||||
const confirmEnErrUnlock = data => {
|
||||
enErrUnlock.value = data.indexs[0]
|
||||
showEnErrUnlock.value = false
|
||||
change('faceEnErrUnlock', enErrUnlock.value)
|
||||
}
|
||||
|
||||
const confirmDistance = data => {
|
||||
distance.value = distanceColumns.value[0][data.indexs[0]].value
|
||||
distanceIndex.value = data.indexs[0]
|
||||
showDistance.value = false
|
||||
change('faceInductionDistance', distance.value)
|
||||
}
|
||||
|
||||
const changeCheck = () => {
|
||||
check.value = !check.value
|
||||
change('faceSwitch', check.value ? 1 : 0)
|
||||
}
|
||||
|
||||
const change = async (type, value) => {
|
||||
if (pending.value) return
|
||||
pending.value = true
|
||||
uni.showLoading({
|
||||
title: '设置中'
|
||||
})
|
||||
const featureBit = 5
|
||||
const { code } = await $bluetooth.updateSetting({
|
||||
keyId: $bluetooth.keyId.toString(),
|
||||
uid: $user.userInfo.uid.toString(),
|
||||
featureBit,
|
||||
params: [check.value ? 1 : 0, distance.value, enErrUnlock.value],
|
||||
withParams: true
|
||||
})
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
if (code === 0) {
|
||||
const { code, message } = await updateLockSettingRequest({
|
||||
lockId: $bluetooth.currentLockInfo.lockId,
|
||||
[type]: value
|
||||
})
|
||||
pending.value = false
|
||||
uni.hideLoading()
|
||||
if (code === 0) {
|
||||
$bluetooth.updateCurrentLockSetting({
|
||||
...$bluetooth.currentLockSetting,
|
||||
lockSettingInfo: {
|
||||
...$bluetooth.currentLockSetting.lockSettingInfo,
|
||||
autoLock: check.value ? 1 : 0,
|
||||
autoLockSecond: value.value
|
||||
}
|
||||
})
|
||||
uni.showToast({
|
||||
title: '设置成功',
|
||||
icon: 'none'
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
pending.value = false
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '设置失败,请保持在锁附近',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
138
pages/lockSound/lockSound.vue
Normal file
138
pages/lockSound/lockSound.vue
Normal file
@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="py-3 px-4 bg-white !py-2 flex items-center justify-between text-base">
|
||||
<view class="item-title">锁声音</view>
|
||||
<switch
|
||||
@click="changeCheck"
|
||||
:checked="check"
|
||||
class="transform-scale-90"
|
||||
:disabled="true"
|
||||
color="#002ce5"
|
||||
/>
|
||||
</view>
|
||||
<view class="m-4 text-sm">
|
||||
功能开启后,你将可以智能锁的提示音。包括电量过低,密码错误等提示。
|
||||
</view>
|
||||
<view class="bg-white" v-if="check">
|
||||
<view class="py-3 px-4">请选择音量</view>
|
||||
<view
|
||||
v-for="(item, index) in volumeList"
|
||||
:key="index"
|
||||
class="py-3 px-4 border-t-solid border-t-gray-200 border-t-2 flex items-center justify-between"
|
||||
@click="value = index + 1"
|
||||
>
|
||||
<view>{{ item }}</view>
|
||||
<view
|
||||
class="rounded-50% w-40 h-40 border-solid border-2 flex items-center justify-center"
|
||||
:class="[value === index + 1 ? 'border-#002ce5' : 'border-black']"
|
||||
>
|
||||
<up-icon v-if="value === index + 1" name="checkmark" color="#002ce5"></up-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
:class="[canUpdate ? 'bg-#63b8af' : 'bg-#a3a3a3']"
|
||||
class="mt-4 rounded-3xl w-600 h-80 line-height-80rpx text-center mx-75rpx text-white text-xl font-bold"
|
||||
@click="update"
|
||||
>
|
||||
保存
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { updateLockSettingRequest } from '@/api/setting'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $user = useUserStore()
|
||||
const $basic = useBasicStore()
|
||||
|
||||
const check = ref(false)
|
||||
|
||||
const volumeList = ['低', '较低', '中', '较高', '高']
|
||||
|
||||
const value = ref(0)
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
const canUpdate = computed(() => {
|
||||
return (
|
||||
($bluetooth.currentLockSetting.lockSettingInfo.lockSound === 1) !== check.value ||
|
||||
value.value !== $bluetooth.currentLockSetting.lockSettingInfo.lockSoundVolume
|
||||
)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
check.value = $bluetooth.currentLockSetting.lockSettingInfo.lockSound === 1
|
||||
value.value = $bluetooth.currentLockSetting.lockSettingInfo.lockSoundVolume
|
||||
})
|
||||
|
||||
const update = async () => {
|
||||
if (!canUpdate.value) return
|
||||
if (pending.value) return
|
||||
pending.value = true
|
||||
uni.showLoading({
|
||||
title: '保存中'
|
||||
})
|
||||
const featureBit = 33
|
||||
const { code } = await $bluetooth.updateSetting({
|
||||
keyId: $bluetooth.keyId.toString(),
|
||||
uid: $user.userInfo.uid.toString(),
|
||||
featureBit,
|
||||
params: [value.value],
|
||||
withParams: true
|
||||
})
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
if (code === 0) {
|
||||
const { code, message } = await updateLockSettingRequest({
|
||||
lockId: $bluetooth.currentLockInfo.lockId,
|
||||
lockSound: check.value ? 1 : 0,
|
||||
lockSoundVolume: value.value
|
||||
})
|
||||
pending.value = false
|
||||
uni.hideLoading()
|
||||
if (code === 0) {
|
||||
$bluetooth.updateCurrentLockSetting({
|
||||
...$bluetooth.currentLockSetting,
|
||||
lockSettingInfo: {
|
||||
...$bluetooth.currentLockSetting.lockSettingInfo,
|
||||
lockSound: check.value ? 1 : 0,
|
||||
lockSoundVolume: value.value
|
||||
}
|
||||
})
|
||||
$basic.backAndToast('更新成功')
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
pending.value = false
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '更新失败,请保持在锁附近',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const changeCheck = () => {
|
||||
check.value = !check.value
|
||||
if (!check.value) {
|
||||
value.value = 0
|
||||
} else {
|
||||
value.value = 3
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
@ -9,7 +9,7 @@
|
||||
</view>
|
||||
<view
|
||||
class="py-3 px-4 bg-white flex items-center justify-between text-base mt-2.5"
|
||||
@click="toJump('lockInfo')"
|
||||
@click="toJump('autoLock')"
|
||||
>
|
||||
<view class="item-title">自动闭锁</view>
|
||||
<view class="flex items-center">
|
||||
@ -25,7 +25,7 @@
|
||||
</view>
|
||||
<view
|
||||
class="py-3 px-4 bg-white flex items-center justify-between text-base mt-4rpx"
|
||||
@click="toJump('lockInfo')"
|
||||
@click="toJump('lockSound')"
|
||||
>
|
||||
<view class="item-title">锁声音</view>
|
||||
<view class="flex items-center">
|
||||
@ -41,7 +41,7 @@
|
||||
</view>
|
||||
<view
|
||||
class="py-3 px-4 bg-white flex items-center justify-between text-base mt-4rpx"
|
||||
@click="toJump('lockInfo')"
|
||||
@click="toUpdateSetting('antiPrySwitch')"
|
||||
>
|
||||
<view class="item-title">防撬报警</view>
|
||||
<view class="flex items-center">
|
||||
@ -55,7 +55,7 @@
|
||||
</view>
|
||||
<view
|
||||
class="py-3 px-4 bg-white flex items-center justify-between text-base mt-2.5"
|
||||
@click="toJump('lockInfo')"
|
||||
@click="toUpdateSetting('remoteUnlock')"
|
||||
>
|
||||
<view class="item-title">远程开锁</view>
|
||||
<view class="flex items-center">
|
||||
@ -69,7 +69,7 @@
|
||||
</view>
|
||||
<view
|
||||
class="py-3 px-4 bg-white flex items-center justify-between text-base mt-4rpx"
|
||||
@click="toJump('lockInfo')"
|
||||
@click="toUpdateSetting('resetSwitch')"
|
||||
>
|
||||
<view class="item-title">重置键</view>
|
||||
<view class="flex items-center">
|
||||
@ -83,7 +83,7 @@
|
||||
</view>
|
||||
<view
|
||||
class="py-3 px-4 bg-white flex items-center justify-between text-base mt-2.5"
|
||||
@click="toJump('lockInfo')"
|
||||
@click="toJump('faceSetting')"
|
||||
>
|
||||
<view class="item-title">面容开锁</view>
|
||||
<view><up-icon name="arrow-right"></up-icon></view>
|
||||
@ -96,17 +96,9 @@
|
||||
<view><up-icon name="arrow-right"></up-icon></view>
|
||||
</view>
|
||||
<view class="py-3 px-4 bg-white !py-2 flex items-center justify-between text-base mt-2.5">
|
||||
<view class="item-title">考勤</view>
|
||||
<switch
|
||||
:checked="$bluetooth.currentLockSetting.lockSettingInfo.attendance === 1"
|
||||
class="transform-scale-90"
|
||||
:disabled="true"
|
||||
color="#002ce5"
|
||||
/>
|
||||
</view>
|
||||
<view class="py-3 px-4 bg-white !py-2 flex items-center justify-between text-base mt-4rpx">
|
||||
<view class="item-title">开锁提醒</view>
|
||||
<switch
|
||||
@click="changeSetting('unlockReminder')"
|
||||
:checked="$bluetooth.currentLockSetting.lockSettingInfo.unlockReminder === 1"
|
||||
class="transform-scale-90"
|
||||
:disabled="true"
|
||||
@ -116,6 +108,7 @@
|
||||
<view class="py-3 px-4 bg-white !py-2 flex items-center justify-between text-base mt-4rpx">
|
||||
<view class="item-title">开锁时是否需联网</view>
|
||||
<switch
|
||||
@click="changeSetting('appUnlockOnline')"
|
||||
:checked="$bluetooth.currentLockSetting.lockSettingInfo.appUnlockOnline === 1"
|
||||
class="transform-scale-90"
|
||||
:disabled="true"
|
||||
@ -124,14 +117,14 @@
|
||||
</view>
|
||||
<view
|
||||
class="py-3 px-4 bg-white flex items-center justify-between text-base mt-2.5"
|
||||
@click="toJump('lockInfo')"
|
||||
@click="toJump('lockDate')"
|
||||
>
|
||||
<view class="item-title">锁时间</view>
|
||||
<view><up-icon name="arrow-right"></up-icon></view>
|
||||
</view>
|
||||
<view
|
||||
class="py-3 px-4 bg-white flex items-center justify-between text-base mt-4rpx"
|
||||
@click="toJump('lockInfo')"
|
||||
@click="toJump('uploadLockData')"
|
||||
>
|
||||
<view class="item-title">上传数据</view>
|
||||
<view><up-icon name="arrow-right"></up-icon></view>
|
||||
@ -174,7 +167,7 @@
|
||||
import { useLockStore } from '@/stores/lock'
|
||||
import { deleteKeyRequest } from '@/api/key'
|
||||
import { useBasicStore } from '@/stores/basic'
|
||||
import { getLockSettingRequest } from '@/api/setting'
|
||||
import { getLockSettingRequest, updateLockSettingRequest } from '@/api/setting'
|
||||
|
||||
const $user = useUserStore()
|
||||
const $bluetooth = useBluetoothStore()
|
||||
@ -185,6 +178,8 @@
|
||||
const checked = ref(false)
|
||||
const requestFinished = ref(false)
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
const volumeList = ['低', '较低', '中', '较高', '高']
|
||||
|
||||
onMounted(async () => {
|
||||
@ -206,6 +201,86 @@
|
||||
}
|
||||
})
|
||||
|
||||
const toUpdateSetting = key => {
|
||||
$basic.routeJump({
|
||||
name: 'updateSetting',
|
||||
params: {
|
||||
key
|
||||
},
|
||||
events: {
|
||||
changeSetting() {
|
||||
changeSetting(key)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const changeSetting = async key => {
|
||||
if (pending.value) return
|
||||
pending.value = true
|
||||
uni.showLoading({
|
||||
title: '更新中'
|
||||
})
|
||||
let featureBit
|
||||
if (key === 'unlockReminder') {
|
||||
featureBit = 47
|
||||
} else if (key === 'appUnlockOnline') {
|
||||
featureBit = 55
|
||||
} else if (key === 'remoteUnlock') {
|
||||
featureBit = 28
|
||||
} else if (key === 'resetSwitch') {
|
||||
featureBit = 31
|
||||
} else if (key === 'antiPrySwitch') {
|
||||
featureBit = 30
|
||||
}
|
||||
const { code } = await $bluetooth.updateSetting({
|
||||
keyId: $bluetooth.keyId.toString(),
|
||||
uid: $user.userInfo.uid.toString(),
|
||||
featureBit,
|
||||
featureEnable: $bluetooth.currentLockSetting.lockSettingInfo[key] === 1 ? 0 : 1,
|
||||
withParams: false
|
||||
})
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
if (code === 0) {
|
||||
const { code, message } = await updateLockSettingRequest({
|
||||
lockId: $bluetooth.currentLockInfo.lockId,
|
||||
[key]: $bluetooth.currentLockSetting.lockSettingInfo[key] === 1 ? 0 : 1
|
||||
})
|
||||
pending.value = false
|
||||
uni.hideLoading()
|
||||
if (code === 0) {
|
||||
$bluetooth.updateCurrentLockSetting({
|
||||
...$bluetooth.currentLockSetting,
|
||||
lockSettingInfo: {
|
||||
...$bluetooth.currentLockSetting.lockSettingInfo,
|
||||
[key]: $bluetooth.currentLockSetting.lockSettingInfo[key] === 1 ? 0 : 1
|
||||
}
|
||||
})
|
||||
$lock.updateLockSearch({
|
||||
...$lock.lockSearch,
|
||||
pageNo: 1
|
||||
})
|
||||
$lock.getLockList($lock.lockSearch)
|
||||
uni.showToast({
|
||||
title: '更新成功',
|
||||
icon: 'none'
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
pending.value = false
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '更新失败,请保持在锁附近',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const toJump = name => {
|
||||
$basic.routeJump({
|
||||
name
|
||||
|
||||
@ -31,9 +31,11 @@
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { updateElectricQuantityRequest } from '@/api/room'
|
||||
import { useLockStore } from '@/stores/lock'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $user = useUserStore()
|
||||
const $lock = useLockStore()
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
@ -78,6 +80,11 @@
|
||||
electricQuantityDate: resultData.electricQuantityDate
|
||||
}
|
||||
})
|
||||
$lock.updateLockSearch({
|
||||
...$lock.lockSearch,
|
||||
pageNo: 1
|
||||
})
|
||||
$lock.getLockList($lock.lockSearch)
|
||||
uni.showToast({
|
||||
title: '更新成功',
|
||||
icon: 'none'
|
||||
|
||||
66
pages/updateSetting/updateSetting.vue
Normal file
66
pages/updateSetting/updateSetting.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="mx-4 pt-5 text-base">
|
||||
<view class="text-sm">
|
||||
<view v-if="type === 'remoteUnlock'">
|
||||
功能开启后,你将可以通过网关远程开锁。此功能的开启和关闭只能在锁附近通过手机蓝牙进行。
|
||||
</view>
|
||||
<view v-if="type === 'resetSwitch'">
|
||||
开启后,可通过长按锁上的设置键重新上电,用APP重新添加
|
||||
</view>
|
||||
<view v-if="type === 'resetSwitch'" class="mt-3">
|
||||
关闭后,重置键无效,锁要通过app删除后才能重新添加
|
||||
</view>
|
||||
<view v-if="type === 'antiPrySwitch'"> 开启后,锁被撬动时,会发出报警声 </view>
|
||||
<view class="mt-5 font-bold"
|
||||
>当前模式:{{
|
||||
$bluetooth.currentLockSetting.lockSettingInfo[type] === 1 ? '已开启' : '已关闭'
|
||||
}}</view
|
||||
>
|
||||
</view>
|
||||
<view
|
||||
@click="update"
|
||||
class="w-full bg-#63b8af text-white line-height-80rpx h-80 rounded-40rpx text-center mt-4 text-lg font-bold"
|
||||
>{{ $bluetooth.currentLockSetting.lockSettingInfo[type] === 1 ? '关闭' : '开启' }}</view
|
||||
>
|
||||
</view></view
|
||||
>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getCurrentInstance, ref } from 'vue'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
|
||||
const instance = getCurrentInstance().proxy
|
||||
const eventChannel = instance.getOpenerEventChannel()
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
|
||||
const type = ref('')
|
||||
|
||||
const update = async () => {
|
||||
eventChannel.emit('changeSetting', {})
|
||||
}
|
||||
|
||||
onLoad(options => {
|
||||
type.value = options.key
|
||||
let title = ''
|
||||
if (type.value === 'resetSwitch') {
|
||||
title = '重置键'
|
||||
} else if (type.value === 'remoteUnlock') {
|
||||
title = '远程开锁'
|
||||
} else if (type.value === 'antiPrySwitch') {
|
||||
title = '防撬报警'
|
||||
}
|
||||
uni.setNavigationBarTitle({
|
||||
title
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
116
pages/uploadLockData/uploadLockData.vue
Normal file
116
pages/uploadLockData/uploadLockData.vue
Normal file
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="mx-4 pt-5 text-base">
|
||||
<view class="text-sm">
|
||||
<view> 本操作将上传锁内数据到服务器,过程可能需要几分钟,请耐心等待 </view>
|
||||
</view>
|
||||
<view
|
||||
@click="asyncData"
|
||||
class="w-full bg-#63b8af text-white line-height-80rpx h-80 rounded-40rpx text-center mt-4 text-lg font-bold"
|
||||
>
|
||||
开始
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { lockDataUploadRequest } from '@/api/setting'
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
const $user = useUserStore()
|
||||
|
||||
const progress = ref(0)
|
||||
const page = ref(0)
|
||||
|
||||
const list = ref([])
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
const typeList = ['password', 'card', 'fingerprint', 'face', 'palmVein', 'remote', 'setting']
|
||||
|
||||
const asyncData = async (flag = false) => {
|
||||
if (pending.value && !flag) return
|
||||
pending.value = true
|
||||
uni.showLoading({
|
||||
title: `上传中${progress.value}/7`
|
||||
})
|
||||
const { code, data } = await $bluetooth.getLockDataList({
|
||||
type: typeList[progress.value],
|
||||
page: page.value,
|
||||
lockId: $bluetooth.currentLockInfo.lockName.toString(),
|
||||
uid: $user.userInfo.uid.toString(),
|
||||
countReq: 10
|
||||
})
|
||||
if (code === 0) {
|
||||
if (typeList[progress.value] === 'setting') {
|
||||
const { code: resultCode } = await lockDataUploadRequest({
|
||||
lockId: $bluetooth.currentLockInfo.lockId,
|
||||
uploadType: 1,
|
||||
records: data.list
|
||||
})
|
||||
uni.hideLoading()
|
||||
pending.value = false
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
if (resultCode === 0) {
|
||||
uni.showToast({
|
||||
title: '上传成功',
|
||||
icon: 'none'
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '上传失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
list.value = list.value.concat(data.list)
|
||||
if (data.size === 10) {
|
||||
page.value++
|
||||
} else if (data.size === 0) {
|
||||
page.value = 0
|
||||
list.value = []
|
||||
progress.value++
|
||||
} else {
|
||||
const { code: resultCode } = await lockDataUploadRequest({
|
||||
lockId: $bluetooth.currentLockInfo.lockId,
|
||||
uploadType: 2,
|
||||
recordType: progress.value + 2,
|
||||
records: list.value
|
||||
})
|
||||
if (resultCode !== 0) {
|
||||
pending.value = false
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '上传失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
page.value = 1
|
||||
list.value = []
|
||||
progress.value++
|
||||
}
|
||||
await asyncData(true)
|
||||
} else {
|
||||
pending.value = false
|
||||
$bluetooth.closeBluetoothConnection()
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '上传失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $uni-bg-color-grey;
|
||||
}
|
||||
</style>
|
||||
@ -266,6 +266,36 @@ const pages = [
|
||||
name: 'selectGroup',
|
||||
path: '/pages/selectGroup/selectGroup',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'updateSetting',
|
||||
path: '/pages/updateSetting/updateSetting',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'lockSound',
|
||||
path: '/pages/lockSound/lockSound',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'autoLock',
|
||||
path: '/pages/autoLock/autoLock',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'faceSetting',
|
||||
path: '/pages/faceSetting/faceSetting',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'lockDate',
|
||||
path: '/pages/lockDate/lockDate',
|
||||
tabBar: false
|
||||
},
|
||||
{
|
||||
name: 'uploadLockData',
|
||||
path: '/pages/uploadLockData/uploadLockData',
|
||||
tabBar: false
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@ -40,7 +40,23 @@ const cmdIds = {
|
||||
// 清理用户
|
||||
cleanUser: 0x300c,
|
||||
// 扩展命令
|
||||
expandCmd: 0x3030
|
||||
expandCmd: 0x3030,
|
||||
// 校准时间
|
||||
calibrationTime: 0x30f0,
|
||||
// 锁密码列表
|
||||
lockPasswordList: 0x3021,
|
||||
// 锁卡片列表
|
||||
lockCardList: 0x3022,
|
||||
// 锁指纹列表
|
||||
lockFingerprintList: 0x3023,
|
||||
// 锁人脸列表
|
||||
lockFaceList: 0x3024,
|
||||
// 锁掌静脉列表
|
||||
lockPalmVeinList: 0x3025,
|
||||
// 锁遥控列表
|
||||
lockRemoteList: 0x3026,
|
||||
// 锁设置列表
|
||||
lockSettingList: 0x302a
|
||||
}
|
||||
|
||||
// 子命令ID
|
||||
@ -86,7 +102,11 @@ const subCmdIds = {
|
||||
// 同步操作记录
|
||||
syncRecord: 41,
|
||||
// 更新管理员密码
|
||||
updateAdminPassword: 2
|
||||
updateAdminPassword: 2,
|
||||
// 修改设置
|
||||
updateSetting: 70,
|
||||
// 修改设置带参数
|
||||
updateSettingWithParams: 72
|
||||
}
|
||||
|
||||
export const useBluetoothStore = defineStore('ble', {
|
||||
@ -319,6 +339,7 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
mode: 'ecb',
|
||||
output: 'array'
|
||||
})
|
||||
const length = binaryData[10] * 256 + binaryData[11]
|
||||
console.log('ecb解密后的数据', decrypted)
|
||||
|
||||
const cmdId = decrypted[0] * 256 + decrypted[1]
|
||||
@ -523,6 +544,24 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
code: decrypted[2]
|
||||
})
|
||||
break
|
||||
case subCmdIds.updateSetting:
|
||||
that.updateCurrentLockInfo({
|
||||
...that.currentLockInfo,
|
||||
token: decrypted.slice(5, 9)
|
||||
})
|
||||
characteristicValueCallback({
|
||||
code: decrypted[2]
|
||||
})
|
||||
break
|
||||
case subCmdIds.updateSettingWithParams:
|
||||
that.updateCurrentLockInfo({
|
||||
...that.currentLockInfo,
|
||||
token: decrypted.slice(5, 9)
|
||||
})
|
||||
characteristicValueCallback({
|
||||
code: decrypted[2]
|
||||
})
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -588,6 +627,40 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
})
|
||||
}
|
||||
break
|
||||
case cmdIds.calibrationTime:
|
||||
characteristicValueCallback({
|
||||
code: decrypted[2]
|
||||
})
|
||||
break
|
||||
case cmdIds.lockPasswordList:
|
||||
case cmdIds.lockCardList:
|
||||
case cmdIds.lockFingerprintList:
|
||||
case cmdIds.lockFaceList:
|
||||
case cmdIds.lockPalmVeinList:
|
||||
case cmdIds.lockRemoteList:
|
||||
case cmdIds.lockSettingList:
|
||||
that.updateCurrentLockInfo({
|
||||
...that.currentLockInfo,
|
||||
token: decrypted.slice(3, 7)
|
||||
})
|
||||
let data
|
||||
if (cmdId === cmdIds.lockSettingList) {
|
||||
data = {
|
||||
list: decrypted.slice(7, length)
|
||||
}
|
||||
} else {
|
||||
data = {
|
||||
page: decrypted[7],
|
||||
size: decrypted[8],
|
||||
list: decrypted.slice(9, length)
|
||||
}
|
||||
}
|
||||
console.log(1234, cmdId, data)
|
||||
characteristicValueCallback({
|
||||
code: decrypted[2],
|
||||
data
|
||||
})
|
||||
break
|
||||
default:
|
||||
that.updateCurrentLockInfo({
|
||||
...that.currentLockInfo,
|
||||
@ -2733,6 +2806,297 @@ export const useBluetoothStore = defineStore('ble', {
|
||||
await this.writeBLECharacteristicValue(packageArray)
|
||||
|
||||
return this.getWriteResult(this.updateAdminPassword, data)
|
||||
},
|
||||
// 更新设置
|
||||
async updateSetting(data) {
|
||||
// 确认蓝牙状态正常
|
||||
if (this.bluetoothStatus !== 0) {
|
||||
console.log('写入未执行', this.bluetoothStatus)
|
||||
this.getBluetoothStatus()
|
||||
return {
|
||||
code: -1
|
||||
}
|
||||
}
|
||||
|
||||
// 确认设备连接正常
|
||||
if (!this.currentLockInfo.connected) {
|
||||
const searchResult = await this.searchAndConnectDevice()
|
||||
if (searchResult.code !== 0) {
|
||||
return searchResult
|
||||
}
|
||||
this.updateCurrentLockInfo({
|
||||
...this.currentLockInfo,
|
||||
deviceId: searchResult.data.deviceId
|
||||
})
|
||||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||||
const result = await this.connectBluetoothDevice()
|
||||
console.log('连接结果', result)
|
||||
if (!result) {
|
||||
return {
|
||||
code: -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否已添加为用户
|
||||
const checkResult = await this.checkLockUser()
|
||||
if (!checkResult) {
|
||||
return {
|
||||
code: -1
|
||||
}
|
||||
}
|
||||
|
||||
let { keyId, uid, featureBit, featureEnable, withParams, params } = data
|
||||
|
||||
let length = 2 + 1 + 1 + 40 + 20 + 4 + 1 + 16
|
||||
if (withParams) {
|
||||
length += 2 + params.length
|
||||
} else {
|
||||
length += 2
|
||||
}
|
||||
const headArray = this.createPackageHeader(3, length)
|
||||
const contentArray = new Uint8Array(length)
|
||||
|
||||
contentArray[0] = cmdIds.expandCmd / 256
|
||||
contentArray[1] = cmdIds.expandCmd % 256
|
||||
|
||||
contentArray[2] = withParams ? subCmdIds.updateSettingWithParams : subCmdIds.updateSetting
|
||||
|
||||
contentArray[3] = length - 3
|
||||
|
||||
for (let i = 0; i < keyId.length; i++) {
|
||||
contentArray[i + 4] = keyId.charCodeAt(i)
|
||||
}
|
||||
|
||||
for (let i = 0; i < uid.length; i++) {
|
||||
contentArray[i + 44] = uid.charCodeAt(i)
|
||||
}
|
||||
|
||||
contentArray[64] = featureBit
|
||||
|
||||
if (withParams) {
|
||||
contentArray[65] = params.length
|
||||
contentArray.set(new Uint8Array(params), 66)
|
||||
} else {
|
||||
contentArray[65] = featureEnable
|
||||
}
|
||||
|
||||
contentArray.set(
|
||||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||||
withParams ? 66 + params.length : 66
|
||||
)
|
||||
|
||||
contentArray[withParams ? 70 + params.length : 70] = 16
|
||||
|
||||
const md5Array = this.md5Encrypte(
|
||||
keyId + uid,
|
||||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||||
this.currentLockInfo.signKey
|
||||
)
|
||||
|
||||
contentArray.set(md5Array, withParams ? 71 + params.length : 71)
|
||||
|
||||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||||
mode: 'ecb',
|
||||
output: 'array'
|
||||
})
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
|
||||
await this.writeBLECharacteristicValue(packageArray)
|
||||
|
||||
return this.getWriteResult(this.updateSetting, data)
|
||||
},
|
||||
// 校准时间
|
||||
async calibrationTime(data) {
|
||||
// 确认蓝牙状态正常
|
||||
if (this.bluetoothStatus !== 0) {
|
||||
console.log('写入未执行', this.bluetoothStatus)
|
||||
this.getBluetoothStatus()
|
||||
return {
|
||||
code: -1
|
||||
}
|
||||
}
|
||||
|
||||
// 确认设备连接正常
|
||||
if (!this.currentLockInfo.connected) {
|
||||
const searchResult = await this.searchAndConnectDevice()
|
||||
if (searchResult.code !== 0) {
|
||||
return searchResult
|
||||
}
|
||||
this.updateCurrentLockInfo({
|
||||
...this.currentLockInfo,
|
||||
deviceId: searchResult.data.deviceId
|
||||
})
|
||||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||||
const result = await this.connectBluetoothDevice()
|
||||
console.log('连接结果', result)
|
||||
if (!result) {
|
||||
return {
|
||||
code: -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否已添加为用户
|
||||
const checkResult = await this.checkLockUser()
|
||||
if (!checkResult) {
|
||||
return {
|
||||
code: -1
|
||||
}
|
||||
}
|
||||
|
||||
let { lockId, uid, nowTime } = data
|
||||
const length = 2 + 40 + 20 + 4 + 4 + 1 + 16
|
||||
const headArray = this.createPackageHeader(3, length)
|
||||
const contentArray = new Uint8Array(length)
|
||||
|
||||
contentArray[0] = cmdIds.calibrationTime / 256
|
||||
contentArray[1] = cmdIds.calibrationTime % 256
|
||||
|
||||
for (let i = 0; i < lockId.length; i++) {
|
||||
contentArray[i + 2] = lockId.charCodeAt(i)
|
||||
}
|
||||
|
||||
for (let i = 0; i < uid.length; i++) {
|
||||
contentArray[i + 42] = uid.charCodeAt(i)
|
||||
}
|
||||
|
||||
contentArray.set(this.timestampToArray(nowTime), 62)
|
||||
|
||||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 66)
|
||||
contentArray[70] = 16
|
||||
|
||||
const md5Array = this.md5Encrypte(
|
||||
lockId + uid,
|
||||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||||
this.currentLockInfo.signKey
|
||||
)
|
||||
|
||||
contentArray.set(md5Array, 71)
|
||||
|
||||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||||
mode: 'ecb',
|
||||
output: 'array'
|
||||
})
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
this.writeBLECharacteristicValue(packageArray)
|
||||
|
||||
return this.getWriteResult(this.calibrationTime, data)
|
||||
},
|
||||
// 获取锁数据列表
|
||||
async getLockDataList(data) {
|
||||
// 确认蓝牙状态正常
|
||||
if (this.bluetoothStatus !== 0) {
|
||||
console.log('写入未执行', this.bluetoothStatus)
|
||||
this.getBluetoothStatus()
|
||||
return {
|
||||
code: -1
|
||||
}
|
||||
}
|
||||
|
||||
// 确认设备连接正常
|
||||
if (!this.currentLockInfo.connected) {
|
||||
const searchResult = await this.searchAndConnectDevice()
|
||||
if (searchResult.code !== 0) {
|
||||
return searchResult
|
||||
}
|
||||
this.updateCurrentLockInfo({
|
||||
...this.currentLockInfo,
|
||||
deviceId: searchResult.data.deviceId
|
||||
})
|
||||
console.log('设备ID:', this.currentLockInfo.deviceId)
|
||||
const result = await this.connectBluetoothDevice()
|
||||
console.log('连接结果', result)
|
||||
if (!result) {
|
||||
return {
|
||||
code: -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否已添加为用户
|
||||
const checkResult = await this.checkLockUser()
|
||||
if (!checkResult) {
|
||||
return {
|
||||
code: -1
|
||||
}
|
||||
}
|
||||
|
||||
let { lockId, uid, page, countReq, type } = data
|
||||
let length = 2 + 40 + 20 + 4 + 1 + 16
|
||||
if (type !== 'setting') {
|
||||
length += 2
|
||||
}
|
||||
const headArray = this.createPackageHeader(3, length)
|
||||
const contentArray = new Uint8Array(length)
|
||||
|
||||
let id
|
||||
|
||||
if (type === 'password') {
|
||||
id = cmdIds.lockPasswordList
|
||||
} else if (type === 'card') {
|
||||
id = cmdIds.lockCardList
|
||||
} else if (type === 'fingerprint') {
|
||||
id = cmdIds.lockFingerprintList
|
||||
} else if (type === 'face') {
|
||||
id = cmdIds.lockFaceList
|
||||
} else if (type === 'remote') {
|
||||
id = cmdIds.lockRemoteList
|
||||
} else if (type === 'palmVein') {
|
||||
id = cmdIds.lockPalmVeinList
|
||||
} else if (type === 'setting') {
|
||||
id = cmdIds.lockSettingList
|
||||
}
|
||||
|
||||
contentArray[0] = id / 256
|
||||
contentArray[1] = id % 256
|
||||
|
||||
for (let i = 0; i < lockId.length; i++) {
|
||||
contentArray[i + 2] = lockId.charCodeAt(i)
|
||||
}
|
||||
|
||||
for (let i = 0; i < uid.length; i++) {
|
||||
contentArray[i + 42] = uid.charCodeAt(i)
|
||||
}
|
||||
|
||||
if (type !== 'setting') {
|
||||
contentArray[62] = page
|
||||
contentArray[63] = countReq
|
||||
|
||||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 64)
|
||||
contentArray[68] = 16
|
||||
|
||||
const md5Array = this.md5Encrypte(
|
||||
lockId + uid,
|
||||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||||
this.currentLockInfo.signKey
|
||||
)
|
||||
|
||||
contentArray.set(md5Array, 69)
|
||||
} else {
|
||||
contentArray.set(this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), 62)
|
||||
contentArray[66] = 16
|
||||
|
||||
const md5Array = this.md5Encrypte(
|
||||
lockId + uid,
|
||||
this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]),
|
||||
this.currentLockInfo.signKey
|
||||
)
|
||||
|
||||
contentArray.set(md5Array, 67)
|
||||
}
|
||||
|
||||
const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.commKey, {
|
||||
mode: 'ecb',
|
||||
output: 'array'
|
||||
})
|
||||
|
||||
const packageArray = this.createPackageEnd(headArray, cebArray)
|
||||
this.writeBLECharacteristicValue(packageArray)
|
||||
|
||||
return this.getWriteResult(this.getLockDataList, data)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user