fix: for thesis

This commit is contained in:
2026-04-17 00:23:18 +08:00
parent 122971200f
commit 49f54a2168
8 changed files with 1074 additions and 1058 deletions

View File

@@ -9,7 +9,8 @@
<div class="voice" v-if="onCall.panel">
<div>
<div class="profilebox">
<img :src="onCall.target.avatar" alt="头像">
<!-- 原逻辑:src="onCall.target.avatar"远端头像 -->
<img :src="defaultAvatar" alt="头像">
</div>
<div class="infobox">
<p>{{ onCall.target.name }}</p>
@@ -37,6 +38,7 @@ import { onCallStore } from '@/store/VoiceTarget';
import { Mic } from '@element-plus/icons-vue';
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { denyCall, hangupCall,sendOffer } from '@/store/Voice.ts';
import defaultAvatar from '@/assets/defaultavatar.jpg';
const onCall = onCallStore();
const userinfo = userInfoStore()

View File

@@ -1,7 +1,8 @@
<template>
<router-link to="/home/user" v-if="userinfo.user.u_avatar" class="user-profile-link">
<router-link to="/home/user" class="user-profile-link">
<div class="user-profile">
<img :src="userinfo.user.u_avatar" alt="User Avatar" />
<!-- 原逻辑:src="userinfo.user.u_avatar"远端头像 -->
<img :src="defaultAvatar" alt="User Avatar" />
<div :class="['status-dot', statusClass]"></div>
</div>
</router-link>
@@ -11,6 +12,7 @@
<script setup>
import { ref, computed } from 'vue';
import { userInfoStore } from '@/store/user.ts';
import defaultAvatar from '@/assets/defaultavatar.jpg';
const userinfo = userInfoStore();

View File

@@ -1,33 +1,33 @@
<template>
<el-row>
<el-col :span="6">
<h1>关于我们</h1>
<p>前端是我</p>
<p>后端是我</p>
<p>测试是我</p>
<p>运维是我</p>
<p>UI设计是我</p>
<p>项目管理是我</p>
<p>架构设计是我</p>
<p>数据库设计还是我</p>
<p>感谢使用与支持</p>
</el-col>
<el-col :span="9">
可以添加微信询问详情
<img class="QRcode" src="@/assets/微信二维码.png" alt="candlelight_official">
</el-col>
<!-- <el-col :span="9">
<img class="QRcode" src="@/assets/微信收款码.png" alt="" />
</el-col>
<el-col :span="9">
<img class="QRcode" src="@/assets/支付宝收款码.jpg" alt="" />
</el-col> -->
</el-row>
</template>
<style>
.QRcode {
width: 100%;
height: 100%;
}
<template>
<el-row>
<el-col :span="6">
<h1>关于我们</h1>
<p>前端是我</p>
<p>后端是我</p>
<p>测试是我</p>
<p>运维是我</p>
<p>UI设计是我</p>
<p>项目管理是我</p>
<p>架构设计是我</p>
<p>数据库设计还是我</p>
<p>感谢使用</p>
</el-col>
<!-- <el-col :span="9">
可以添加微信询问详情
<img class="QRcode" src="@/assets/微信二维码.png" alt="candlelight_official">
</el-col> -->
<!-- <el-col :span="9">
<img class="QRcode" src="@/assets/微信收款码.png" alt="" />
</el-col>
<el-col :span="9">
<img class="QRcode" src="@/assets/支付宝收款码.jpg" alt="" />
</el-col> -->
</el-row>
</template>
<style>
.QRcode {
width: 100%;
height: 100%;
}
</style>

View File

@@ -1,24 +1,24 @@
<template>
<div class="home-default">
<h1>欢迎使用Myplayer</h1>
<h2>当前版本v0.3.0测试版</h2>
<p>v0.1.0 websocket实时聊天实装</p>
<p>v0.1.1 面板更新websocket重连机制增加</p>
<p>v0.1.2 修复bug群聊功能性实现webRTC点对点语言聊天实装</p>
<p>v0.2.0 修复若干bug完善了部分ui和逻辑</p>
<p>v0.3.0 重构了后端以及前端逻辑</p>
<p>预期开发计划1播放器相关开发 2ui重绘 3群聊功能完善......</p>
<p>总之还有好多事慢慢写吧</p>
</div>
</template>
<script setup>
</script>
<style scoped>
.home-default {
text-align: center;
padding: 20px;
}
<template>
<div class="home-default">
<h1>欢迎使用Myplayer</h1>
<h2>当前版本v0.4.0测试版</h2>
<!-- <p>v0.1.0 websocket实时聊天实装</p>
<p>v0.1.1 面板更新websocket重连机制增加</p>
<p>v0.1.2 修复bug群聊功能性实现webRTC点对点语言聊天实装</p>
<p>v0.2.0 修复若干bug完善了部分ui和逻辑</p>
<p>v0.3.0 重构了后端以及前端逻辑</p>
<p>预期开发计划1播放器相关开发 2ui重绘 3群聊功能完善......</p> -->
<p>总之还有好多事慢慢写吧</p>
</div>
</template>
<script setup>
</script>
<style scoped>
.home-default {
text-align: center;
padding: 20px;
}
</style>

View File

@@ -9,7 +9,8 @@
@click="switchTemplate(item.id, item.u_name, item.u_avatar)"
:class="{ 'selected': selectedFriendId === item.id }">
<div class="user-profile">
<img :src="item.u_avatar" alt="User Avatar" />
<!-- 原逻辑:src="item.u_avatar"远端头像 -->
<img :src="defaultAvatar" alt="User Avatar" />
<div :class="['status-dot', statusClass]"></div>
</div>
<div style="display: inline-block;">{{ item.u_name }}#{{ item.u_id }}</div>
@@ -24,8 +25,8 @@
<div v-for="(item) in messagebox" class="message-item">
<div
:class="{ 'message-item-profile': true, 'left': item.from !== userinfo.user.id, 'right': item.from === userinfo.user.id }">
<img :src="item.from !== userinfo.user.id ? oppositeAvatar : userinfo.user.u_avatar"
alt="User Avatar" />
<!-- 原逻辑:src="item.from !== userinfo.user.id ? oppositeAvatar : userinfo.user.u_avatar"远端头像 -->
<img :src="defaultAvatar" alt="User Avatar" />
</div>
<div
:class="{ 'message-item-content': true, 'left': item.from !== userinfo.user.id, 'right': item.from === userinfo.user.id }">
@@ -48,7 +49,8 @@
<el-dialog v-model="dialogVisibleCallConfirm" title="确认通话对象" width="30%" :before-close="handleClose">
<el-row style="height: 80px;align-items: center;">
<div class="user-profile">
<img :src="oppositeAvatar" alt="User Avatar" />
<!-- 原逻辑:src="oppositeAvatar"远端头像 -->
<img :src="defaultAvatar" alt="User Avatar" />
</div>
<div>{{ oppositeName }}</div>
</el-row>
@@ -64,7 +66,8 @@
<el-table-column prop="u_avatar" label="" width="100">
<template #default="scope">
<!-- 使用 el-avatar 组件显示头像 -->
<el-avatar :src="friendSearchResult[scope.$index].u_avatar" size="large" />
<!-- 原逻辑:src="friendSearchResult[scope.$index].u_avatar"远端头像 -->
<el-avatar :src="defaultAvatar" size="large" />
</template>
</el-table-column>
<el-table-column prop="u_name" label="姓名" width="100"></el-table-column>
@@ -96,6 +99,7 @@ import { messageStore } from '@/store/message.ts';
import { Search } from '@element-plus/icons-vue'
import { onCallStore } from '@/store/VoiceTarget.ts';
import { getFriends, deleteFriend } from '@/api/friend';
import defaultAvatar from '@/assets/defaultavatar.jpg';
const userinfo = userInfoStore()

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
<template></template>
<template>设置</template>

View File

@@ -1,496 +1,498 @@
<template>
<el-row>
<el-col :span="12">
<div class="updateProfile">
<div class="profile">
<img :src="avatarPreview" alt="头像">
</div>
<el-col span="12">
<input type="file" id="avatar" @change="handleAvatarChange" accept="image/*" />
</el-col>
<el-col span="12">
<el-button class="re-profile" @click="uploadAvatar">修改头像</el-button>
</el-col>
<el-col span="12">
<span>推荐头像参数<br>
分辨率1051*1051 96dpi <br>
格式jpgpng <br>
大小1M
</span>
</el-col>
</div>
</el-col>
<el-col :span="12">
<el-row>
<span style="width: 80%;">用户名{{ userinfo.user.u_name }}</span>
<el-button @click="dialogVisibleChangeName = true">修改名字</el-button>
</el-row>
<el-row>
<span style="width: 80%;">账号{{ userinfo.account }}</span>
<!-- <el-button @click="dialogVisibleChangeAccount = true">修改账号</el-button> -->
</el-row>
<el-row>
<span style="width: 80%;">个性签名{{ userinfo.user.u_introduction }}</span>
<el-button @click="dialogVisibleChangeIntro = true">修改简介</el-button>
</el-row>
<el-row>
<span style="width: 80%;">密码 *********************</span>
<el-button @click="dialogVisibleChangePassword = true">修改密码</el-button>
</el-row>
</el-col>
</el-row>
<!-- 修改名字弹窗 -->
<el-dialog v-model="dialogVisibleChangeName" title="修改名字" width="500">
<el-input v-model="newname" autocomplete="off" />
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisibleChangeName = false">算了</el-button>
<el-button type="primary" @click="changeName">
</el-button>
</div>
</template>
</el-dialog>
<!-- 修改个签弹窗 -->
<el-dialog v-model="dialogVisibleChangeIntro" title="修改个签" width="500">
<el-input v-model="newintro" autocomplete="off" size="large" />
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisibleChangeIntro = false">算了</el-button>
<el-button type="primary" @click="changeIntro">
</el-button>
</div>
</template>
</el-dialog>
<!-- 修改邮箱弹窗 -->
<el-dialog v-model="dialogVisibleChangeAccount" title="修改邮箱" width="500">
<el-row style="margin-bottom: 10px;">
<el-col span="6">当前邮箱</el-col>
<el-col span="18">{{ userinfo.user.u_account }}</el-col>
</el-row>
<el-form ref="formRef" :model="formData" :rules="rules">
<el-form-item label="新邮箱" prop="newaccount">
<el-col span="24">
<el-input v-model="formData.newaccount" autocomplete="off" placeholder="请输入邮箱地址"
style="width: 300px;" />
</el-col>
</el-form-item>
<el-form-item label="验证码" prop="code">
<el-col span="18">
<el-input v-model="formData.code" autocomplete="off" placeholder="请输入验证码" style="width: 225px;" />
</el-col>
<el-col span="6">
<button class="codebutton" type="button" :disabled="isCountingDown" @click="sendVerificationCode">
{{ isCountingDown ? `${countdownTime} s` : 'Get Code' }}
</button>
</el-col>
</el-form-item>
<el-form-item>
<div class="dialog-footer">
<el-button @click="dialogVisibleChangeAccount = false">算了</el-button>
<el-button type="primary" @click="changeAccount">
</el-button>
</div>
</el-form-item>
</el-form>
</el-dialog>
<!-- 修改密码弹窗 -->
<el-dialog v-model="dialogVisibleChangePassword" title="修改密码" width="500">
<el-form ref="formRedPassword" :model="password" :rules="passwordRules">
<el-form-item label="原密码" prop="oldpassword">
<el-col span="24">
<el-input v-model="password.oldpassword" autocomplete="off" placeholder="请输入原密码"
show-password="true" style="width: 300px;" />
</el-col>
</el-form-item>
<el-form-item label="新密码" prop="password">
<el-col span="24">
<el-input v-model="password.password" autocomplete="off" placeholder="请输入新密码" show-password="true"
style="width: 300px;" />
</el-col>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-col span="24">
<el-input v-model="password.confirmPassword" autocomplete="off" placeholder="确认密码"
show-password="true" style="width: 300px;" />
</el-col>
</el-form-item>
<el-form-item>
<div class="dialog-footer">
<el-button @click="dialogVisibleChangePassword = false">算了</el-button>
<el-button type="primary" @click="changePassword">
</el-button>
</div>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script setup>
import { userInfoStore } from '@/store/user';
import axios from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { reactive, ref } from 'vue'
import { getUserInfo } from '@/functions/user';
const userinfo = userInfoStore();
console.log(userinfo.account);
const dialogVisibleChangeName = ref(false)
const dialogVisibleChangeIntro = ref(false)
const dialogVisibleChangeAccount = ref(false)
const dialogVisibleChangePassword = ref(false)
const isCountingDown = ref(false);
const countdownTime = ref(60);
const newname = ref('')
const newintro = ref('')
const formRef = ref(null); // 表单引用
const formData = ref({
newaccount: '',
v_id: '',
code: '' // 初始化表单数据
});
const formRedPassword = ref(null); // 密码表单引用
const password = ref({
oldpassword: '',
password: '',
confirmPassword: ''
}); // 密码输入框
// 定义验证规则
const rules = {
newaccount: [
{ required: true, message: '请输入账号', trigger: 'blur' }, // 非空验证
{ type: 'email', message: '请输入有效的邮箱地址', trigger: ['blur', 'change'] } // 邮箱格式验证
],
code: [
{ required: true, message: '请输入验证码', trigger: 'blur' }, // 非空验证
]
};
// 定义密码验证规则
const passwordRules = {
oldpassword: [
{ required: true, message: '请输入原密码', trigger: 'blur' }, // 非空验证
],
password: [
{ required: true, message: '请输入新密码', trigger: 'blur' }, // 非空验证
{ min: 6, message: '密码长度至少6位', trigger: 'blur' }, // 密码长度验证
],
confirmPassword: [
{ required: true, message: '请确认密码', trigger: 'blur' }, // 非空验证
{ min: 6, message: '密码长度至少6位', trigger: 'blur' }, // 密码长度验证
]
};
//修改头像部分
//预览头像
const avatarPreview = ref(userinfo.user.u_avatar);
const avatar = ref(null); // 存储上传的头像文件
// 处理头像预览并将文件保存到变量
const handleAvatarChange = (event) => {
const file = event.target.files[0];
if (file) {
avatar.value = file;
avatarPreview.value = URL.createObjectURL(file);
}
};
//上传到服务器
const uploadAvatar = () => {
if(!avatar.value){
ElMessage('请选择头像')
return
}
const formdata = new FormData();
formdata.append('file', avatar.value)
formdata.append('id', userinfo.user.u_id)
axios({
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': userinfo.token
},
method: 'post',
url: '/api/avatar/upload',
data: formdata
}).then((response) => {
if (response.data.code !== 200) {
ElMessage.error(response.data.msg || '上传失败')
return
}
getUserInfo()
ElMessage.success('上传成功')
}).catch((error) => {
console.error('上传失败:', error);
ElMessage.error('上传失败')
})
}
const changeName = async () => {
const response = await axios.post('/api/user/updatename', {
u_name: newname.value
}
, {
headers: {
'Authorization': userinfo.token,
'Content-Type': 'application/json'
}
});
if (response.data.code === 200) {
userinfo.user.u_name = newname.value
newname.value = ''
dialogVisibleChangeName.value = false
ElMessage.success('修改成功')
} else {
ElMessage.error(response.data.msg)
}
}
const changeIntro = async () => {
console.log(newintro.value);
const response = await axios.post('/api/user/updateintroduction', {
u_introduction: newintro.value
}, {
headers: {
'Authorization': userinfo.token,
'Content-Type': 'application/json'
}
});
if (response.data.code === 200) {
userinfo.user.u_introduction = newintro.value
newintro.value = ''
dialogVisibleChangeIntro.value = false
ElMessage.success('修改成功')
} else {
ElMessage.error(response.data.msg)
}
}
// 发送验证码
const sendVerificationCode = () => {
formRef.value.validateField('newaccount', (isValid) => {
console.log(isValid);
if (isValid) {
// 如果邮箱验证通过
ElMessage.success('邮箱格式正确,正在发送验证码...');
axios({
headers: {
'Content-Type': 'application/json'
},
method: "post",
url: "/api/code/sendcode",
data: JSON.stringify({ u_account: formData.value.newaccount })
})
.then((response) => {
if (response.data && response.data.code !== 200) {
ElMessageBox.alert("注册失败,请重新填写 msg:" + (response.data.msg || '未知错误'), '注册失败');
} else {
startCountdown();
formData.value.v_id = response.data.data;
console.log(formData.value.v_id);
ElMessageBox.alert('发送成功,请耐心等待', '请求成功');
}
})
.catch((error) => {
console.error("请求失败:", error);
ElMessageBox.alert("请求失败,请稍后再试", '网络错误');
});
} else {
// 如果邮箱验证失败
ElMessage.error('请输入有效的邮箱地址');
return;
}
});
};
// 开始倒计时
const startCountdown = () => {
isCountingDown.value = true;
const interval = setInterval(() => {
countdownTime.value--;
if (countdownTime.value <= 0) {
clearInterval(interval);
isCountingDown.value = false;
countdownTime.value = 60;
}
}, 1000);
};
// 验证验证码,并进行邮箱更改
const changeAccount = async () => {
// 验证新邮箱字段
formRef.value.validateField(['newaccount', 'code'], (errorMessage) => {
console.log(errorMessage);
if (errorMessage) {
// 如果验证通过(errorMessage为空)
ElMessage.success('正在修改邮箱...');
// 验证验证码
axios({
headers: {
'Content-Type': 'application/json'
},
method: "post",
url: "/api/code/verifycode",
data: {
v_id: formData.value.v_id,
code: formData.value.code
}
}).then((response) => {
if (response.data.code !== 200) {
ElMessage.error(response.data.msg || '验证码错误');
return;
} else {
// 验证码验证通过,发起修改邮箱的请求
axios({
headers: {
'Content-Type': 'application/json',
'Authorization': userinfo.token
},
method: "post",
url: "/api/user/updateaccount",
data: {
u_account: formData.value.newaccount
}
}).then((response) => {
if (response.data.code !== 200) {
ElMessage.error(response.data.msg || '修改失败');
return;
} else {
ElMessage.success('邮箱修改成功');
userinfo.user.u_account = formData.value.newaccount; // 更新当前邮箱
formRef.value.resetFields(); // 重置表单数据
formRef.value.clearValidate(); // 清除验证错误
dialogVisibleChangeAccount.value = false; // 关闭弹窗
}
})
}
})
} else {
// 如果验证失败errorMessage不为空
ElMessage.error('请输入正确的验证码');
}
});
};
// 修改密码
const changePassword = async () => {
// 验证密码字段
formRedPassword.value.validateField(['oldpassword', 'password', 'confirmPassword'], (errorMessage) => {
console.log(errorMessage);
if (password.value.password !== password.value.confirmPassword) {
ElMessage.error('两次密码输入不一致');
return;
}
if (password.value.password === password.value.oldpassword) {
ElMessage.error('密码一样你改密码呢');
return;
}
if (errorMessage) {
// 如果验证通过errorMessage为空
ElMessage.success('正在修改密码...');
// 发送修改密码请求
axios({
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': userinfo.token
},
method: "post",
url: "/api/user/updatepassword",
data: password.value
}).then((response) => {
if (response.data.code !== 200) {
ElMessage.error(response.data.msg || '修改失败');
return;
} else {
ElMessage.success('密码修改成功');
formRedPassword.value.resetFields(); // 重置表单数据
formRedPassword.value.clearValidate(); // 清除验证错误
dialogVisibleChangePassword.value = false; // 关闭弹窗
}
})
} else {
// 如果验证失败errorMessage不为空
ElMessage.error('请输入正确的密码');
}
});
};
</script>
<style>
.updateProfile {
position: relative;
}
.profile {
top: 50px;
left: 100px;
width: 150px;
height: 150px;
border-radius: 50%;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
.profile img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
.userinfo {
position: relative;
}
.re-profile {
margin-top: 20px;
}
.el-row {
margin-top: 30px;
}
.dialog-footer {
position: relative;
margin-left: 300px;
}
.codebutton {
width: 75px;
padding: 8px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.codebutton:hover {
background-color: #0056b3;
}
.codebutton:disabled {
background-color: #ccc;
cursor: not-allowed;
}
<template>
<el-row>
<el-col :span="12">
<div class="updateProfile">
<div class="profile">
<!-- 原逻辑:src="avatarPreview"远端头像/本地预览 -->
<img :src="defaultAvatar" alt="头像">
</div>
<el-col span="12">
<input type="file" id="avatar" @change="handleAvatarChange" accept="image/*" />
</el-col>
<el-col span="12">
<el-button class="re-profile" @click="uploadAvatar">修改头像</el-button>
</el-col>
<el-col span="12">
<span>推荐头像参数<br>
分辨率1051*1051 96dpi <br>
格式jpgpng <br>
大小1M
</span>
</el-col>
</div>
</el-col>
<el-col :span="12">
<el-row>
<span style="width: 80%;">用户名{{ userinfo.user.u_name }}</span>
<el-button @click="dialogVisibleChangeName = true">修改名字</el-button>
</el-row>
<el-row>
<span style="width: 80%;">账号{{ userinfo.account }}</span>
<!-- <el-button @click="dialogVisibleChangeAccount = true">修改账号</el-button> -->
</el-row>
<el-row>
<span style="width: 80%;">个性签名{{ userinfo.user.u_introduction }}</span>
<el-button @click="dialogVisibleChangeIntro = true">修改简介</el-button>
</el-row>
<el-row>
<span style="width: 80%;">密码 *********************</span>
<el-button @click="dialogVisibleChangePassword = true">修改密码</el-button>
</el-row>
</el-col>
</el-row>
<!-- 修改名字弹窗 -->
<el-dialog v-model="dialogVisibleChangeName" title="修改名字" width="500">
<el-input v-model="newname" autocomplete="off" />
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisibleChangeName = false">算了</el-button>
<el-button type="primary" @click="changeName">
</el-button>
</div>
</template>
</el-dialog>
<!-- 修改个签弹窗 -->
<el-dialog v-model="dialogVisibleChangeIntro" title="修改个签" width="500">
<el-input v-model="newintro" autocomplete="off" size="large" />
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisibleChangeIntro = false">算了</el-button>
<el-button type="primary" @click="changeIntro">
</el-button>
</div>
</template>
</el-dialog>
<!-- 修改邮箱弹窗 -->
<el-dialog v-model="dialogVisibleChangeAccount" title="修改邮箱" width="500">
<el-row style="margin-bottom: 10px;">
<el-col span="6">当前邮箱</el-col>
<el-col span="18">{{ userinfo.user.u_account }}</el-col>
</el-row>
<el-form ref="formRef" :model="formData" :rules="rules">
<el-form-item label="新邮箱" prop="newaccount">
<el-col span="24">
<el-input v-model="formData.newaccount" autocomplete="off" placeholder="请输入邮箱地址"
style="width: 300px;" />
</el-col>
</el-form-item>
<el-form-item label="验证码" prop="code">
<el-col span="18">
<el-input v-model="formData.code" autocomplete="off" placeholder="请输入验证码" style="width: 225px;" />
</el-col>
<el-col span="6">
<button class="codebutton" type="button" :disabled="isCountingDown" @click="sendVerificationCode">
{{ isCountingDown ? `${countdownTime} s` : 'Get Code' }}
</button>
</el-col>
</el-form-item>
<el-form-item>
<div class="dialog-footer">
<el-button @click="dialogVisibleChangeAccount = false">算了</el-button>
<el-button type="primary" @click="changeAccount">
</el-button>
</div>
</el-form-item>
</el-form>
</el-dialog>
<!-- 修改密码弹窗 -->
<el-dialog v-model="dialogVisibleChangePassword" title="修改密码" width="500">
<el-form ref="formRedPassword" :model="password" :rules="passwordRules">
<el-form-item label="原密码" prop="oldpassword">
<el-col span="24">
<el-input v-model="password.oldpassword" autocomplete="off" placeholder="请输入原密码"
show-password="true" style="width: 300px;" />
</el-col>
</el-form-item>
<el-form-item label="新密码" prop="password">
<el-col span="24">
<el-input v-model="password.password" autocomplete="off" placeholder="请输入新密码" show-password="true"
style="width: 300px;" />
</el-col>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-col span="24">
<el-input v-model="password.confirmPassword" autocomplete="off" placeholder="确认密码"
show-password="true" style="width: 300px;" />
</el-col>
</el-form-item>
<el-form-item>
<div class="dialog-footer">
<el-button @click="dialogVisibleChangePassword = false">算了</el-button>
<el-button type="primary" @click="changePassword">
</el-button>
</div>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script setup>
import { userInfoStore } from '@/store/user';
import axios from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { reactive, ref } from 'vue'
import { getUserInfo } from '@/functions/user';
import defaultAvatar from '@/assets/defaultavatar.jpg'
const userinfo = userInfoStore();
console.log(userinfo.account);
const dialogVisibleChangeName = ref(false)
const dialogVisibleChangeIntro = ref(false)
const dialogVisibleChangeAccount = ref(false)
const dialogVisibleChangePassword = ref(false)
const isCountingDown = ref(false);
const countdownTime = ref(60);
const newname = ref('')
const newintro = ref('')
const formRef = ref(null); // 表单引用
const formData = ref({
newaccount: '',
v_id: '',
code: '' // 初始化表单数据
});
const formRedPassword = ref(null); // 密码表单引用
const password = ref({
oldpassword: '',
password: '',
confirmPassword: ''
}); // 密码输入框
// 定义验证规则
const rules = {
newaccount: [
{ required: true, message: '请输入账号', trigger: 'blur' }, // 非空验证
{ type: 'email', message: '请输入有效的邮箱地址', trigger: ['blur', 'change'] } // 邮箱格式验证
],
code: [
{ required: true, message: '请输入验证码', trigger: 'blur' }, // 非空验证
]
};
// 定义密码验证规则
const passwordRules = {
oldpassword: [
{ required: true, message: '请输入原密码', trigger: 'blur' }, // 非空验证
],
password: [
{ required: true, message: '请输入新密码', trigger: 'blur' }, // 非空验证
{ min: 6, message: '密码长度至少6位', trigger: 'blur' }, // 密码长度验证
],
confirmPassword: [
{ required: true, message: '请确认密码', trigger: 'blur' }, // 非空验证
{ min: 6, message: '密码长度至少6位', trigger: 'blur' }, // 密码长度验证
]
};
//修改头像部分
//预览头像
// const avatarPreview = ref(userinfo.user.u_avatar); // 原:远端头像预览
const avatar = ref(null); // 存储上传的头像文件
// 处理头像预览并将文件保存到变量
const handleAvatarChange = (event) => {
const file = event.target.files[0];
if (file) {
avatar.value = file;
// avatarPreview.value = URL.createObjectURL(file); // 原:本地预览
}
};
//上传到服务器
const uploadAvatar = () => {
if(!avatar.value){
ElMessage('请选择头像')
return
}
const formdata = new FormData();
formdata.append('file', avatar.value)
formdata.append('id', userinfo.user.u_id)
axios({
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': userinfo.token
},
method: 'post',
url: '/api/avatar/upload',
data: formdata
}).then((response) => {
if (response.data.code !== 200) {
ElMessage.error(response.data.msg || '上传失败')
return
}
getUserInfo()
ElMessage.success('上传成功')
}).catch((error) => {
console.error('上传失败:', error);
ElMessage.error('上传失败')
})
}
const changeName = async () => {
const response = await axios.post('/api/user/updatename', {
u_name: newname.value
}
, {
headers: {
'Authorization': userinfo.token,
'Content-Type': 'application/json'
}
});
if (response.data.code === 200) {
userinfo.user.u_name = newname.value
newname.value = ''
dialogVisibleChangeName.value = false
ElMessage.success('修改成功')
} else {
ElMessage.error(response.data.msg)
}
}
const changeIntro = async () => {
console.log(newintro.value);
const response = await axios.post('/api/user/updateintroduction', {
u_introduction: newintro.value
}, {
headers: {
'Authorization': userinfo.token,
'Content-Type': 'application/json'
}
});
if (response.data.code === 200) {
userinfo.user.u_introduction = newintro.value
newintro.value = ''
dialogVisibleChangeIntro.value = false
ElMessage.success('修改成功')
} else {
ElMessage.error(response.data.msg)
}
}
// 发送验证码
const sendVerificationCode = () => {
formRef.value.validateField('newaccount', (isValid) => {
console.log(isValid);
if (isValid) {
// 如果邮箱验证通过
ElMessage.success('邮箱格式正确,正在发送验证码...');
axios({
headers: {
'Content-Type': 'application/json'
},
method: "post",
url: "/api/code/sendcode",
data: JSON.stringify({ u_account: formData.value.newaccount })
})
.then((response) => {
if (response.data && response.data.code !== 200) {
ElMessageBox.alert("注册失败,请重新填写 msg:" + (response.data.msg || '未知错误'), '注册失败');
} else {
startCountdown();
formData.value.v_id = response.data.data;
console.log(formData.value.v_id);
ElMessageBox.alert('发送成功,请耐心等待', '请求成功');
}
})
.catch((error) => {
console.error("请求失败:", error);
ElMessageBox.alert("请求失败,请稍后再试", '网络错误');
});
} else {
// 如果邮箱验证失败
ElMessage.error('请输入有效的邮箱地址');
return;
}
});
};
// 开始倒计时
const startCountdown = () => {
isCountingDown.value = true;
const interval = setInterval(() => {
countdownTime.value--;
if (countdownTime.value <= 0) {
clearInterval(interval);
isCountingDown.value = false;
countdownTime.value = 60;
}
}, 1000);
};
// 验证验证码,并进行邮箱更改
const changeAccount = async () => {
// 验证新邮箱字段
formRef.value.validateField(['newaccount', 'code'], (errorMessage) => {
console.log(errorMessage);
if (errorMessage) {
// 如果验证通过errorMessage为空
ElMessage.success('正在修改邮箱...');
// 验证验证码
axios({
headers: {
'Content-Type': 'application/json'
},
method: "post",
url: "/api/code/verifycode",
data: {
v_id: formData.value.v_id,
code: formData.value.code
}
}).then((response) => {
if (response.data.code !== 200) {
ElMessage.error(response.data.msg || '验证码错误');
return;
} else {
// 验证码验证通过,发起修改邮箱的请求
axios({
headers: {
'Content-Type': 'application/json',
'Authorization': userinfo.token
},
method: "post",
url: "/api/user/updateaccount",
data: {
u_account: formData.value.newaccount
}
}).then((response) => {
if (response.data.code !== 200) {
ElMessage.error(response.data.msg || '修改失败');
return;
} else {
ElMessage.success('邮箱修改成功');
userinfo.user.u_account = formData.value.newaccount; // 更新当前邮箱
formRef.value.resetFields(); // 重置表单数据
formRef.value.clearValidate(); // 清除验证错误
dialogVisibleChangeAccount.value = false; // 关闭弹窗
}
})
}
})
} else {
// 如果验证失败errorMessage不为空
ElMessage.error('请输入正确的验证码');
}
});
};
// 修改密码
const changePassword = async () => {
// 验证密码字段
formRedPassword.value.validateField(['oldpassword', 'password', 'confirmPassword'], (errorMessage) => {
console.log(errorMessage);
if (password.value.password !== password.value.confirmPassword) {
ElMessage.error('两次密码输入不一致');
return;
}
if (password.value.password === password.value.oldpassword) {
ElMessage.error('密码一样你改密码呢');
return;
}
if (errorMessage) {
// 如果验证通过errorMessage为空
ElMessage.success('正在修改密码...');
// 发送修改密码请求
axios({
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': userinfo.token
},
method: "post",
url: "/api/user/updatepassword",
data: password.value
}).then((response) => {
if (response.data.code !== 200) {
ElMessage.error(response.data.msg || '修改失败');
return;
} else {
ElMessage.success('密码修改成功');
formRedPassword.value.resetFields(); // 重置表单数据
formRedPassword.value.clearValidate(); // 清除验证错误
dialogVisibleChangePassword.value = false; // 关闭弹窗
}
})
} else {
// 如果验证失败errorMessage不为空
ElMessage.error('请输入正确的密码');
}
});
};
</script>
<style>
.updateProfile {
position: relative;
}
.profile {
top: 50px;
left: 100px;
width: 150px;
height: 150px;
border-radius: 50%;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
.profile img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
.userinfo {
position: relative;
}
.re-profile {
margin-top: 20px;
}
.el-row {
margin-top: 30px;
}
.dialog-footer {
position: relative;
margin-left: 300px;
}
.codebutton {
width: 75px;
padding: 8px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.codebutton:hover {
background-color: #0056b3;
}
.codebutton:disabled {
background-color: #ccc;
cursor: not-allowed;
}
</style>