<template>
|
<div
|
class="exam-list-container w-screen h-screen bg-slate-50 flex flex-col items-center"
|
>
|
<NormalHeader class="shrink-0"></NormalHeader>
|
|
<div class="list-container container grow relative">
|
<div
|
class="personal-center-box list-content absolute top-0 bottom-0 left-0 right-0 py-4"
|
>
|
<div class="information">
|
<el-card class="h-full" :body-style="{ height: '50%' }">
|
<div
|
class="card-wrapper w-full h-full flex flex-col px-8 box-border"
|
>
|
<div>个人信息</div>
|
<div class="img-box">
|
<input
|
type="file"
|
@change="changeHeadPortrait"
|
accept=".jpg, .png"
|
style="display: none"
|
ref="fileHeadPortrait"
|
id="fileHeadPortrait"
|
/>
|
<img
|
class="img"
|
id="headPortrait"
|
@click="uploadImage"
|
:src="'api/files/' + userData.imagePath"
|
/>
|
<span>{{ userData.userName }}</span>
|
</div>
|
<div>
|
<el-form label-width="auto" style="max-width: 600px">
|
<el-form-item label="姓名">
|
{{ userData.realName }}
|
</el-form-item>
|
<el-form-item label="班级">
|
{{ userData.className.join(",") }}
|
</el-form-item>
|
<el-form-item label="注册时间">
|
{{ userData.createTime }}
|
</el-form-item>
|
</el-form>
|
</div>
|
</div>
|
</el-card>
|
</div>
|
<div class="list-wrapper w-full h-full">
|
<el-card class="h-full" :body-style="{ height: '100%' }">
|
<el-tabs v-model="activeName" class="demo-tabs">
|
<el-tab-pane label="资料修改" name="information">
|
<el-form
|
:model="informationForm"
|
label-width="auto"
|
style="max-width: 600px"
|
:rules="informationRules"
|
ref="informationFormRef"
|
>
|
<el-form-item label="真实姓名" prop="realName">
|
<el-input v-model="informationForm.realName" />
|
</el-form-item>
|
<el-form-item label="年龄">
|
<el-input v-model="informationForm.age" />
|
</el-form-item>
|
<el-form-item label="性别">
|
<el-select
|
v-model="informationForm.sex"
|
style="width: 100px"
|
>
|
<el-option label="男" :value="1" />
|
<el-option label="女" :value="2" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="出生年月">
|
<el-date-picker
|
v-model="informationForm.birthDay"
|
type="date"
|
placeholder="Pick a day"
|
/>
|
</el-form-item>
|
<el-form-item label="手机" prop="phone">
|
<el-input v-model="informationForm.phone" />
|
</el-form-item>
|
<el-form-item>
|
<div class="submit-box">
|
<el-button
|
type="primary"
|
@click="informationSubmit(informationFormRef)"
|
>更新</el-button
|
>
|
</div>
|
</el-form-item></el-form
|
></el-tab-pane
|
>
|
<el-tab-pane label="密码修改" name="password">
|
<el-form
|
:model="passwordForm"
|
label-width="auto"
|
style="max-width: 600px"
|
:rules="passwordRules"
|
ref="passwordFormRef"
|
>
|
<el-form-item label="旧密码" prop="oldPassword">
|
<el-input
|
v-model="passwordForm.oldPassword"
|
type="password"
|
show-password
|
/>
|
</el-form-item>
|
<el-form-item label="新密码" prop="newPassword">
|
<el-input
|
v-model="passwordForm.newPassword"
|
type="password"
|
show-password
|
/>
|
</el-form-item>
|
<el-form-item label="确认密码" prop="newPasswordA">
|
<el-input
|
v-model="passwordForm.newPasswordA"
|
type="password"
|
show-password
|
/>
|
</el-form-item>
|
<el-form-item>
|
<div class="submit-box">
|
<el-button
|
type="primary"
|
@click="passwordSubmit(passwordFormRef)"
|
>保存</el-button
|
>
|
</div>
|
</el-form-item>
|
</el-form>
|
</el-tab-pane>
|
</el-tabs>
|
</el-card>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref } from "vue";
|
import { uploadImg, userUpdate,passwordUpdate } from "@/api/modules/personalCenter.js";
|
import { ElMessage } from "element-plus";
|
|
const activeName = ref("information");
|
const userData = ref(JSON.parse(localStorage.getItem("user")).userInfo);
|
const informationFormRef = ref();
|
const passwordFormRef = ref();
|
const informationForm = ref({
|
realName: userData.value.realName,
|
sex: userData.value.sex,
|
age: userData.value.age,
|
phone: userData.value.phone,
|
birthDay: userData.value.birthDay,
|
});
|
const passwordForm = ref({
|
oldPassword: "",
|
newPassword: "",
|
newPasswordA: "",
|
});
|
// 手机号验证逻辑
|
const validatePhone = (rule, value, callback) => {
|
const phoneRegex = /^1[3-9]\d{9}$/;
|
if (!phoneRegex.test(value)) {
|
callback(new Error("手机号格式不正确"));
|
} else {
|
callback();
|
}
|
};
|
const validatePassword = (rule, value, callback) => {
|
if (!/[A-Z]/.test(value)) {
|
callback(new Error("密码必须包含至少一个大写字母"));
|
} else if (!/[a-z]/.test(value)) {
|
callback(new Error("密码必须包含至少一个小写字母"));
|
} else if (!/[0-9]/.test(value)) {
|
callback(new Error("密码必须包含至少一个数字"));
|
} else {
|
callback();
|
}
|
};
|
const validatePasswordA = (rule, value, callback) => {
|
if (value !== passwordForm.value.newPassword) {
|
callback(new Error("两次输入密码不同!"));
|
} else {
|
callback();
|
}
|
};
|
const informationRules = {
|
realName: [{ required: true, message: "请填写真实姓名", trigger: "blur" }],
|
phone: [
|
{ validator: validatePhone, trigger: "blur" },
|
{ required: true, message: "请输入手机号", trigger: "blur" },
|
],
|
};
|
const passwordRules = {
|
oldPassword: [
|
{ validator: validatePassword, trigger: "blur" },
|
{ required: true, message: "请输入旧密码", trigger: "blur" },
|
],
|
newPassword: [
|
{ validator: validatePasswordA, trigger: "blur" },
|
{ required: true, message: "请输入新密码", trigger: "blur" },
|
],
|
newPasswordA: [
|
{ validator: validatePasswordA, trigger: "blur" },
|
{ required: true, message: "请输入再次输入新密码", trigger: "blur" },
|
],
|
};
|
//头像上传
|
let formData = new FormData();
|
const uploadImage = () => {
|
let logoFile = document.getElementById("fileHeadPortrait");
|
if (logoFile) {
|
logoFile.click();
|
}
|
};
|
const changeHeadPortrait = (e) => {
|
// let platformLogo = document.getElementById("headPortrait");
|
if (e.target.files[0]) {
|
// let reader = new FileReader();
|
// reader.onload = function (e) {
|
// if (platformLogo) {
|
// platformLogo.setAttribute("src", e.target.result);
|
// }
|
// };
|
// reader.readAsDataURL(e.target.files[0]);
|
formData.set("file", e.target.files[0]);
|
uploadImg(formData).then(
|
() => {
|
ElMessage({
|
showClose: true,
|
message: "上传成功",
|
type: "success",
|
});
|
// window.location.reload();
|
},
|
(err) => {
|
ElMessage.error(err.data.errorMsg);
|
}
|
);
|
}
|
};
|
const informationSubmit = async (formEl) => {
|
if (!formEl) return;
|
await formEl.validate((valid, fields) => {
|
if (valid) {
|
informationForm.value.birthDay = timestampToDate(
|
informationForm.value.birthDay
|
);
|
userUpdate(informationForm.value).then(
|
() => {
|
ElMessage({
|
showClose: true,
|
message: "更新成功",
|
type: "success",
|
});
|
const newData = JSON.parse(localStorage.getItem("user"));
|
newData.userInfo.realName = informationForm.value.realName;
|
newData.userInfo.sex = informationForm.value.sex;
|
newData.userInfo.age = informationForm.value.age;
|
newData.userInfo.phone = informationForm.value.phone;
|
newData.userInfo.birthDay = informationForm.value.birthDay;
|
localStorage.setItem("user", JSON.stringify(newData));
|
},
|
(err) => {
|
ElMessage.error(err.data.errorMsg);
|
}
|
);
|
} else {
|
console.log("error submit!", fields);
|
}
|
});
|
};
|
const passwordSubmit = async (formEl) => {
|
if (!formEl) return;
|
await formEl.validate((valid, fields) => {
|
if (valid) {
|
let data = {
|
userId:userData.value.id,
|
newPassword:passwordForm.value.newPassword,
|
oldPassword:passwordForm.value.oldPassword,
|
}
|
passwordUpdate(data).then(
|
() => {
|
ElMessage({
|
showClose: true,
|
message: "修改成功",
|
type: "success",
|
});
|
},
|
(err) => {
|
ElMessage.error(err.data.errorMsg);
|
}
|
);
|
} else {
|
console.log("error submit!", fields);
|
}
|
});
|
};
|
function timestampToDate(timestamp) {
|
const date = new Date(timestamp); // 将时间戳转换为Date对象
|
const year = date.getFullYear();
|
const month = date.getMonth() + 1; // 月份从0开始,所以要加1
|
const day = date.getDate();
|
const hours = date.getHours();
|
const minutes = date.getMinutes();
|
const seconds = date.getSeconds();
|
const convertedTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
return convertedTime; // 使用Intl.DateTimeFormat进行格式化
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
:deep(.el-tabs__nav-wrap:after) {
|
display: none;
|
}
|
.personal-center-box {
|
display: flex;
|
justify-content: space-between;
|
}
|
.information {
|
width: 500px;
|
margin-right: 20px;
|
}
|
.img-box {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
flex-direction: column;
|
margin-top: 30px;
|
margin-bottom: 30px;
|
}
|
.img {
|
height: 150px;
|
width: 150px;
|
border-radius: 100px;
|
overflow: hidden;
|
object-fit: cover;
|
}
|
.submit-box {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
width: 100%;
|
}
|
</style>
|