mirror of
https://github.com/Cccc-owo/CheckInApp.git
synced 2026-06-17 14:06:28 +00:00
feat: migrate from Element Plus to Ant Design Vue and update Vite configuration for better dependency management
- Updated Vite configuration to manually chunk Ant Design Vue for improved dependency management. - Added a comprehensive migration testing checklist for transitioning from Element Plus 2.13.0 to Ant Design Vue 4.x, covering various components and functionalities.
This commit is contained in:
@@ -16,55 +16,148 @@
|
||||
<p>您已成功注册,账户信息如下:</p>
|
||||
</div>
|
||||
|
||||
<div class="info-table">
|
||||
<div class="info-row">
|
||||
<div class="info-label">用户名</div>
|
||||
<div class="info-value">{{ user?.alias || '加载中...' }}</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">注册时间</div>
|
||||
<div class="info-value">{{ formatDate(user?.created_at) }}</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">审批状态</div>
|
||||
<div class="info-value">
|
||||
<span class="status-tag warning">待审批</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-descriptions :column="1" bordered class="mb-6">
|
||||
<a-descriptions-item label="用户名">
|
||||
{{ user?.alias || '加载中...' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="邮箱">
|
||||
<template v-if="user?.email">
|
||||
{{ user.email }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-tag color="warning">未设置</a-tag>
|
||||
</template>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="密码">
|
||||
<template v-if="user?.has_password">
|
||||
<a-tag color="success">已设置</a-tag>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-tag color="warning">未设置</a-tag>
|
||||
</template>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="注册时间">
|
||||
{{ formatDate(user?.created_at) }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="审批状态">
|
||||
<a-tag color="warning">待审批</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
|
||||
<div class="alert-box">
|
||||
<div class="alert-title">⚠️ 审批说明</div>
|
||||
<ul class="tips-list">
|
||||
<li>管理员将在 <strong>24 小时内</strong> 审核您的注册申请</li>
|
||||
<li>审核通过后,您将可以使用所有功能</li>
|
||||
<li>如超过 24 小时未审批,账户将被自动删除</li>
|
||||
<li>您可以随时刷新此页面查看最新状态</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a-alert
|
||||
message="⚠️ 审批说明"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb-6"
|
||||
>
|
||||
<template #description>
|
||||
<ul class="tips-list">
|
||||
<li>管理员将在 <strong>24 小时内</strong> 审核您的注册申请</li>
|
||||
<li>审核通过后,您将可以使用所有功能</li>
|
||||
<li>如超过 24 小时未审批,账户将被自动删除</li>
|
||||
<li><strong>建议:</strong>审批期间可以设置邮箱和密码,方便后续使用</li>
|
||||
<li>您可以随时刷新此页面查看最新状态</li>
|
||||
</ul>
|
||||
</template>
|
||||
</a-alert>
|
||||
|
||||
<div class="actions">
|
||||
<button class="btn btn-primary" @click="checkStatus">
|
||||
<a-button type="primary" size="large" @click="checkStatus">
|
||||
<template #icon><ReloadOutlined /></template>
|
||||
刷新状态
|
||||
</button>
|
||||
<button class="btn btn-default" @click="logout">
|
||||
</a-button>
|
||||
<a-button size="large" @click="showProfileModal = true">
|
||||
<template #icon><SettingOutlined /></template>
|
||||
完善信息
|
||||
</a-button>
|
||||
<a-button size="large" @click="logout">
|
||||
<template #icon><LogoutOutlined /></template>
|
||||
退出登录
|
||||
</button>
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 完善信息弹窗 -->
|
||||
<a-modal
|
||||
v-model:open="showProfileModal"
|
||||
title="完善个人信息"
|
||||
:confirm-loading="profileLoading"
|
||||
@ok="handleUpdateProfile"
|
||||
@cancel="resetProfileForm"
|
||||
width="500px"
|
||||
>
|
||||
<a-form :model="profileForm" layout="vertical">
|
||||
<a-form-item label="邮箱地址(可选)" name="email">
|
||||
<a-input
|
||||
v-model:value="profileForm.email"
|
||||
placeholder="用于接收审批通知"
|
||||
type="email"
|
||||
/>
|
||||
<div class="form-hint">建议设置邮箱,方便接收审批结果通知</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="新密码(可选)"
|
||||
name="new_password"
|
||||
:help="user?.has_password ? '留空表示不修改密码' : '设置密码后可以使用密码登录'"
|
||||
>
|
||||
<a-input-password
|
||||
v-model:value="profileForm.new_password"
|
||||
placeholder="至少6位字符"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-if="profileForm.new_password"
|
||||
label="确认密码"
|
||||
name="confirm_password"
|
||||
>
|
||||
<a-input-password
|
||||
v-model:value="profileForm.confirm_password"
|
||||
placeholder="再次输入新密码"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-if="user?.has_password && profileForm.new_password"
|
||||
label="当前密码"
|
||||
name="current_password"
|
||||
>
|
||||
<a-input-password
|
||||
v-model:value="profileForm.current_password"
|
||||
placeholder="修改密码时需要提供当前密码"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { ReloadOutlined, LogoutOutlined, SettingOutlined } from '@ant-design/icons-vue'
|
||||
import { userAPI } from '@/api'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const router = useRouter()
|
||||
const authStore = useAuthStore()
|
||||
const user = ref(null)
|
||||
const showProfileModal = ref(false)
|
||||
const profileLoading = ref(false)
|
||||
|
||||
const profileForm = ref({
|
||||
email: '',
|
||||
new_password: '',
|
||||
confirm_password: '',
|
||||
current_password: '',
|
||||
})
|
||||
|
||||
const checkStatus = async () => {
|
||||
try {
|
||||
@@ -72,14 +165,99 @@ const checkStatus = async () => {
|
||||
user.value = response
|
||||
|
||||
if (response.is_approved) {
|
||||
alert('恭喜!您的账户已通过审批')
|
||||
message.success('恭喜!您的账户已通过审批')
|
||||
router.push('/dashboard')
|
||||
} else {
|
||||
alert('仍在等待审批中')
|
||||
message.info('仍在等待审批中')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取状态失败:', error)
|
||||
alert('获取状态失败:' + (error.message || '未知错误'))
|
||||
message.error('获取状态失败:' + (error.message || '未知错误'))
|
||||
}
|
||||
}
|
||||
|
||||
const loadUserInfo = async () => {
|
||||
try {
|
||||
const response = await userAPI.getCurrentUser()
|
||||
user.value = response
|
||||
// 初始化表单
|
||||
profileForm.value.email = response.email || ''
|
||||
} catch (error) {
|
||||
console.error('加载用户信息失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleUpdateProfile = async () => {
|
||||
// 验证
|
||||
if (profileForm.value.new_password && profileForm.value.new_password.length < 6) {
|
||||
message.error('密码至少需要 6 位字符')
|
||||
return
|
||||
}
|
||||
|
||||
if (profileForm.value.new_password !== profileForm.value.confirm_password) {
|
||||
message.error('两次输入的密码不一致')
|
||||
return
|
||||
}
|
||||
|
||||
if (user.value?.has_password && profileForm.value.new_password && !profileForm.value.current_password) {
|
||||
message.error('修改密码时需要提供当前密码')
|
||||
return
|
||||
}
|
||||
|
||||
profileLoading.value = true
|
||||
|
||||
try {
|
||||
const updateData = {}
|
||||
|
||||
// 只提交有变化的字段
|
||||
if (profileForm.value.email !== (user.value?.email || '')) {
|
||||
updateData.email = profileForm.value.email || null
|
||||
}
|
||||
|
||||
if (profileForm.value.new_password) {
|
||||
updateData.new_password = profileForm.value.new_password
|
||||
if (user.value?.has_password) {
|
||||
updateData.current_password = profileForm.value.current_password
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有要更新的字段
|
||||
if (Object.keys(updateData).length === 0) {
|
||||
message.info('没有需要更新的信息')
|
||||
showProfileModal.value = false
|
||||
return
|
||||
}
|
||||
|
||||
await userAPI.updateProfile(updateData)
|
||||
message.success('个人信息更新成功')
|
||||
showProfileModal.value = false
|
||||
resetProfileForm()
|
||||
|
||||
// 重新加载用户信息
|
||||
await loadUserInfo()
|
||||
|
||||
// 如果设置了密码,更新本地存储的用户信息
|
||||
if (updateData.new_password) {
|
||||
const currentUser = authStore.user
|
||||
if (currentUser) {
|
||||
currentUser.has_password = true
|
||||
localStorage.setItem('user', JSON.stringify(currentUser))
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('更新个人信息失败:', error)
|
||||
message.error(error.message || '更新失败,请重试')
|
||||
} finally {
|
||||
profileLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const resetProfileForm = () => {
|
||||
profileForm.value = {
|
||||
email: user.value?.email || '',
|
||||
new_password: '',
|
||||
confirm_password: '',
|
||||
current_password: '',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +273,7 @@ const formatDate = (dateStr) => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadUserInfo()
|
||||
checkStatus()
|
||||
})
|
||||
</script>
|
||||
@@ -160,66 +339,10 @@ onMounted(() => {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.info-table {
|
||||
background: #f9f9f9;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
.mb-6 {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.info-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
flex: 0 0 120px;
|
||||
padding: 15px 20px;
|
||||
background: #f5f5f5;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
flex: 1;
|
||||
padding: 15px 20px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-tag.warning {
|
||||
background: #fff3cd;
|
||||
color: #856404;
|
||||
border: 1px solid #ffc107;
|
||||
}
|
||||
|
||||
.alert-box {
|
||||
background: #e7f3ff;
|
||||
border-left: 4px solid #409eff;
|
||||
padding: 20px;
|
||||
margin-bottom: 30px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.alert-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.tips-list {
|
||||
text-align: left;
|
||||
padding-left: 20px;
|
||||
@@ -236,34 +359,12 @@ onMounted(() => {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 12px 30px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #409eff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #66b1ff;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
background: #f5f5f5;
|
||||
color: #606266;
|
||||
border: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
.btn-default:hover {
|
||||
background: #e8e8e8;
|
||||
.form-hint {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user