Files
medical-mall/pages/user/change-password.uvue

354 lines
6.3 KiB
Plaintext
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 class="change-password-page">
<view class="header">
<view class="back-btn" @click="goBack">
<text class="back-icon"></text>
</view>
<text class="header-title">修改密码</text>
</view>
<view class="content">
<form @submit="onSubmit">
<!-- 当前密码 -->
<view class="form-item">
<text class="label">当前密码</text>
<input
class="input"
type="password"
placeholder="请输入当前密码"
v-model="form.currentPassword"
:disabled="loading"
required
/>
</view>
<!-- 新密码 -->
<view class="form-item">
<text class="label">新密码</text>
<input
class="input"
type="password"
placeholder="请输入新密码6-20位字符"
v-model="form.newPassword"
:disabled="loading"
required
/>
<text class="hint">6-20位字符建议包含字母、数字和特殊符号</text>
</view>
<!-- 确认新密码 -->
<view class="form-item">
<text class="label">确认新密码</text>
<input
class="input"
type="password"
placeholder="请再次输入新密码"
v-model="form.confirmPassword"
:disabled="loading"
required
/>
</view>
<!-- 提交按钮 -->
<button
class="submit-btn"
form-type="submit"
:disabled="loading || !isFormValid"
:loading="loading"
>
{{ loading ? '处理中...' : '确认修改' }}
</button>
</form>
<!-- 忘记密码提示 -->
<view class="forgot-password">
<text class="forgot-text" @click="goToForgotPassword">忘记密码?</text>
</view>
</view>
<!-- 成功提示 -->
<view v-if="showSuccess" class="success-modal" @click="hideSuccess">
<view class="success-content" @click.stop>
<text class="success-icon">✓</text>
<text class="success-title">修改成功</text>
<text class="success-text">密码已成功修改,请使用新密码登录</text>
<button class="success-btn" @click="hideSuccess">确定</button>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, computed } from 'vue'
import supa from '@/components/supadb/aksupainstance.uts'
// 表单数据
const form = ref({
currentPassword: '',
newPassword: '',
confirmPassword: ''
})
const loading = ref<boolean>(false)
const showSuccess = ref<boolean>(false)
// 表单验证
const isFormValid = computed((): boolean => {
const { currentPassword, newPassword, confirmPassword } = form.value
return currentPassword.length >= 6 &&
newPassword.length >= 6 &&
newPassword.length <= 20 &&
newPassword === confirmPassword
})
// 提交表单
const onSubmit = async () => {
if (!isFormValid.value) {
uni.showToast({
title: '请填写完整且正确的密码信息',
icon: 'none'
})
return
}
loading.value = true
try {
// 调用 Supabase 更新密码
const { error } = await supa.auth.updateUser({
password: form.value.newPassword
})
if (error !== null) {
throw error
}
// 成功
showSuccess.value = true
// 清除表单
form.value = {
currentPassword: '',
newPassword: '',
confirmPassword: ''
}
} catch (error: any) {
console.error('修改密码失败:', error)
let errorMessage = '修改密码失败'
if (error.message?.includes('invalid_credentials')) {
errorMessage = '当前密码错误'
} else if (error.message?.includes('password')) {
errorMessage = '新密码不符合要求'
}
uni.showToast({
title: errorMessage,
icon: 'none'
})
} finally {
loading.value = false
}
}
// 导航函数
const goBack = () => {
uni.navigateBack()
}
const goToForgotPassword = () => {
uni.navigateTo({
url: '/pages/user/forgot-password'
})
}
const hideSuccess = () => {
showSuccess.value = false
goBack()
}
</script>
<style>
.change-password-page {
min-height: 100vh;
background-color: #f5f5f5;
}
.header {
background-color: #ffffff;
padding: 15px;
display: flex;
align-items: center;
border-bottom: 1px solid #e5e5e5;
}
.back-btn {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
.back-icon {
font-size: 24px;
color: #333;
}
.header-title {
font-size: 18px;
font-weight: bold;
color: #333;
flex: 1;
}
.content {
padding: 20px;
}
.form-item {
margin-bottom: 20px;
background-color: #ffffff;
border-radius: 10px;
padding: 15px;
}
.label {
display: block;
font-size: 16px;
color: #333;
margin-bottom: 10px;
font-weight: bold;
}
.input {
width: 100%;
height: 44px;
border: 1px solid #ddd;
border-radius: 8px;
padding: 0 15px;
font-size: 16px;
box-sizing: border-box;
}
.input:focus {
border-color: #007aff;
outline: none;
}
.input:disabled {
background-color: #f9f9f9;
color: #999;
}
.hint {
display: block;
font-size: 12px;
color: #999;
margin-top: 5px;
}
.submit-btn {
width: 100%;
height: 50px;
background-color: #007aff;
color: #ffffff;
border-radius: 25px;
font-size: 16px;
font-weight: bold;
border: none;
margin-top: 30px;
}
.submit-btn:disabled {
background-color: #cccccc;
}
.forgot-password {
text-align: center;
margin-top: 20px;
}
.forgot-text {
color: #007aff;
font-size: 14px;
text-decoration: underline;
}
/* 成功提示模态框 */
.success-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.success-content {
width: 280px;
background-color: #ffffff;
border-radius: 15px;
padding: 30px 20px;
text-align: center;
}
.success-icon {
display: block;
width: 60px;
height: 60px;
line-height: 60px;
background-color: #4cd964;
color: #ffffff;
font-size: 30px;
border-radius: 50%;
margin: 0 auto 20px;
}
.success-title {
display: block;
font-size: 18px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.success-text {
display: block;
font-size: 14px;
color: #666;
margin-bottom: 20px;
line-height: 1.4;
}
.success-btn {
width: 100%;
height: 44px;
background-color: #007aff;
color: #ffffff;
border-radius: 22px;
font-size: 16px;
border: none;
}
/* 响应式优化 */
@media screen and (min-width: 768px) {
.change-password-page {
max-width: 500px;
margin: 0 auto;
border-left: 1px solid #e5e5e5;
border-right: 1px solid #e5e5e5;
}
.content {
padding: 40px;
}
}
</style>