Browse Source

all

yangrongze
hanyuqing 3 months ago
parent
commit
52cfbffd0f
  1. 138
      vue/src/system/Profile.vue

138
vue/src/system/Profile.vue

@ -4,7 +4,7 @@
<Menu <Menu
@menu-click="handleSidebarClick" @menu-click="handleSidebarClick"
/> />
<!-- 主内容区域 --> <!-- 主内容区域 -->
<div class="main-content"> <div class="main-content">
<div class="profile-container"> <div class="profile-container">
@ -13,15 +13,15 @@
<h1 class="page-title">个人主页</h1> <h1 class="page-title">个人主页</h1>
<p class="page-subtitle">管理您的个人信息和账户设置</p> <p class="page-subtitle">管理您的个人信息和账户设置</p>
</div> </div>
<!-- 个人信息卡片 --> <!-- 个人信息卡片 -->
<div class="profile-card"> <div class="profile-card">
<!-- 头像区域 --> <!-- 头像区域 -->
<div class="avatar-section"> <div class="avatar-section">
<div class="avatar-container"> <div class="avatar-container">
<img <img
:src="userProfile.avatar" :src="userProfile.avatar"
alt="用户头像" alt="用户头像"
class="avatar-image" class="avatar-image"
@error="handleAvatarError" @error="handleAvatarError"
> >
@ -29,11 +29,11 @@
<span class="camera-icon">📷</span> <span class="camera-icon">📷</span>
<span class="overlay-text">更换头像</span> <span class="overlay-text">更换头像</span>
</div> </div>
<input <input
type="file" type="file"
ref="fileInput" ref="fileInput"
@change="handleAvatarChange" @change="handleAvatarChange"
accept="image/*" accept="image/*"
class="hidden-input" class="hidden-input"
> >
</div> </div>
@ -44,40 +44,40 @@
</div> </div>
</div> </div>
<!-- 用户信息表单 --> <!-- 用户信息表单 -->
<div class="info-section"> <div class="info-section">
<h2 class="section-title">修改密码</h2> <h2 class="section-title">修改密码</h2>
<form class="password-form" @submit.prevent="changePassword"> <form class="password-form" @submit.prevent="changePassword">
<div class="form-group"> <div class="form-group">
<label for="currentPassword" class="form-label">当前密码</label> <label for="currentPassword" class="form-label">当前密码</label>
<input <input
type="password" type="password"
id="currentPassword" id="currentPassword"
v-model="passwordForm.currentPassword" v-model="passwordForm.currentPassword"
class="form-input" class="form-input"
placeholder="请输入当前密码" placeholder="请输入当前密码"
required required
> >
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="newPassword" class="form-label">新密码</label> <label for="newPassword" class="form-label">新密码</label>
<input <input
type="password" type="password"
id="newPassword" id="newPassword"
v-model="passwordForm.newPassword" v-model="passwordForm.newPassword"
class="form-input" class="form-input"
placeholder="请输入新密码" placeholder="请输入新密码"
required required
> >
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="confirmPassword" class="form-label">确认新密码</label> <label for="confirmPassword" class="form-label">确认新密码</label>
<input <input
type="password" type="password"
id="confirmPassword" id="confirmPassword"
v-model="passwordForm.confirmPassword" v-model="passwordForm.confirmPassword"
class="form-input" class="form-input"
placeholder="请再次输入新密码" placeholder="请再次输入新密码"
@ -85,7 +85,7 @@
> >
<p v-if="passwordMismatch" class="error-text">两次输入的密码不一致</p> <p v-if="passwordMismatch" class="error-text">两次输入的密码不一致</p>
</div> </div>
<div class="form-actions"> <div class="form-actions">
<button type="submit" class="save-button" :disabled="passwordSaving || passwordMismatch"> <button type="submit" class="save-button" :disabled="passwordSaving || passwordMismatch">
<span v-if="!passwordSaving">修改密码</span> <span v-if="!passwordSaving">修改密码</span>
@ -141,8 +141,8 @@ const errorMessage = ref('');
// //
const passwordMismatch = computed(() => { const passwordMismatch = computed(() => {
return passwordForm.value.newPassword && return passwordForm.value.newPassword &&
passwordForm.value.confirmPassword && passwordForm.value.confirmPassword &&
passwordForm.value.newPassword !== passwordForm.value.confirmPassword; passwordForm.value.newPassword !== passwordForm.value.confirmPassword;
}); });
@ -168,45 +168,45 @@ const handleAvatarChange = async (event) => {
errorMessage.value = '请选择图片文件'; errorMessage.value = '请选择图片文件';
return; return;
} }
// (2MB) // (2MB)
if (file.size > 2 * 1024 * 1024) { if (file.size > 2 * 1024 * 1024) {
errorMessage.value = '图片大小不能超过2MB'; errorMessage.value = '图片大小不能超过2MB';
return; return;
} }
// //
avatarUploading.value = true; avatarUploading.value = true;
avatarUploadSuccess.value = false; avatarUploadSuccess.value = false;
errorMessage.value = ''; errorMessage.value = '';
try { try {
// localStoragetoken // localStoragetoken
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
if (!token) { if (!token) {
errorMessage.value = '用户未登录,请先登录'; errorMessage.value = '用户未登录,请先登录';
avatarUploading.value = false; avatarUploading.value = false;
return; return;
} }
// FormData // FormData
const formData = new FormData(); const formData = new FormData();
formData.append('avatar', file); formData.append('avatar', file);
formData.append('token', token); formData.append('token', token);
console.log('准备上传头像文件:', file.name); console.log('准备上传头像文件:', file.name);
console.log('Token:', token); console.log('Token:', token);
// API // API
const response = await updateAvatar(formData,{ const response = await updateAvatar(formData,{
headers: { headers: {
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
} }
}); });
console.log('收到响应:', response); console.log('收到响应:', response);
if (response.success) { if (response.success) {
// 使 // 使
// URL // URL
@ -216,11 +216,11 @@ const handleAvatarChange = async (event) => {
avatarPath = avatarPath; avatarPath = avatarPath;
} }
userProfile.value.avatar = avatarPath; userProfile.value.avatar = avatarPath;
// //
avatarUploadSuccess.value = true; avatarUploadSuccess.value = true;
successMessage.value = '头像更新成功'; successMessage.value = '头像更新成功';
// 3 // 3
setTimeout(() => { setTimeout(() => {
avatarUploadSuccess.value = false; avatarUploadSuccess.value = false;
@ -236,7 +236,7 @@ const handleAvatarChange = async (event) => {
stack: error.stack, stack: error.stack,
name: error.name name: error.name
}); });
// //
if (error.response) { if (error.response) {
// //
@ -261,12 +261,12 @@ const updateProfile = () => {
profileSaving.value = true; profileSaving.value = true;
errorMessage.value = ''; errorMessage.value = '';
successMessage.value = ''; successMessage.value = '';
// API // API
setTimeout(() => { setTimeout(() => {
profileSaving.value = false; profileSaving.value = false;
successMessage.value = '个人信息更新成功'; successMessage.value = '个人信息更新成功';
// 3 // 3
setTimeout(() => { setTimeout(() => {
successMessage.value = ''; successMessage.value = '';
@ -279,38 +279,38 @@ const changePassword = async () => {
if (passwordMismatch.value) { if (passwordMismatch.value) {
return; return;
} }
passwordSaving.value = true; passwordSaving.value = true;
errorMessage.value = ''; errorMessage.value = '';
successMessage.value = ''; successMessage.value = '';
try { try {
// localStoragetoken // localStoragetoken
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
if (!token) { if (!token) {
errorMessage.value = '用户未登录,请先登录'; errorMessage.value = '用户未登录,请先登录';
passwordSaving.value = false; passwordSaving.value = false;
return; return;
} }
// API // API
const response = await updatePassword({ const response = await updatePassword({
token, token,
currentPassword: passwordForm.value.currentPassword, currentPassword: passwordForm.value.currentPassword,
newPassword: passwordForm.value.newPassword newPassword: passwordForm.value.newPassword
}); });
if (response.success) { if (response.success) {
successMessage.value = '密码修改成功'; successMessage.value = '密码修改成功';
// //
passwordForm.value = { passwordForm.value = {
currentPassword: '', currentPassword: '',
newPassword: '', newPassword: '',
confirmPassword: '' confirmPassword: ''
}; };
// 3 // 3
setTimeout(() => { setTimeout(() => {
successMessage.value = ''; successMessage.value = '';
@ -331,15 +331,15 @@ onMounted(async () => {
try { try {
// localStoragetoken // localStoragetoken
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
console.log('Profile组件挂载,获取到的token:', token); console.log('Profile组件挂载,获取到的token:', token);
if (token) { if (token) {
// API // API
const response = await getUserProfile(token); const response = await getUserProfile(token);
console.log('获取用户信息响应:', response); console.log('获取用户信息响应:', response);
if (response.success) { if (response.success) {
// //
// //
@ -347,9 +347,9 @@ onMounted(async () => {
if (avatarUrl.startsWith('/resource/')) { if (avatarUrl.startsWith('/resource/')) {
avatarUrl = avatarUrl; // 使 avatarUrl = avatarUrl; // 使
} }
console.log('设置头像URL:', avatarUrl); console.log('设置头像URL:', avatarUrl);
userProfile.value = { userProfile.value = {
username: response.user.username, username: response.user.username,
avatar: avatarUrl avatar: avatarUrl
@ -357,7 +357,7 @@ onMounted(async () => {
} else { } else {
console.error('获取用户信息失败:', response.message); console.error('获取用户信息失败:', response.message);
errorMessage.value = response.message || '获取用户信息失败'; errorMessage.value = response.message || '获取用户信息失败';
// tokentoken // tokentoken
if (response.message && response.message.includes('登录')) { if (response.message && response.message.includes('登录')) {
localStorage.removeItem('token'); localStorage.removeItem('token');
@ -376,40 +376,23 @@ onMounted(async () => {
</script> </script>
<style scoped> <style scoped>
.app-container {
.app-container{
display: flex; display: flex;
height: 100vh; height: 100vh;
overflow: hidden;
} }
.main-content { .main-content {
display: flex;
height: 100vh;
background-color: #F5F8FF;
flex: 1; flex: 1;
overflow: auto;;
padding: 1.5rem; padding: 1.5rem;
overflow-y: auto;
height: 100%;
background-color: #f5f7fa;
transition: margin-left 0.3s ease; transition: margin-left 0.3s ease;
} }
/* 确保左侧导航栏完全固定 */
.app-container > :first-child {
position: fixed;
height: 100vh;
z-index: 10;
}
/* 为右侧内容添加左边距,避免被固定导航栏遮挡 */
.main-content {
margin-left: 240px; /* 与Menu.vue中的sidebar-container宽度相同 */
}
/* 当菜单折叠时调整内容区域 */
.app-container:has(.sidebar-container.collapsed) .main-content {
margin-left: 60px;
}
.profile-container { .profile-container {
max-width: 700px; width: 97%;
margin: 0 auto; margin: 0 auto;
} }
@ -454,7 +437,6 @@ onMounted(async () => {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
padding: 1.5rem; padding: 1.5rem;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
max-width: 600px;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }

Loading…
Cancel
Save