Files
jurong_circle_frontdesk/src/views/EditPasswordPage.vue
2025-07-31 13:55:29 +08:00

249 lines
5.5 KiB
Vue

<template>
<div class="password-change-page">
<!-- 导航栏 -->
<nav class="navbar">
<div class="nav-left">
<router-link to="/myprofile" class="back-btn">
<el-icon><ArrowLeft /></el-icon>
返回
</router-link>
</div>
<div class="nav-center">
<h1 class="nav-title">修改密码</h1>
</div>
<div class="nav-right"></div>
</nav>
<!-- 密码修改表单 -->
<div class="password-form-container">
<div class="password-form">
<el-form
ref="passwordFormRef"
:model="passwordForm"
:rules="passwordRules"
label-width="100px"
>
<el-form-item label="当前密码" prop="currentPassword">
<el-input
v-model="passwordForm.currentPassword"
type="password"
placeholder="请输入当前密码"
show-password
/>
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input
v-model="passwordForm.newPassword"
type="password"
placeholder="请输入新密码"
show-password
/>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input
v-model="passwordForm.confirmPassword"
type="password"
placeholder="请确认新密码"
show-password
/>
</el-form-item>
</el-form>
<div class="form-actions">
<el-button @click="resetPasswordForm">重置</el-button>
<el-button type="primary" @click="changePassword" :loading="changingPassword">
修改密码
</el-button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { ElMessage } from 'element-plus'
import { ArrowLeft } from '@element-plus/icons-vue'
import api from '@/utils/api'
const router = useRouter()
const userStore = useUserStore()
// 响应式数据
const passwordForm = reactive({
currentPassword: '',
newPassword: '',
confirmPassword: ''
})
const changingPassword = ref(false)
const passwordFormRef = ref()
// 表单验证规则
const passwordRules = {
currentPassword: [
{ required: true, message: '请输入当前密码', trigger: 'blur' }
],
newPassword: [
{ required: true, message: '请输入新密码', trigger: 'blur' },
{ min: 6, max: 20, message: '密码长度在 6 到 20 个字符', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: '请确认新密码', trigger: 'blur' },
{
validator: (rule, value, callback) => {
if (value !== passwordForm.newPassword) {
callback(new Error('两次输入密码不一致'))
} else {
callback()
}
},
trigger: 'blur'
}
]
}
/**
* 修改密码
*/
const changePassword = async () => {
try {
await passwordFormRef.value.validate()
changingPassword.value = true
const response = await api.put('/auth/change-password', {
currentPassword: passwordForm.currentPassword,
newPassword: passwordForm.newPassword
})
if (response.data.success) {
ElMessage.success(response.data.message || '密码修改成功')
resetPasswordForm()
// 修改成功后返回个人资料页
router.push('/profile')
} else {
ElMessage.error(response.data.message || '密码修改失败')
}
} catch (error) {
console.error('密码修改失败:', error)
if (error.response) {
ElMessage.error(error.response.data.message || '密码修改失败')
} else {
ElMessage.error('密码修改失败')
}
} finally {
changingPassword.value = false
}
}
/**
* 重置密码表单
*/
const resetPasswordForm = () => {
passwordForm.currentPassword = ''
passwordForm.newPassword = ''
passwordForm.confirmPassword = ''
passwordFormRef.value?.clearValidate()
}
</script>
<style lang="scss" scoped>
.password-change-page {
min-height: 100vh;
background-color: #f5f5f5;
}
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
height: 56px;
background: white;
border-bottom: 1px solid #eee;
position: sticky;
top: 0;
z-index: 100;
}
.nav-left,
.nav-right {
flex: 1;
}
.back-btn {
color: #409eff;
font-size: 14px;
display: flex;
align-items: center;
gap: 5px;
}
.nav-title {
margin: 0;
font-size: 18px;
font-weight: 500;
color: #333;
}
.password-form-container {
padding: 20px 16px;
}
.password-form {
background: white;
border-radius: 12px;
padding: 25px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
border: 1px solid rgba(0, 0, 0, 0.05);
max-width: 500px;
margin: 0 auto;
}
.form-actions {
text-align: center;
margin-top: 30px;
display: flex;
gap: 15px;
justify-content: center;
}
.form-actions .el-button {
min-width: 100px;
border-radius: 8px;
font-weight: 500;
}
/* 响应式设计 */
@media (max-width: 768px) {
.password-form-container {
padding: 10px;
}
.password-form {
padding: 20px;
border-radius: 8px;
}
.form-actions {
flex-direction: column;
align-items: center;
}
.form-actions .el-button {
width: 100%;
max-width: 200px;
}
.el-form {
:deep(.el-form-item__label) {
width: 80px !important;
font-size: 14px;
}
}
}
</style>