wx-starlock/pages/createPassword/createPassword.vue
2025-02-17 15:41:41 +08:00

662 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<view class="tabs">
<up-tabs
:list="tabs"
lineWidth="40rpx"
lineHeight="5rpx"
:current="currentIndex"
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="currentIndex"
@change="changeSwiper"
>
<swiper-item>
<LockInput
:value="permanentName"
title="姓名"
placeholder="请给密码命名"
@change-input="changeName('permanent', $event)"
></LockInput>
<view class="text">{{ text }}</view>
<view class="button" @click="createPassword('permanent')">获取密码</view>
</swiper-item>
<swiper-item>
<LockInput
:value="temporaryName"
title="姓名"
placeholder="请给密码命名"
@change-input="changeName('temporary', $event)"
></LockInput>
<view style="margin-top: 20rpx">
<LockDateHourPicker
title="失效时间"
:value="temporaryTime"
:minDate="minDate"
:maxDate="maxDate"
type="datehour"
@change-time="changeTemporaryTime"
></LockDateHourPicker>
</view>
<view class="text">{{ text }}</view>
<view class="button" @click="createPassword('temporary')">获取密码</view>
</swiper-item>
<swiper-item>
<LockInput
:value="singleName"
title="姓名"
placeholder="请给密码命名"
@change-input="changeName('single', $event)"
></LockInput>
<view class="text">密码有效期为6个小时只能使用一次</view>
<view class="button" @click="createPassword('single')">获取密码</view>
</swiper-item>
<swiper-item>
<LockInput
:value="customName"
title="姓名"
placeholder="请给密码命名"
@change-input="changeName('custom', $event)"
></LockInput>
<LockInput
:value="customPassword"
title="密码"
placeholder="请输入6-9位数字"
:maxlength="9"
type="number"
@change-input="changePassword('custom', $event)"
></LockInput>
<view class="mt-3 border-b-2 border-b-solid border-b-gray-200">
<LockSwitch
:value="customPermanent"
title="永久"
@change="changePermanent('custom', $event)"
></LockSwitch>
</view>
<view v-if="!customPermanent" class="border-b-2 border-b-solid border-b-gray-200">
<LockDatetimePicker
title="生效时间"
:value="customStartTime"
@change-time="changeDate('customStartTime', $event)"
></LockDatetimePicker>
</view>
<view v-if="!customPermanent">
<LockDatetimePicker
title="失效时间"
:value="customEndTime"
@change-time="changeDate('customEndTime', $event)"
></LockDatetimePicker>
</view>
<view class="mt-3">
<LockSwitch
:value="customAdmin"
title="是否为管理员"
@change="changeAdmin('custom', $event)"
></LockSwitch>
</view>
<view class="text">
手动输入6-9位数字作为密码可在锁旁边通过手机蓝牙添加也可通过网关远程添加
</view>
<view class="button" @click="createPassword('custom')">获取密码</view>
</swiper-item>
<swiper-item>
<LockInput
:value="cycleName"
title="姓名"
placeholder="请给密码命名"
@change-input="changeName('cycle', $event)"
></LockInput>
<view style="margin-top: 20rpx" class="border-b-2 border-b-solid border-b-gray-200">
<view
@click="showCycle = true"
class="flex items-center bg-white font-bold text-base h-100 w-full"
>
<view class="w-168 ml-4 leading-[100rpx]">有效日</view>
<view class="ml-a mr-2 flex items-center">
<view class="mr-2 text-right w-[518rpx] h-100 leading-[100rpx]"
>{{ cycleOptions[0][defaultIndex].name }}
</view>
<up-icon name="arrow-right"></up-icon>
</view>
</view>
</view>
<view class="border-b-2 border-b-solid border-b-gray-200">
<view
@click="showHoursStart = true"
class="flex items-center bg-white font-bold text-base h-100 w-full"
>
<view class="w-168 ml-4 leading-[100rpx]">生效时间</view>
<view class="ml-a mr-2 flex items-center">
<view class="mr-2 text-right w-[518rpx] h-100 leading-[100rpx]"
>{{ hoursStart }}:00
</view>
<up-icon name="arrow-right"></up-icon>
</view>
</view>
</view>
<view>
<view
@click="showHoursEnd = true"
class="flex items-center bg-white font-bold text-base h-100 w-full"
>
<view class="w-168 ml-4 leading-[100rpx]">失效时间</view>
<view class="ml-a mr-2 flex items-center">
<view class="mr-2 text-right w-[518rpx] h-100 leading-[100rpx]">
{{ hoursEnd }}:00</view
>
<up-icon name="arrow-right"></up-icon>
</view>
</view>
</view>
<view class="text">{{ text }}</view>
<view class="button" @click="createPassword('cycle')">获取密码</view>
</swiper-item>
<swiper-item>
<LockInput
:value="emptyName"
title="姓名"
placeholder="请给密码命名"
@change-input="changeName('empty', $event)"
></LockInput>
<view class="text">
<view>清空密码当日23:59前有效</view>
<view>
清空内容1:当日0点前生成的所有密码(当日0点后生成的密码不受清空密码影响可继续使用)
</view>
<view>清空内容2:清空密码使用后立即清除所有自定义密码(含使用过和未使用过的)</view>
<view>如需彻底清除所有密码请使用重置所有密码功能</view></view
>
<view class="button" @click="createPassword('empty')">获取密码</view>
</swiper-item>
</swiper>
<up-picker
:show="showCycle"
:columns="cycleOptions"
keyName="name"
:defaultIndex="[defaultIndex]"
@close="showCycle = false"
closeOnClickOverlay
@cancel="showCycle = false"
@confirm="selectCycle"
></up-picker>
<up-picker
:show="showHoursStart"
:columns="hours"
:defaultIndex="[hoursStart]"
closeOnClickOverlay
@close="showHoursStart = false"
@cancel="showHoursStart = false"
@confirm="selectHours('start', $event)"
></up-picker>
<up-picker
:show="showHoursEnd"
:columns="hours"
:defaultIndex="[hoursEnd]"
closeOnClickOverlay
@close="showHoursEnd = false"
@cancel="showHoursEnd = false"
@confirm="selectHours('end', $event)"
></up-picker>
</view>
</template>
<script setup>
import { timeFormat } from 'uview-plus'
import { onMounted, ref } from 'vue'
import test from 'uview-plus/libs/function/test'
import { useBasicStore } from '@/stores/basic'
import LockInput from '@/components/LockInput/LockInput.vue'
import LockDateHourPicker from '@/components/LockDateHourPicker/LockDateHourPicker.vue'
import { addCustomPasswordRequest, createPsaawordRequest } from '@/api/keyboardPwd'
import { useBluetoothStore } from '@/stores/bluetooth'
import { useLockStore } from '@/stores/lock'
import { useUserStore } from '@/stores/user'
const $lock = useLockStore()
const $basic = useBasicStore()
const $bluetooth = useBluetoothStore()
const $user = useUserStore()
const tabs = [
{
name: '永久'
},
{
name: '限时'
},
{
name: '单次'
},
{
name: '自定义'
},
{
name: '循环'
},
{
name: '清空'
}
]
const cycleOptions = ref([
[
{ type: 5, name: '周末' },
{ type: 6, name: '每日' },
{ type: 7, name: '工作日' },
{ type: 8, name: '星期一' },
{ type: 9, name: '星期二' },
{ type: 10, name: '星期三' },
{ type: 11, name: '星期四' },
{ type: 12, name: '星期五' },
{ type: 13, name: '星期六' },
{ type: 14, name: '星期日' }
]
])
const defaultIndex = ref(0)
const showCycle = ref(false)
const showHoursStart = ref(false)
const showHoursEnd = ref(false)
const hours = ref([Array.from({ length: 25 }, (v, k) => `${k}`)])
const permanentName = ref('')
const temporaryName = ref('')
const singleName = ref('')
const customName = ref('')
const cycleName = ref('')
const emptyName = ref('')
const temporaryTime = ref(Number(new Date()))
const customPermanent = ref(true)
const customStartTime = ref(0)
const customEndTime = ref(0)
const customAdmin = ref(false)
const customPassword = ref('')
const hoursStart = ref(0)
const hoursEnd = ref(0)
const minDate = ref(Number(new Date()))
const maxDate = ref(Number(4133951940000))
const currentIndex = ref(0)
const deviceInfo = ref(null)
const pending = ref(false)
const text = ref(
'密码生成后请在当日2359前使用一次进行激活否则过0点后未激活则失效。密码激活后有效期内不限次数使用。'
)
onMounted(async () => {
deviceInfo.value = await $basic.getDeviceInfo()
temporaryTime.value = Number(getNextFullHour())
hoursStart.value = Number(timeFormat(getNextFullHour(), 'h')) - 1
hoursEnd.value = Number(timeFormat(getNextFullHour(), 'h'))
minDate.value = Number(getNextFullHour())
maxDate.value = Number(getFutureTimestamp())
})
const changePassword = (type, e) => {
if (type === 'custom') {
customPassword.value = e
}
}
const selectCycle = e => {
showCycle.value = false
defaultIndex.value = e.indexs[0]
}
const changePermanent = (type, e) => {
if (type === 'custom') {
customPermanent.value = e.detail.value
if (customPermanent.value) {
customStartTime.value = 0
customEndTime.value = 0
} else {
customStartTime.value = new Date().getTime()
customEndTime.value = new Date().getTime()
}
}
}
const changeAdmin = (type, e) => {
if (type === 'custom') {
customAdmin.value = e.detail.value
}
}
const changeDate = (type, e) => {
if (type === 'customStartTime') {
customStartTime.value = e
} else {
customEndTime.value = e
}
}
const selectHours = (type, e) => {
if (type === 'start') {
showHoursStart.value = false
hoursStart.value = e.indexs[0]
} else {
showHoursEnd.value = false
hoursEnd.value = e.indexs[0]
}
}
const getNextFullHour = () => {
const now = new Date()
const currentHour = now.getHours() + 1
now.setHours(currentHour)
now.setMinutes(0)
now.setSeconds(0)
now.setMilliseconds(0)
return now
}
const getFutureTimestamp = () => {
const currentDate = new Date()
const year = currentDate.getFullYear()
const month = currentDate.getMonth()
const day = currentDate.getDate()
const futureDate = new Date(year + 3, month, day, 23, 0, 0)
return futureDate.getTime()
}
const createPassword = async type => {
if (
(type === 'temporary' && temporaryName.value === '') ||
(type === 'permanent' && permanentName.value === '') ||
(type === 'single' && singleName.value === '') ||
(type === 'cycle' && cycleName.value === '') ||
(type === 'empty' && emptyName.value === '') ||
(type === 'custom' && customName.value === '')
) {
uni.showToast({
title: '名称不能为空',
icon: 'none'
})
return
}
if (type === 'custom' && !test.rangeLength(customPassword.value, [6, 9])) {
uni.showToast({
title: '密码为6-9位纯数字',
icon: 'none'
})
return
}
if (
type === 'custom' &&
customPermanent.value === false &&
customStartTime.value >= customEndTime.value
) {
uni.showToast({
title: '失效时间需晚于生效时间',
icon: 'none'
})
return
}
if (type === 'cycle' && hoursStart.value >= hoursEnd.value) {
uni.showToast({
title: '失效时间需晚于生效时间',
icon: 'none'
})
return
}
const netWork = await $basic.getNetworkType()
if (!netWork) {
return
}
if (pending.value) {
return
}
pending.value = true
if (type === 'custom') {
uni.showLoading({
title: '生成中'
})
const params = {
keyId: $bluetooth.keyId.toString(),
uid: $user.userInfo.uid.toString(),
pwdNo: 0,
operate: 0,
isAdmin: customAdmin.value ? 1 : 0,
pwd: customPassword.value,
userCountLimit: 0xffff,
startTime: Math.floor(customStartTime.value / 1000),
endTime: Math.floor(customEndTime.value / 1000)
}
const { code, data } = await $bluetooth.setLockPassword(params)
if (code === 0 && data.status === 0) {
console.log(1111, data)
const { code: requestCode, message } = await addCustomPasswordRequest({
lockId: $bluetooth.currentLockInfo.lockId,
isCoerced: 2,
addType: 1,
pwdUserNo: data.no,
pwdRight: customAdmin.value ? 1 : 0,
keyboardPwdType: customPermanent.value ? 2 : 3,
keyboardPwdName: customName.value,
keyboardPwd: customPassword.value,
startDate: customStartTime.value,
endDate: customEndTime.value
})
uni.hideLoading()
if (requestCode === 0) {
uni.reportEvent('create_password', {})
$lock.updatePasswordSearch({
...$lock.passwordSearch,
pageNo: 1
})
$lock.getPasswordList($lock.passwordSearch)
uni.showModal({
title: '密码生成成功',
content: `密码:${customPassword.value}`,
cancelText: '复制',
success: res => {
if (res.confirm) {
uni.navigateBack()
} else {
uni.setClipboardData({
data: customPassword.value,
success: () => {
$basic.backAndToast('复制成功')
}
})
}
}
})
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
} else {
uni.hideLoading()
if (data.status === 0xff) {
uni.showToast({
title: '创建失败',
icon: 'none'
})
} 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'
})
} else {
uni.showToast({
title: '创建失败,请保持在锁附近',
icon: 'none'
})
}
}
} else {
let params = {
lockId: $bluetooth.currentLockInfo.lockId,
isCoerced: 2,
pwdRight: 0
}
if (type === 'temporary') {
params.keyboardPwdName = temporaryName.value
params.keyboardPwdType = 3
params.startDate = new Date().setHours(0, 0, 0, 0)
params.endDate = temporaryTime.value
params.hoursStart = 0
params.hoursEnd = 0
} else if (type === 'permanent') {
params.startDate = 0
params.endDate = 0
params.keyboardPwdName = permanentName.value
params.keyboardPwdType = 2
params.hoursStart = 0
params.hoursEnd = 0
} else if (type === 'single') {
params.startDate = 0
params.endDate = 0
params.keyboardPwdName = singleName.value
params.keyboardPwdType = 1
params.hoursStart = 0
params.hoursEnd = 0
} else if (type === 'cycle') {
params.startDate = new Date().getTime()
params.endDate = new Date().getTime()
params.keyboardPwdName = cycleName.value
params.keyboardPwdType = cycleOptions.value[0][defaultIndex.value].type
params.hoursStart = hoursStart.value
params.hoursEnd = hoursEnd.value
} else {
params.startDate = 0
params.endDate = 0
params.keyboardPwdName = emptyName.value
params.keyboardPwdType = 4
params.hoursStart = 0
params.hoursEnd = 0
}
const { code, data, message } = await createPsaawordRequest(params)
if (code === 0) {
uni.reportEvent('create_password', {})
$lock.updatePasswordSearch({
...$lock.passwordSearch,
pageNo: 1
})
$lock.getPasswordList($lock.passwordSearch)
uni.showModal({
title: '密码生成成功',
content: `密码:${data.keyboardPwd}`,
cancelText: '复制',
success: res => {
if (res.confirm) {
uni.navigateBack()
} else {
uni.setClipboardData({
data: data.keyboardPwd,
success: () => {
$basic.backAndToast('复制成功')
}
})
}
}
})
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
}
pending.value = false
}
const changeName = (type, e) => {
if (type === 'temporary') {
temporaryName.value = e
} else if (type === 'permanent') {
permanentName.value = e
} else if (type === 'single') {
singleName.value = e
} else if (type === 'cycle') {
cycleName.value = e
} else if (type === 'custom') {
customName.value = e
} else if (type === 'empty') {
emptyName.value = e
}
}
const changeTemporaryTime = e => {
temporaryTime.value = e
}
const clickTab = data => {
currentIndex.value = data.index
}
const changeSwiper = e => {
currentIndex.value = 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>