diff --git a/api/face.js b/api/face.js new file mode 100644 index 0000000..7b9cf69 --- /dev/null +++ b/api/face.js @@ -0,0 +1,48 @@ +import request from '../utils/request' + +// face 人脸模块 + +// 获取人脸列表 +export function getFaceList(data) { + return request({ + url: '/face/list', + method: 'POST', + data + }) +} + +// 删除人脸 +export function deleteFaceRequest(data) { + return request({ + url: '/face/delete', + method: 'POST', + data + }) +} + +// 清空人脸 +export function clearFaceRequest(data) { + return request({ + url: '/face/clear', + method: 'POST', + data + }) +} + +// 检查人脸名称是否重复 +export function checkFaceNameRequest(data) { + return request({ + url: '/face/checkFaceName', + method: 'POST', + data + }) +} + +// 添加人脸 +export function addFaceRequest(data) { + return request({ + url: '/face/add', + method: 'POST', + data + }) +} diff --git a/api/palmVein.js b/api/palmVein.js new file mode 100644 index 0000000..83e1327 --- /dev/null +++ b/api/palmVein.js @@ -0,0 +1,48 @@ +import request from '../utils/request' + +// palmVein 掌纹模块 + +// 获取掌纹列表 +export function getPalmVeinList(data) { + return request({ + url: '/palmVein/list', + method: 'POST', + data + }) +} + +// 删除掌纹 +export function deletePalmVeinRequest(data) { + return request({ + url: '/palmVein/delete', + method: 'POST', + data + }) +} + +// 清空掌纹 +export function clearPalmVeinRequest(data) { + return request({ + url: '/palmVein/clear', + method: 'POST', + data + }) +} + +// 检查掌纹名称是否重复 +export function checkPalmVeinNameRequest(data) { + return request({ + url: '/palmVein/checkPalmVeinName', + method: 'POST', + data + }) +} + +// 添加掌纹 +export function addPalmVeinRequest(data) { + return request({ + url: '/palmVein/add', + method: 'POST', + data + }) +} diff --git a/api/record.js b/api/record.js new file mode 100644 index 0000000..a7c5fd3 --- /dev/null +++ b/api/record.js @@ -0,0 +1,48 @@ +import request from '../utils/request' + +// record 记录模块 + +// 获取事件记录列表 +export function getEventRecordListRequest(data) { + return request({ + url: '/lockRecords/lockEventList', + method: 'POST', + data + }) +} + +// 获取操作记录列表 +export function getRecordListRequest(data) { + return request({ + url: '/lockRecords/list', + method: 'POST', + data + }) +} + +// 清空操作记录 +export function clearRecordRequest(data) { + return request({ + url: '/lockRecords/clear', + method: 'POST', + data + }) +} + +// 查询最后一条记录时间 +export function getLastRecordTimeRequest(data) { + return request({ + url: '/lockRecords/getLastRecordTime', + method: 'POST', + data + }) +} + +// 锁记录上传 +export function uploadRecordRequest(data) { + return request({ + url: '/lockRecords/fromLock', + method: 'POST', + data + }) +} diff --git a/api/remote.js b/api/remote.js new file mode 100644 index 0000000..fe2bc64 --- /dev/null +++ b/api/remote.js @@ -0,0 +1,48 @@ +import request from '../utils/request' + +// remote 远程模块 + +// 获取远程列表 +export function getRemoteList(data) { + return request({ + url: '/remote/list', + method: 'POST', + data + }) +} + +// 删除远程 +export function deleteRemoteRequest(data) { + return request({ + url: '/remote/delete', + method: 'POST', + data + }) +} + +// 清空远程 +export function clearRemoteRequest(data) { + return request({ + url: '/remote/clear', + method: 'POST', + data + }) +} + +// 检查远程名称是否重复 +export function checkRemoteNameRequest(data) { + return request({ + url: '/remote/checkRemoteName', + method: 'POST', + data + }) +} + +// 添加远程 +export function addRemoteRequest(data) { + return request({ + url: '/remote/add', + method: 'POST', + data + }) +} diff --git a/components/LockSwitch/LockSwitch.vue b/components/LockSwitch/LockSwitch.vue index f23e8a1..294ac54 100644 --- a/components/LockSwitch/LockSwitch.vue +++ b/components/LockSwitch/LockSwitch.vue @@ -1,7 +1,16 @@ - {{ title }} + + {{ title }} + + {{ placeholder }} @@ -16,16 +25,26 @@ const props = defineProps({ title: String, placeholder: String, - value: Boolean + value: Boolean, + tip: String }) onMounted(() => { checked.value = props.value }) + const emits = defineEmits(['change']) + const change = e => { - console.log(111, e) - // this.$emit('changeInput', e.detail.value) + emits('change', e) + } + + const tipDialog = () => { + uni.showModal({ + title: '提示', + content: props.tip, + showCancel: false + }) } diff --git a/pages.json b/pages.json index d6d4f97..ff05c2b 100644 --- a/pages.json +++ b/pages.json @@ -197,6 +197,132 @@ "navigationBarTitleText": "添加指纹", "disableScroll": true } + }, + { + "path": "pages/faceList/faceList", + "style": { + "navigationBarTitleText": "人脸", + "disableScroll": true + } + }, + { + "path": "pages/createFace/createFace", + "style": { + "navigationBarTitleText": "添加人脸", + "disableScroll": true + } + }, + { + "path": "pages/faceDetail/faceDetail", + "style": { + "navigationBarTitleText": "人脸详情", + "disableScroll": true + } + }, + { + "path": "pages/bindFace/bindFace", + "style": { + "navigationBarTitleText": "添加人脸", + "disableScroll": true + } + }, + { + "path": "pages/remoteList/remoteList", + "style": { + "navigationBarTitleText": "遥控", + "disableScroll": true + } + }, + { + "path": "pages/createRemote/createRemote", + "style": { + "navigationBarTitleText": "添加遥控", + "disableScroll": true + } + }, + { + "path": "pages/remoteDetail/remoteDetail", + "style": { + "navigationBarTitleText": "遥控详情", + "disableScroll": true + } + }, + { + "path": "pages/bindRemote/bindRemote", + "style": { + "navigationBarTitleText": "添加遥控", + "disableScroll": true + } + }, + { + "path": "pages/palmVeinList/palmVeinList", + "style": { + "navigationBarTitleText": "掌静脉", + "disableScroll": true + } + }, + { + "path": "pages/createPalmVein/createPalmVein", + "style": { + "navigationBarTitleText": "添加掌静脉", + "disableScroll": true + } + }, + { + "path": "pages/palmVeinDetail/palmVeinDetail", + "style": { + "navigationBarTitleText": "掌静脉详情", + "disableScroll": true + } + }, + { + "path": "pages/bindPalmVein/bindPalmVein", + "style": { + "navigationBarTitleText": "添加掌静脉", + "disableScroll": true + } + }, + { + "path": "pages/createAdmin/createAdmin", + "style": { + "navigationBarTitleText": "创建授权管理员", + "disableScroll": true + } + }, + { + "path": "pages/adminDetail/adminDetail", + "style": { + "navigationBarTitleText": "授权管理员详情", + "disableScroll": true + } + }, + { + "path": "pages/adminList/adminList", + "style": { + "navigationBarTitleText": "授权管理员", + "disableScroll": true + } + }, + { + "path": "pages/recordList/recordList", + "style": { + "navigationBarTitleText": "操作记录", + "disableScroll": true + } + }, + { + "path": "pages/recordDetail/recordDetail", + "style": { + "navigationBarTitleText": "操作记录详情", + "disableScroll": true + } + }, + { + "path": "pages/typeRecordList/typeRecordList", + "style": { + "navigationBarTitleText": "操作记录", + "disableScroll": true + } } ], "globalStyle": { diff --git a/pages/adminDetail/adminDetail.vue b/pages/adminDetail/adminDetail.vue new file mode 100644 index 0000000..d16d1c6 --- /dev/null +++ b/pages/adminDetail/adminDetail.vue @@ -0,0 +1,157 @@ + + + + + 姓名 + {{ info.keyName }} + + + 有效期 + 永久 + + {{ timeFormat(info.startDate, 'yyyy-mm-dd h:M') }} + {{ timeFormat(info.endDate, 'yyyy-mm-dd h:M') }} + + + + 接受者 + {{ info.username }} + + + 添加者 + {{ info.senderUsername }} + + + 发送时间 + {{ timeFormat(info.sendDate, 'yyyy-mm-dd h:M') }} + + + 操作记录 + + + 删除 + + + + + + 同时删除其发送的所有钥匙,钥匙删除后不能恢复 + + + + + + + + + + + diff --git a/pages/adminList/adminList.vue b/pages/adminList/adminList.vue new file mode 100644 index 0000000..0704ebe --- /dev/null +++ b/pages/adminList/adminList.vue @@ -0,0 +1,399 @@ + + + + + + + + + + 暂无数据 + + + + + + + + + {{ item.keyName }} + + {{ $lock.getKeyStatus(item.keyStatus) }} + + + {{ item.timeText }} + + + + + + + + + + 添加授权管理员 + + + + + + 同时删除其发送的所有钥匙,钥匙删除后不能恢复 + + + + + + + + + + + diff --git a/pages/bindCard/bindCard.vue b/pages/bindCard/bindCard.vue index a4435cd..9cf2331 100644 --- a/pages/bindCard/bindCard.vue +++ b/pages/bindCard/bindCard.vue @@ -67,6 +67,28 @@ } else { $basic.backAndToast(message) } + } else if (data.status === 0xff) { + $basic.backAndToast('添加失败,请重试') + } else if (data.status === 0xfe) { + uni.showToast({ + title: '管理员已满', + icon: 'none' + }) + } else if (data.status === 0xfd) { + uni.showToast({ + title: '用户已满', + icon: 'none' + }) + } else if (data.status === 0xfc) { + uni.showToast({ + title: '卡片已满', + icon: 'none' + }) + } else if (data.status === 0xfb) { + uni.showToast({ + title: '卡片已存在', + icon: 'none' + }) } }) } diff --git a/pages/bindFace/bindFace.vue b/pages/bindFace/bindFace.vue new file mode 100644 index 0000000..a717da0 --- /dev/null +++ b/pages/bindFace/bindFace.vue @@ -0,0 +1,133 @@ + + + + + + + 请单人正对门锁,距离一个成年人手臂长度(约0.6米)。保持脸部无遮挡,漏出五官 + + 正在录入中… + 准备好了,开始添加 + + + + + + + diff --git a/pages/bindFingerprint/bindFingerprint.vue b/pages/bindFingerprint/bindFingerprint.vue index 5f4608f..5764617 100644 --- a/pages/bindFingerprint/bindFingerprint.vue +++ b/pages/bindFingerprint/bindFingerprint.vue @@ -4,7 +4,7 @@ {{ text }} - ({{ process }}/5) + ({{ process }}/{{ maxProcess }}) { if (options.info) { const params = JSON.parse(options.info) - const { code } = await $bluetooth.registerAuthentication(params) + const { code, data } = await $bluetooth.registerAuthentication(params) if (code === 0) { text.value = '请将您的手指按下' + maxProcess.value = data.maxProcess showProcess.value = true } else { $basic.backAndToast('操作失败,请重试') @@ -57,6 +59,7 @@ endDate: params.endDate, fingerprintName: params.fingerprintName, fingerprintNumber: String(data.fingerprintNumber), + fingerprintUserNo: String(data.fingerprintNumber), fingerprintType: params.fingerprintType, addType: 1, fingerRight: params.isAdmin, @@ -73,6 +76,28 @@ uni.$on('registerFingerprintProcess', data => { if (data.status === 0) { process.value = data.process + } else if (data.status === 0xff) { + $basic.backAndToast('添加失败,请重试') + } else if (data.status === 0xfe) { + uni.showToast({ + title: '管理员已满', + icon: 'none' + }) + } else if (data.status === 0xfd) { + uni.showToast({ + title: '用户已满', + icon: 'none' + }) + } else if (data.status === 0xfc) { + uni.showToast({ + title: '指纹已满', + icon: 'none' + }) + } else if (data.status === 0xfb) { + uni.showToast({ + title: '指纹已存在', + icon: 'none' + }) } }) } diff --git a/pages/bindPalmVein/bindPalmVein.vue b/pages/bindPalmVein/bindPalmVein.vue new file mode 100644 index 0000000..48680b4 --- /dev/null +++ b/pages/bindPalmVein/bindPalmVein.vue @@ -0,0 +1,106 @@ + + + + + {{ text }} + + + + + diff --git a/pages/bindRemote/bindRemote.vue b/pages/bindRemote/bindRemote.vue new file mode 100644 index 0000000..087e2fc --- /dev/null +++ b/pages/bindRemote/bindRemote.vue @@ -0,0 +1,114 @@ + + + + + + + + {{ text }} + + + + + + + diff --git a/pages/cardDetail/cardDetail.vue b/pages/cardDetail/cardDetail.vue index e5ad46d..f8038c1 100644 --- a/pages/cardDetail/cardDetail.vue +++ b/pages/cardDetail/cardDetail.vue @@ -39,7 +39,10 @@ 添加时间 {{ timeFormat(info.createDate, 'yyyy-mm-dd h:M') }} - + + 操作记录 + + 删除 @@ -50,11 +53,13 @@ import { onLoad } from '@dcloudio/uni-app' import { timeFormat } from 'uview-plus' import { useLockStore } from '@/stores/lock' + import { useBasicStore } from '@/stores/basic' const instance = getCurrentInstance().proxy const eventChannel = instance.getOpenerEventChannel() const $lock = useLockStore() + const $basic = useBasicStore() const info = ref(null) @@ -65,6 +70,17 @@ } }) + const toRecordList = async () => { + $basic.routeJump({ + name: 'typeRecordList', + params: { + name: info.value.cardName, + key: 'cardId', + id: info.value.cardId + } + }) + } + const deletePassword = async () => { eventChannel.emit('delete', {}) } diff --git a/pages/createAdmin/createAdmin.vue b/pages/createAdmin/createAdmin.vue new file mode 100644 index 0000000..e6b594b --- /dev/null +++ b/pages/createAdmin/createAdmin.vue @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + 发送 + + + + + + + + + + + + + + 发送 + + + + + + + + + + diff --git a/pages/createFace/createFace.vue b/pages/createFace/createFace.vue new file mode 100644 index 0000000..9c906c0 --- /dev/null +++ b/pages/createFace/createFace.vue @@ -0,0 +1,307 @@ + + + + + + + + + + + + + 下一步 + + + + + + + + + + + + + 下一步 + + + + + + + + + + diff --git a/pages/createFingerprint/createFingerprint.vue b/pages/createFingerprint/createFingerprint.vue index 920fbb0..4287fd3 100644 --- a/pages/createFingerprint/createFingerprint.vue +++ b/pages/createFingerprint/createFingerprint.vue @@ -39,7 +39,7 @@ @@ -83,7 +83,7 @@ diff --git a/pages/createPalmVein/createPalmVein.vue b/pages/createPalmVein/createPalmVein.vue new file mode 100644 index 0000000..63c1d1e --- /dev/null +++ b/pages/createPalmVein/createPalmVein.vue @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + 下一步 + + + + + + + + + + + + + + + + 下一步 + + + + + + + + + + diff --git a/pages/createRemote/createRemote.vue b/pages/createRemote/createRemote.vue new file mode 100644 index 0000000..4e4121b --- /dev/null +++ b/pages/createRemote/createRemote.vue @@ -0,0 +1,281 @@ + + + + + + + + + + 下一步 + + + + + + + + + + 下一步 + + + + + + + + + + diff --git a/pages/faceDetail/faceDetail.vue b/pages/faceDetail/faceDetail.vue new file mode 100644 index 0000000..df2e70c --- /dev/null +++ b/pages/faceDetail/faceDetail.vue @@ -0,0 +1,126 @@ + + + + + 人脸号 + {{ info.faceNumber }} + + + 姓名 + {{ info.faceName }} + + + 有效期 + 永久 + + {{ timeFormat(info.startDate, 'yyyy-mm-dd h:M') }} + {{ timeFormat(info.endDate, 'yyyy-mm-dd h:M') }} + + + {{ timeFormat(info.startDate, 'yyyy-mm-dd') }} + {{ timeFormat(info.endDate, 'yyyy-mm-dd') }} + + + + 有效日 + {{ $lock.convertWeekDaysToChineseString(info.weekDay) }} + + + 有效时间 + + {{ timeFormat(info.startDate, 'h:M') }} - {{ timeFormat(info.endDate, 'h:M') }} + + + + 添加者 + {{ info.senderUsername }} + + + 添加时间 + {{ timeFormat(info.createDate, 'yyyy-mm-dd h:M') }} + + + 操作记录 + + + 删除 + + + + + + + + + diff --git a/pages/faceList/faceList.vue b/pages/faceList/faceList.vue new file mode 100644 index 0000000..fa65ee1 --- /dev/null +++ b/pages/faceList/faceList.vue @@ -0,0 +1,464 @@ + + + + + + + + + + 暂无数据 + + + + + + + + + {{ item.faceName }} + + {{ item.statusText }} + + + {{ item.timeText }} + + + + + + + + + + 重置人脸 + 添加人脸 + + + + + + + + + diff --git a/pages/fingerprintDetail/fingerprintDetail.vue b/pages/fingerprintDetail/fingerprintDetail.vue index 2246aa2..4e3ad61 100644 --- a/pages/fingerprintDetail/fingerprintDetail.vue +++ b/pages/fingerprintDetail/fingerprintDetail.vue @@ -39,7 +39,10 @@ 添加时间 {{ timeFormat(info.createDate, 'yyyy-mm-dd h:M') }} - + + 操作记录 + + 删除 @@ -50,6 +53,9 @@ import { onLoad } from '@dcloudio/uni-app' import { timeFormat } from 'uview-plus' import { useLockStore } from '@/stores/lock' + import { useBasicStore } from '@/stores/basic' + + const $basic = useBasicStore() const instance = getCurrentInstance().proxy const eventChannel = instance.getOpenerEventChannel() @@ -58,6 +64,17 @@ const info = ref(null) + const toRecordList = async () => { + $basic.routeJump({ + name: 'typeRecordList', + params: { + name: info.value.fingerprintName, + key: 'fingerprintId', + id: info.value.fingerprintId + } + }) + } + onLoad(options => { if (options.info) { info.value = JSON.parse(options.info) diff --git a/pages/keyDetail/keyDetail.vue b/pages/keyDetail/keyDetail.vue index 4a7b498..131ceae 100644 --- a/pages/keyDetail/keyDetail.vue +++ b/pages/keyDetail/keyDetail.vue @@ -45,6 +45,10 @@ 发送时间 {{ timeFormat(currentKeyInfo.sendDate, 'yyyy-mm-dd h:M') }} + + 操作记录 + + 删除 指纹 - + + + 遥控 + + + + 人脸 + + + + 掌静脉 + + 授权管理员 - + 操作记录 @@ -163,7 +196,8 @@ ...mapActions(useBluetoothStore, [ 'openDoor', 'updateServerTimestamp', - 'closeBluetoothConnection' + 'closeBluetoothConnection', + 'syncRecord' ]), ...mapActions(useBasicStore, ['routeJump', 'backAndToast', 'getNetworkType']), closePopup() { @@ -252,7 +286,12 @@ openTime: parseInt(new Date().getTime() / 1000, 10) + this.time, onlineToken: this.onlineToken }) - this.closeBluetoothConnection() + this.syncRecord({ + keyId: this.currentLockInfo.toString(), + uid: this.userInfo.uid.toString() + }).then(() => { + this.closeBluetoothConnection() + }) if (type === 'open') { uni.reportEvent('open_door', { result: code, diff --git a/pages/palmVeinDetail/palmVeinDetail.vue b/pages/palmVeinDetail/palmVeinDetail.vue new file mode 100644 index 0000000..e68de89 --- /dev/null +++ b/pages/palmVeinDetail/palmVeinDetail.vue @@ -0,0 +1,127 @@ + + + + + 掌静脉号 + {{ info.palmVeinNumber }} + + + 姓名 + {{ info.palmVeinName }} + + + 有效期 + 永久 + + {{ timeFormat(info.startDate, 'yyyy-mm-dd h:M') }} + {{ timeFormat(info.endDate, 'yyyy-mm-dd h:M') }} + + + {{ timeFormat(info.startDate, 'yyyy-mm-dd') }} + {{ timeFormat(info.endDate, 'yyyy-mm-dd') }} + + + + 有效日 + {{ $lock.convertWeekDaysToChineseString(info.weekDay) }} + + + 有效时间 + + {{ timeFormat(info.startDate, 'h:M') }} - {{ timeFormat(info.endDate, 'h:M') }} + + + + 添加者 + {{ info.senderUsername }} + + + 添加时间 + {{ timeFormat(info.createDate, 'yyyy-mm-dd h:M') }} + + + 操作记录 + + + 删除 + + + + + + + + + diff --git a/pages/palmVeinList/palmVeinList.vue b/pages/palmVeinList/palmVeinList.vue new file mode 100644 index 0000000..9f409f0 --- /dev/null +++ b/pages/palmVeinList/palmVeinList.vue @@ -0,0 +1,468 @@ + + + + + + + + + + 暂无数据 + + + + + + + + + + + {{ item.palmVeinName }} + + {{ item.statusText }} + + + {{ item.timeText }} + + + + + + + + + + 重置掌静脉 + 添加掌静脉 + + + + + + + + + diff --git a/pages/passwordDetail/passwordDetail.vue b/pages/passwordDetail/passwordDetail.vue index e39bbe5..734e9eb 100644 --- a/pages/passwordDetail/passwordDetail.vue +++ b/pages/passwordDetail/passwordDetail.vue @@ -33,6 +33,10 @@ timeFormat(currentPasswordInfo.sendDate, 'yyyy-mm-dd h:M') }} + + 操作记录 + + 删除 @@ -59,7 +63,17 @@ timeFormat, ...mapActions(useBluetoothStore, ['setLockPassword', 'closeBluetoothConnection']), ...mapActions(useLockStore, ['updatePasswordSearch', 'getPasswordList']), - ...mapActions(useBasicStore, ['backAndToast', 'getNetworkType']), + ...mapActions(useBasicStore, ['backAndToast', 'getNetworkType', 'routeJump']), + async toRecordList() { + this.routeJump({ + name: 'typeRecordList', + params: { + name: this.currentPasswordInfo.keyboardPwdName, + key: 'keyboardPwdId', + id: this.currentPasswordInfo.keyboardPwdId + } + }) + }, async deletePassword() { const netWork = await this.getNetworkType() if (!netWork) { diff --git a/pages/recordDetail/recordDetail.vue b/pages/recordDetail/recordDetail.vue new file mode 100644 index 0000000..2079ffe --- /dev/null +++ b/pages/recordDetail/recordDetail.vue @@ -0,0 +1,32 @@ + + + + 操作时间:{{ timeFormat(info.operateDate, 'yyyy-mm-dd h:M') }}{{ + }} + {{ + info.recordDetailStr + }} + + + + + + diff --git a/pages/recordList/recordList.vue b/pages/recordList/recordList.vue new file mode 100644 index 0000000..2ecd987 --- /dev/null +++ b/pages/recordList/recordList.vue @@ -0,0 +1,448 @@ + + + + 日期: + + + + + + 事件: + + + + + + + + + + + 暂无数据 + + + + + + + + {{ item.recordStr }} + + + + + + + + + + + + 清空记录 + 同步记录 + + + + + + + + + diff --git a/pages/remoteDetail/remoteDetail.vue b/pages/remoteDetail/remoteDetail.vue new file mode 100644 index 0000000..ca9b62f --- /dev/null +++ b/pages/remoteDetail/remoteDetail.vue @@ -0,0 +1,127 @@ + + + + + 遥控号 + {{ info.remoteNumber }} + + + 姓名 + {{ info.remoteName }} + + + 有效期 + 永久 + + {{ timeFormat(info.startDate, 'yyyy-mm-dd h:M') }} + {{ timeFormat(info.endDate, 'yyyy-mm-dd h:M') }} + + + {{ timeFormat(info.startDate, 'yyyy-mm-dd') }} + {{ timeFormat(info.endDate, 'yyyy-mm-dd') }} + + + + 有效日 + {{ $lock.convertWeekDaysToChineseString(info.weekDay) }} + + + 有效时间 + + {{ timeFormat(info.startDate, 'h:M') }} - {{ timeFormat(info.endDate, 'h:M') }} + + + + 添加者 + {{ info.senderUsername }} + + + 添加时间 + {{ timeFormat(info.createDate, 'yyyy-mm-dd h:M') }} + + + 操作记录 + + + 删除 + + + + + + + + + diff --git a/pages/remoteList/remoteList.vue b/pages/remoteList/remoteList.vue new file mode 100644 index 0000000..7470f29 --- /dev/null +++ b/pages/remoteList/remoteList.vue @@ -0,0 +1,466 @@ + + + + + + + + + + 暂无数据 + + + + + + + + + + + {{ item.remoteName }} + + {{ item.statusText }} + + + {{ item.timeText }} + + + + + + + + + + 重置遥控 + 添加遥控 + + + + + + + + + diff --git a/pages/typeRecordList/typeRecordList.vue b/pages/typeRecordList/typeRecordList.vue new file mode 100644 index 0000000..93a9a72 --- /dev/null +++ b/pages/typeRecordList/typeRecordList.vue @@ -0,0 +1,272 @@ + + + + + + + 暂无数据 + + + + + + {{ timeFormat(item.operateDate, 'yyyy-mm-dd h:M') }} + {{ item.recordTypeName }} + + + + + + + + 同步记录 + + + + + + + + + diff --git a/static/images/background_close_door.png b/static/images/background_close_door.png index 04f5fa5..1b3d33e 100755 Binary files a/static/images/background_close_door.png and b/static/images/background_close_door.png differ diff --git a/static/images/background_empty_list.png b/static/images/background_empty_list.png index 80cdb63..339ed19 100644 Binary files a/static/images/background_empty_list.png and b/static/images/background_empty_list.png differ diff --git a/static/images/background_main.jpg b/static/images/background_main.jpg index 53c25b1..e51efc0 100644 Binary files a/static/images/background_main.jpg and b/static/images/background_main.jpg differ diff --git a/static/images/background_open_door.png b/static/images/background_open_door.png index e2a93f5..73313ab 100644 Binary files a/static/images/background_open_door.png and b/static/images/background_open_door.png differ diff --git a/static/images/icon_add.png b/static/images/icon_add.png index 937c30b..73524e6 100644 Binary files a/static/images/icon_add.png and b/static/images/icon_add.png differ diff --git a/static/images/icon_add_blue.png b/static/images/icon_add_blue.png index d08fc12..fd36391 100644 Binary files a/static/images/icon_add_blue.png and b/static/images/icon_add_blue.png differ diff --git a/static/images/icon_add_card.png b/static/images/icon_add_card.png index 0e25497..dd3a520 100755 Binary files a/static/images/icon_add_card.png and b/static/images/icon_add_card.png differ diff --git a/static/images/icon_add_face_1.png b/static/images/icon_add_face_1.png new file mode 100755 index 0000000..aeacd24 Binary files /dev/null and b/static/images/icon_add_face_1.png differ diff --git a/static/images/icon_add_face_2.png b/static/images/icon_add_face_2.png new file mode 100755 index 0000000..90e5f03 Binary files /dev/null and b/static/images/icon_add_face_2.png differ diff --git a/static/images/icon_add_palm_vein.png b/static/images/icon_add_palm_vein.png new file mode 100755 index 0000000..d491e67 Binary files /dev/null and b/static/images/icon_add_palm_vein.png differ diff --git a/static/images/icon_add_remote.png b/static/images/icon_add_remote.png new file mode 100644 index 0000000..b2e956f Binary files /dev/null and b/static/images/icon_add_remote.png differ diff --git a/static/images/icon_add_round.png b/static/images/icon_add_round.png index d0f9a4d..6f76848 100644 Binary files a/static/images/icon_add_round.png and b/static/images/icon_add_round.png differ diff --git a/static/images/icon_address.png b/static/images/icon_address.png index d2ddd5e..fd4022e 100644 Binary files a/static/images/icon_address.png and b/static/images/icon_address.png differ diff --git a/static/images/icon_admin.png b/static/images/icon_admin.png index d2a83cf..c389a77 100755 Binary files a/static/images/icon_admin.png and b/static/images/icon_admin.png differ diff --git a/static/images/icon_admin_black.png b/static/images/icon_admin_black.png index c431086..825bc88 100644 Binary files a/static/images/icon_admin_black.png and b/static/images/icon_admin_black.png differ diff --git a/static/images/icon_arrow.png b/static/images/icon_arrow.png index a0a91ec..f0d9d84 100644 Binary files a/static/images/icon_arrow.png and b/static/images/icon_arrow.png differ diff --git a/static/images/icon_card.png b/static/images/icon_card.png index b660629..1355daf 100644 Binary files a/static/images/icon_card.png and b/static/images/icon_card.png differ diff --git a/static/images/icon_card_white.png b/static/images/icon_card_white.png index 355b5c0..719ada5 100755 Binary files a/static/images/icon_card_white.png and b/static/images/icon_card_white.png differ diff --git a/static/images/icon_cloud.png b/static/images/icon_cloud.png index e93fd9c..aa41ec5 100644 Binary files a/static/images/icon_cloud.png and b/static/images/icon_cloud.png differ diff --git a/static/images/icon_cloud_active.png b/static/images/icon_cloud_active.png index 13f3d99..f15e39f 100644 Binary files a/static/images/icon_cloud_active.png and b/static/images/icon_cloud_active.png differ diff --git a/static/images/icon_delete.png b/static/images/icon_delete.png index 0c990ec..2559304 100644 Binary files a/static/images/icon_delete.png and b/static/images/icon_delete.png differ diff --git a/static/images/icon_door_lock.png b/static/images/icon_door_lock.png index 72dd4b9..5ee591d 100755 Binary files a/static/images/icon_door_lock.png and b/static/images/icon_door_lock.png differ diff --git a/static/images/icon_face.png b/static/images/icon_face.png new file mode 100644 index 0000000..ce6b9fd Binary files /dev/null and b/static/images/icon_face.png differ diff --git a/static/images/icon_face_white.png b/static/images/icon_face_white.png new file mode 100755 index 0000000..739bd42 Binary files /dev/null and b/static/images/icon_face_white.png differ diff --git a/static/images/icon_fingerprint.png b/static/images/icon_fingerprint.png index 19e66bd..6ec6147 100644 Binary files a/static/images/icon_fingerprint.png and b/static/images/icon_fingerprint.png differ diff --git a/static/images/icon_fingerprint_0.png b/static/images/icon_fingerprint_0.png index ffc2d97..5ef3c50 100755 Binary files a/static/images/icon_fingerprint_0.png and b/static/images/icon_fingerprint_0.png differ diff --git a/static/images/icon_fingerprint_1.png b/static/images/icon_fingerprint_1.png index ba603bf..cded470 100755 Binary files a/static/images/icon_fingerprint_1.png and b/static/images/icon_fingerprint_1.png differ diff --git a/static/images/icon_fingerprint_2.png b/static/images/icon_fingerprint_2.png index 89dea31..489de43 100755 Binary files a/static/images/icon_fingerprint_2.png and b/static/images/icon_fingerprint_2.png differ diff --git a/static/images/icon_fingerprint_3.png b/static/images/icon_fingerprint_3.png index a106ee5..b77d0fa 100755 Binary files a/static/images/icon_fingerprint_3.png and b/static/images/icon_fingerprint_3.png differ diff --git a/static/images/icon_fingerprint_4.png b/static/images/icon_fingerprint_4.png index 0c45326..ed7a18f 100755 Binary files a/static/images/icon_fingerprint_4.png and b/static/images/icon_fingerprint_4.png differ diff --git a/static/images/icon_fingerprint_5.png b/static/images/icon_fingerprint_5.png index a1e9b54..241b66f 100644 Binary files a/static/images/icon_fingerprint_5.png and b/static/images/icon_fingerprint_5.png differ diff --git a/static/images/icon_lock_touch_screen.png b/static/images/icon_lock_touch_screen.png index de3f363..c01adc9 100755 Binary files a/static/images/icon_lock_touch_screen.png and b/static/images/icon_lock_touch_screen.png differ diff --git a/static/images/icon_notification_read.png b/static/images/icon_notification_read.png index 95dc3cb..a9cb140 100755 Binary files a/static/images/icon_notification_read.png and b/static/images/icon_notification_read.png differ diff --git a/static/images/icon_notification_unread.png b/static/images/icon_notification_unread.png index be7a877..3a04613 100755 Binary files a/static/images/icon_notification_unread.png and b/static/images/icon_notification_unread.png differ diff --git a/static/images/icon_palm_vein.png b/static/images/icon_palm_vein.png new file mode 100644 index 0000000..018050b Binary files /dev/null and b/static/images/icon_palm_vein.png differ diff --git a/static/images/icon_palm_vein_white.png b/static/images/icon_palm_vein_white.png new file mode 100644 index 0000000..0b94f87 Binary files /dev/null and b/static/images/icon_palm_vein_white.png differ diff --git a/static/images/icon_remote.png b/static/images/icon_remote.png new file mode 100644 index 0000000..3bf9398 Binary files /dev/null and b/static/images/icon_remote.png differ diff --git a/static/images/icon_remote_white.png b/static/images/icon_remote_white.png new file mode 100644 index 0000000..8568eee Binary files /dev/null and b/static/images/icon_remote_white.png differ diff --git a/static/images/icon_sync.png b/static/images/icon_sync.png new file mode 100644 index 0000000..0473a40 Binary files /dev/null and b/static/images/icon_sync.png differ diff --git a/static/images/img.png b/static/images/img.png new file mode 100644 index 0000000..1837e47 Binary files /dev/null and b/static/images/img.png differ diff --git a/stores/basic.js b/stores/basic.js index 869ff81..b5a94fc 100644 --- a/stores/basic.js +++ b/stores/basic.js @@ -151,6 +151,96 @@ const pages = [ name: 'bindFingerprint', path: '/pages/bindFingerprint/bindFingerprint', tabBar: false + }, + { + name: 'faceList', + path: '/pages/faceList/faceList', + tabBar: false + }, + { + name: 'createFace', + path: '/pages/createFace/createFace', + tabBar: false + }, + { + name: 'faceDetail', + path: '/pages/faceDetail/faceDetail', + tabBar: false + }, + { + name: 'bindFace', + path: '/pages/bindFace/bindFace', + tabBar: false + }, + { + name: 'remoteList', + path: '/pages/remoteList/remoteList', + tabBar: false + }, + { + name: 'createRemote', + path: '/pages/createRemote/createRemote', + tabBar: false + }, + { + name: 'remoteDetail', + path: '/pages/remoteDetail/remoteDetail', + tabBar: false + }, + { + name: 'bindRemote', + path: '/pages/bindRemote/bindRemote', + tabBar: false + }, + { + name: 'palmVeinList', + path: '/pages/palmVeinList/palmVeinList', + tabBar: false + }, + { + name: 'createPalmVein', + path: '/pages/createPalmVein/createPalmVein', + tabBar: false + }, + { + name: 'palmVeinDetail', + path: '/pages/palmVeinDetail/palmVeinDetail', + tabBar: false + }, + { + name: 'bindPalmVein', + path: '/pages/bindPalmVein/bindPalmVein', + tabBar: false + }, + { + name: 'createAdmin', + path: '/pages/createAdmin/createAdmin', + tabBar: false + }, + { + name: 'adminDetail', + path: '/pages/adminDetail/adminDetail', + tabBar: false + }, + { + name: 'adminList', + path: '/pages/adminList/adminList', + tabBar: false + }, + { + name: 'recordList', + path: '/pages/recordList/recordList', + tabBar: false + }, + { + name: 'recordDetail', + path: '/pages/recordDetail/recordDetail', + tabBar: false + }, + { + name: 'typeRecordList', + path: '/pages/typeRecordList/typeRecordList', + tabBar: false } ] diff --git a/stores/bluetooth.js b/stores/bluetooth.js index 7e7ecd7..c223b7f 100644 --- a/stores/bluetooth.js +++ b/stores/bluetooth.js @@ -12,6 +12,7 @@ import { reportOpenDoorRequest } from '@/api/lockRecords' import { updateTimezoneOffsetRequest } from '@/api/user' import log from '@/utils/log' import { useUserStore } from '@/stores/user' +import { getLastRecordTimeRequest, uploadRecordRequest } from '@/api/record' // 定时器 let timer @@ -68,12 +69,22 @@ const subCmdIds = { registerFaceConfirm: 82, // 注册人脸取消 registerFaceCancel: 86, + // 注册人脸过程 + registerFaceProcess: 83, // 注册遥控 registerRemote: 26, // 注册遥控确认 registerRemoteConfirm: 27, // 注册遥控取消 - registerRemoteCancel: 28 + registerRemoteCancel: 28, + // 注册掌纹 + registerPalmVein: 42, + // 注册掌纹确认 + registerPalmVeinConfirm: 43, + // 注册掌纹取消 + registerPalmVeinCancel: 44, + // 同步操作记录 + syncRecord: 41 } export const useBluetoothStore = defineStore('ble', { @@ -256,7 +267,7 @@ export const useBluetoothStore = defineStore('ble', { }) }, // 解析特征值 - parsingCharacteristicValue(binaryData) { + async parsingCharacteristicValue(binaryData) { const $user = useUserStore() const that = this // 0x20 明文 0x22 SM4(事先约定密钥) 0x23 SM4(设备指定密钥) @@ -367,7 +378,6 @@ export const useBluetoothStore = defineStore('ble', { break case cmdIds.expandCmd: const subCmdId = decrypted[3] - // eslint-disable-next-line default-case switch (subCmdId) { case subCmdIds.resetLockPassword: that.updateCurrentLockInfo({ @@ -397,9 +407,8 @@ export const useBluetoothStore = defineStore('ble', { }) break case subCmdIds.registerCard: - case subCmdIds.registerFingerprint: - case subCmdIds.registerFace: case subCmdIds.registerRemote: + case subCmdIds.registerPalmVein: that.updateCurrentLockInfo({ ...that.currentLockInfo, token: decrypted.slice(5, 9) @@ -407,8 +416,20 @@ export const useBluetoothStore = defineStore('ble', { characteristicValueCallback({ code: decrypted[2], data: { - status: decrypted[9], - no: decrypted[10] * 256 + decrypted[11] + status: decrypted[9] + } + }) + break + case subCmdIds.registerFingerprint: + case subCmdIds.registerFace: + that.updateCurrentLockInfo({ + ...that.currentLockInfo, + token: decrypted.slice(5, 9) + }) + characteristicValueCallback({ + code: decrypted[2], + data: { + maxProcess: decrypted[11] } }) break @@ -424,12 +445,67 @@ export const useBluetoothStore = defineStore('ble', { fingerprintNumber: decrypted[6] * 256 + decrypted[7] }) break + case subCmdIds.registerFaceConfirm: + uni.$emit('registerFaceConfirm', { + status: decrypted[5], + faceNumber: decrypted[6] * 256 + decrypted[7] + }) + break + case subCmdIds.registerRemoteConfirm: + uni.$emit('registerRemoteConfirm', { + status: decrypted[5], + remoteNumber: decrypted[6] * 256 + decrypted[7] + }) + break + case subCmdIds.registerPalmVeinConfirm: + uni.$emit('registerPalmVeinConfirm', { + status: decrypted[5], + palmVeinNumber: decrypted[6] * 256 + decrypted[7] + }) + break case subCmdIds.registerFingerprintProcess: uni.$emit('registerFingerprintProcess', { status: decrypted[5], process: decrypted[6] }) break + case subCmdIds.registerFaceProcess: + uni.$emit('registerFaceProcess', { + status: decrypted[5], + process: decrypted[6] + }) + break + case subCmdIds.syncRecord: + if (decrypted[2] === 0 && decrypted[6] > 0) { + const records = [] + const count = decrypted[6] || 0 + for (let i = 0; i < count; i++) { + let password = decrypted.slice(14 + 17 * i, 14 + 17 * i + 10) + if (password.every(item => item === 0)) { + password = null + } else { + password = this.uint8ArrayToString(password) + } + const record = { + type: decrypted[7 + 17 * i], + user: decrypted[8 + 17 * i] * 256 + decrypted[9 + 17 * i], + date: this.arrayToTimestamp(decrypted.slice(10 + 17 * i, 14 + 17 * i)) * 1000, + success: 1, + password + } + records.push(record) + } + const { code, message } = await uploadRecordRequest({ + records, + lockId: this.currentLockInfo.lockId + }) + characteristicValueCallback({ code, data: { count }, message }) + } else { + characteristicValueCallback({ code: decrypted[2] }) + } + break + default: + break } break case cmdIds.openDoor: @@ -2292,8 +2368,10 @@ export const useBluetoothStore = defineStore('ble', { contentArray[2] = subCmdIds.registerFingerprint } else if (type === 'face') { contentArray[2] = subCmdIds.registerFace - } else { + } else if (type === 'remote') { contentArray[2] = subCmdIds.registerRemote + } else if (type === 'palmVein') { + contentArray[2] = subCmdIds.registerPalmVein } contentArray[3] = length - 3 @@ -2371,8 +2449,10 @@ export const useBluetoothStore = defineStore('ble', { contentArray[2] = subCmdIds.registerFingerprintCancel } else if (type === 'face') { contentArray[2] = subCmdIds.registerFaceCancel - } else { + } else if (type === 'remote') { contentArray[2] = subCmdIds.registerRemoteCancel + } else if (type === 'palmVein') { + contentArray[2] = subCmdIds.registerPalmVeinCancel } contentArray[3] = length - 3 @@ -2407,6 +2487,127 @@ export const useBluetoothStore = defineStore('ble', { await this.writeBLECharacteristicValue(packageArray) return this.getWriteResult(this.registerAuthenticationCancel, data) + }, + // 获取操作记录 + async syncRecord(params) { + const { uid, keyId } = params + + const { code, data, message } = await this.syncSingleRecord({ + uid, + keyId + }) + + if (code === 0) { + if (data?.count === 10) { + return await this.syncSingleRecord({ + uid, + keyId + }) + } + return { code, data, message } + } + return { code, data, message } + }, + // 获取单次操作记录 + async syncSingleRecord(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 + } + } + + const { keyId, uid } = data + + const logsCount = 10 + + const timeResult = await getLastRecordTimeRequest({ + lockId: this.currentLockInfo.lockId + }) + + if (timeResult.code !== 0) { + return timeResult + } + + const operateDate = Math.ceil(timeResult.data.operateDate / 1000) + const currentDate = Math.ceil(timeResult.data.currentDate / 1000) + + const length = 2 + 1 + 1 + 40 + 20 + 2 + 4 + 4 + 1 + 16 + const headArray = this.createPackageHeader(3, length) + + const contentArray = new Uint8Array(length) + contentArray[0] = cmdIds.expandCmd / 256 + contentArray[1] = cmdIds.expandCmd % 256 + + // 子命令 + contentArray[2] = subCmdIds.syncRecord + + 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] = logsCount / 256 + contentArray[65] = logsCount % 256 + + contentArray.set(this.timestampToArray(operateDate), 66) + contentArray.set(this.timestampToArray(currentDate), 70) + + contentArray[74] = 16 + + const md5Array = this.md5Encrypte( + uid + keyId, + this.currentLockInfo.token || new Uint8Array([0, 0, 0, 0]), + this.currentLockInfo.bluetooth.publicKey + ) + + contentArray.set(md5Array, 75) + + const cebArray = sm4.encrypt(contentArray, this.currentLockInfo.bluetooth.privateKey, { + mode: 'ecb', + output: 'array' + }) + + const packageArray = this.createPackageEnd(headArray, cebArray) + + await this.writeBLECharacteristicValue(packageArray) + + return this.getWriteResult(this.syncSingleRecord, data) } } })