290 lines
8.1 KiB
Vue
290 lines
8.1 KiB
Vue
<template>
|
||
<uni-popup ref="popup" type="center" :safe-area="true" :mask-click="false">
|
||
<view class="pay-password-dialog">
|
||
<view class="dialog-header">
|
||
<text class="title">{{ getDialogTitle }}</text>
|
||
<u-icon name="close" size="20" color="#999" @click="hide" />
|
||
</view>
|
||
|
||
<view class="form-container">
|
||
<!-- 关闭支付密码选项 -->
|
||
<view class="switch-item" v-if="hasOldPassword">
|
||
<text>关闭支付密码</text>
|
||
<u-switch v-model="isClosePassword" activeColor="#F32B2B" @change="handleSwitchChange" />
|
||
</view>
|
||
|
||
<!-- 旧密码 - 只在修改密码或关闭密码时显示 -->
|
||
<view class="form-item" v-if="hasOldPassword">
|
||
<text class="label">原密码:</text>
|
||
<view class="input-wrapper">
|
||
<u-input v-model="oldPassword" type="number" :border="false" placeholder="请输入原密码" :maxlength="6"
|
||
:disabled="isClosePassword" :password="!showOldPassword" @input="handleInput($event, 'oldPassword')" />
|
||
<u-icon :name="showOldPassword ? 'eye-off' : 'eye-fill'" size="20" color="#999"
|
||
v-if="hasOldPassword && !isClosePassword" @click="showOldPassword = !showOldPassword" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 新密码和确认密码部分 -->
|
||
<template v-if="!isClosePassword">
|
||
<!-- 新密码 -->
|
||
<view class="form-item">
|
||
<text class="label">新密码:</text>
|
||
<view class="input-wrapper">
|
||
<u-input v-model="newPassword" type="number" placeholder="请输入6位数字密码" maxlength="6" :border="false"
|
||
:password="!showNewPassword" @input="handleInput($event, 'newPassword')" />
|
||
<u-icon :name="showNewPassword ? 'eye-off' : 'eye-fill'" size="20" color="#999"
|
||
@click="showNewPassword = !showNewPassword" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 确认密码 -->
|
||
<view class="form-item">
|
||
<text class="label">确认密码:</text>
|
||
<view class="input-wrapper">
|
||
<u-input v-model="confirmPassword" type="number" :border="false" placeholder="请再次输入密码" maxlength="6"
|
||
:password="!showConfirmPassword" @input="handleInput($event, 'confirmPassword')" />
|
||
<u-icon :name="showConfirmPassword ? 'eye-off' : 'eye-fill'" size="20" color="#999"
|
||
@click="showConfirmPassword = !showConfirmPassword" />
|
||
</view>
|
||
</view>
|
||
</template>
|
||
</view>
|
||
|
||
<view class="footer">
|
||
<button :class="{ 'primary-button': isFormValid, 'disabled-button': !isFormValid }" :disabled="!isFormValid"
|
||
@click.stop='handleConfirm'>
|
||
完成
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed } from 'vue'
|
||
import { useUserStore } from '@/store'
|
||
|
||
const userStore = useUserStore()
|
||
const popup = ref<any>(null)
|
||
|
||
// 密码显示状态 - 默认都是不可见的
|
||
const showOldPassword = ref(false)
|
||
const showNewPassword = ref(false)
|
||
const showConfirmPassword = ref(false)
|
||
|
||
// 重置密码可见性
|
||
const resetPasswordVisibility = () => {
|
||
showOldPassword.value = false
|
||
showNewPassword.value = false
|
||
showConfirmPassword.value = false
|
||
}
|
||
|
||
// 表单数据
|
||
const oldPassword = ref('')
|
||
const newPassword = ref('')
|
||
const confirmPassword = ref('')
|
||
|
||
// 是否有旧密码(是否已开启支付密码)
|
||
const hasOldPassword = ref(false)
|
||
|
||
// 是否关闭支付密码
|
||
const isClosePassword = ref(false)
|
||
|
||
// 获取弹框标题
|
||
const getDialogTitle = computed(() => {
|
||
if (!hasOldPassword.value) return '设置支付密码'
|
||
if (isClosePassword.value) return '关闭支付密码'
|
||
return '修改支付密码'
|
||
})
|
||
|
||
// 表单验证逻辑更新
|
||
const isFormValid = computed(() => {
|
||
if (isClosePassword.value) {
|
||
// 关闭支付密码时,只要有开关就可以点击完成
|
||
return true
|
||
} else if (!hasOldPassword.value) {
|
||
// 首次设置密码
|
||
if (!newPassword.value || !confirmPassword.value) return false
|
||
if (newPassword.value.length !== 6 || confirmPassword.value.length !== 6) return false
|
||
return newPassword.value === confirmPassword.value
|
||
} else {
|
||
// 修改密码
|
||
if (!oldPassword.value || !newPassword.value || !confirmPassword.value) return false
|
||
if (oldPassword.value.length !== 6 || newPassword.value.length !== 6 || confirmPassword.value.length !== 6) return false
|
||
return newPassword.value === confirmPassword.value
|
||
}
|
||
})
|
||
|
||
// 处理输入,限制只能输入数字且最多6位
|
||
const handleInput = (value: string, field: 'oldPassword' | 'newPassword' | 'confirmPassword') => {
|
||
// 只保留数字且最多6位
|
||
const numericValue = value?.replace(/[^\d]/g, '').slice(0, 6)
|
||
|
||
// 更新对应字段的值
|
||
switch (field) {
|
||
case 'oldPassword':
|
||
oldPassword.value = numericValue
|
||
break
|
||
case 'newPassword':
|
||
newPassword.value = numericValue
|
||
break
|
||
case 'confirmPassword':
|
||
confirmPassword.value = numericValue
|
||
break
|
||
}
|
||
}
|
||
|
||
// 生成随机6位数字
|
||
const generateRandomPassword = () => {
|
||
return Math.floor(Math.random() * 1000000).toString().padStart(6, '0')
|
||
}
|
||
|
||
// 重置表单更新
|
||
const resetForm = () => {
|
||
oldPassword.value = ''
|
||
newPassword.value = ''
|
||
confirmPassword.value = ''
|
||
resetPasswordVisibility()
|
||
isClosePassword.value = false
|
||
}
|
||
|
||
// 显示弹框
|
||
const show = async () => {
|
||
hasOldPassword.value = userStore.userInfo.paywithpwd === 1
|
||
isClosePassword.value = false
|
||
resetPasswordVisibility()
|
||
popup.value?.open('center')
|
||
}
|
||
|
||
// 隐藏弹框
|
||
const hide = () => {
|
||
popup.value?.close()
|
||
resetForm()
|
||
}
|
||
|
||
// 确认按钮处理更新
|
||
const handleConfirm = async () => {
|
||
try {
|
||
await userStore.setPayPassword({
|
||
paywithpwd: isClosePassword.value ? 0 : 1,
|
||
oldpwd: hasOldPassword.value ? oldPassword.value : '',
|
||
newpwd: isClosePassword.value ? '' : newPassword.value,
|
||
})
|
||
// 更新本地状态
|
||
userStore.userInfo.paywithpwd = isClosePassword.value ? 0 : 1
|
||
uni.showToast({
|
||
title: isClosePassword.value ? '已关闭支付密码' : '设置成功',
|
||
icon: 'success',
|
||
})
|
||
hide()
|
||
resetForm()
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: '操作失败',
|
||
icon: 'error',
|
||
})
|
||
}
|
||
}
|
||
|
||
// 处理开关切换
|
||
const handleSwitchChange = (value: boolean) => {
|
||
isClosePassword.value = value
|
||
// 切换时重置密码输入
|
||
if (value) {
|
||
newPassword.value = ''
|
||
confirmPassword.value = ''
|
||
oldPassword.value = generateRandomPassword() // 生成随机6位数字
|
||
resetPasswordVisibility()
|
||
} else {
|
||
oldPassword.value = ''
|
||
}
|
||
}
|
||
|
||
// 暴露方法给父组件使用
|
||
defineExpose({
|
||
show,
|
||
hide
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.pay-password-dialog {
|
||
width: 600rpx;
|
||
padding: 40rpx;
|
||
background-color: #fff;
|
||
border-radius: 24rpx;
|
||
position: relative;
|
||
|
||
.dialog-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 40rpx;
|
||
|
||
.title {
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
}
|
||
|
||
.form-container {
|
||
.switch-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 20rpx 0;
|
||
margin-bottom: 20rpx;
|
||
|
||
text {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
}
|
||
|
||
.form-item {
|
||
margin-bottom: 30rpx;
|
||
|
||
.label {
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
margin-bottom: 16rpx;
|
||
display: block;
|
||
}
|
||
|
||
.input-wrapper {
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: #f5f5f5;
|
||
border-radius: 12rpx;
|
||
padding: 20rpx;
|
||
height: 50rpx;
|
||
|
||
:deep(.u-border) {
|
||
border-style: hidden;
|
||
}
|
||
|
||
:deep(.u-input) {
|
||
flex: 1;
|
||
height: 100%;
|
||
background-color: transparent;
|
||
border: none;
|
||
font-size: 10rpx;
|
||
}
|
||
|
||
:deep(.u-input__input) {
|
||
height: 100%;
|
||
line-height: 60rpx;
|
||
font-size: 10rpx;
|
||
border: none;
|
||
padding: 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.footer {
|
||
padding: 0 30rpx;
|
||
}
|
||
}
|
||
</style> |