DCFronted/src/components/ChangePasswordDialog.vue
2025-07-13 21:40:32 +08:00

207 lines
3.8 KiB
Vue

<template>
<div v-if="visible" class="password-dialog-overlay" @click.self="handleClose">
<div class="password-dialog">
<div class="password-dialog-content">
<div class="dialog-title">修改密码</div>
<div class="confirm-content">
<p class="confirm-message">是否要修改密码?</p>
</div>
</div>
<div class="password-dialog-footer">
<button class="cancel-button" @click="handleClose" :disabled="loading">取消</button>
<button
class="confirm-button"
@click="handleSubmit"
:disabled="loading"
>
{{ loading ? '修改中...' : '确定' }}
</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, watch, defineProps, defineEmits } from 'vue'
import { requestResetPassword, resetPassword } from '@/api/login.js'
const props = defineProps({
visible: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['close', 'success', 'error'])
const loading = ref(false)
// 监听弹窗显示状态
watch(() => props.visible, (visible) => {
if (visible) {
loading.value = false
}
})
const handleClose = () => {
if (!loading.value) {
emit('close')
}
}
const handleSubmit = async () => {
if (loading.value) {
return
}
loading.value = true
try {
// 请求修改密码
await requestResetPassword()
emit('success', '密码修改请求已发送!')
emit('close')
} catch (error) {
console.error('请求修改密码失败:', error)
const errorMessage = error.response?.data?.detail || error.response?.data?.message || error.message || '请求修改密码失败,请重试'
emit('error', errorMessage)
} finally {
loading.value = false
}
}
</script>
<style scoped>
.password-dialog-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.password-dialog {
background: white;
border-radius: 8px;
width: 90%;
max-width: 400px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
animation: dialog-fade-in 0.3s ease;
}
.password-dialog-content {
padding: 20px;
text-align: center;
}
.dialog-title {
font-size: 18px;
font-weight: 600;
color: #333;
margin-bottom: 20px;
}
.confirm-content {
margin-bottom: 0;
}
.confirm-message {
font-size: 16px;
color: #666;
margin: 0;
line-height: 1.5;
}
.password-dialog-footer {
padding: 10px 20px 20px;
text-align: center;
display: flex;
justify-content: center;
gap: 12px;
}
.cancel-button, .confirm-button {
padding: 8px 24px;
border: none;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: background-color 0.3s;
}
.cancel-button {
background-color: #909399;
color: white;
}
.cancel-button:hover:not(:disabled) {
background-color: #a6a9ad;
}
.confirm-button {
background-color: #67c23a;
color: white;
}
.confirm-button:hover:not(:disabled) {
background-color: #85ce61;
}
.confirm-button:disabled {
background-color: #c0c4cc;
cursor: not-allowed;
}
.cancel-button:disabled {
background-color: #c0c4cc;
cursor: not-allowed;
}
@keyframes dialog-fade-in {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 移动端适配 */
@media screen and (max-width: 480px) {
.password-dialog {
width: 85%;
}
.dialog-title {
font-size: 16px;
}
.password-dialog-content {
padding: 16px;
}
.confirm-message {
font-size: 14px;
}
.password-dialog-footer {
flex-direction: column;
gap: 8px;
}
.cancel-button, .confirm-button {
width: 100%;
padding: 10px;
font-size: 13px;
}
}
</style>