cyber/src/pages/accountPages/Account_setting.vue

485 lines
10 KiB
Vue
Raw Normal View History

2025-02-14 23:14:54 +08:00
<script setup>
import {ref} from 'vue'
import AuthService from "../../../services/auth.js";
import router from "../../router/index.js";
import store from "../../store/index.js";
import api from "../../utils/axios.js";
import swal from "../../utils/sweetalert.js";
const permissionLevel = ref({
"0" : "普通用户",
"1" : "管理员"
})
const isAvatarHover = ref(false)
const isEditingUsername = ref(false)
const tempUsername = ref(store.state.userInfo.username)
const isEditingIntro = ref(false)
const userIntro = ref('')
const tempIntro = ref(userIntro.value)
const fileInput = ref(null);
const openFileDialog = () => {
fileInput.value.click();
}
const handleFileChange = async (event) => {
const file = event.target.files[0];
if (file) {
fileInput.value = file;
store.commit('startLoading', '正在上传图片...');
try {
const formData = new FormData();
formData.append("image", file);
const jsonData = JSON.stringify({TOKEN: store.state.token});
formData.append("jsondata", jsonData);
const response = await api.post("/changeprofile", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
if (response.code === 0) {
await AuthService.setSelfInfo();
swal.tip('success', '头像上传成功! ');
} else {
swal.tip('error', '未知错误...');
}
} catch (error) {
console.error("败:", error);
swal.tip('error', '网络连接错误');
}
store.commit('stopLoading');
}
}
function editUsername() {
isEditingUsername.value = true
tempUsername.value = store.state.userInfo.username
}
function confirmEditUsername() {
swal.tip('error', '不让改');
isEditingUsername.value = false
}
function cancelEditUsername() {
isEditingUsername.value = false
}
function logout() {
AuthService.logout();
router.replace('/login')
}
// 进入编辑简介
function editIntro() {
isEditingIntro.value = true
tempIntro.value = userIntro.value
}
// 取消编辑简介
function cancelEditIntro() {
isEditingIntro.value = false
tempIntro.value = userIntro.value
}
// 保存编辑简介
function saveIntro() {
userIntro.value = tempIntro.value
isEditingIntro.value = false
}
</script>
<template>
<div class="container">
<div class="profile-box">
<!-- 头像 -->
<div
class="avatar-wrapper"
@mouseenter="isAvatarHover = true"
@mouseleave="isAvatarHover = false"
>
<img
:src="store.getters.profileImage"
alt="用户头像"
class="avatar-image"
/>
<div :style="isAvatarHover ? 'opacity: 1;' : 'opacity: 0;'" class="avatar-overlay" @click="openFileDialog">
可修改头像
</div>
<input
type="file"
ref="fileInput"
accept="image/png, image/jpg, image/jpeg"
style="display: none"
@change="handleFileChange"
/>
</div>
<!-- 信息 -->
<div class="user-info">
<div class="username-row">
<label>用户名</label>
<span v-if="!isEditingUsername" class="username-text">
{{ store.state.userInfo.username }}
</span>
<input
v-else
type="text"
class="username-input"
v-model="tempUsername"
/>
<!-- 改名 -->
<span
v-if="!isEditingUsername"
class="edit-emoji"
@click="editUsername"
>
🖊
</span>
<div v-if="isEditingUsername">
<button
class="confirm-btn"
@click="confirmEditUsername"
v-if="tempUsername !== store.state.userInfo.username"
>
</button>
<button
class="cancel-btn"
@click="cancelEditUsername"
>
×
</button>
</div>
</div>
<div class="permission-row">
<label>账号权限</label>
<span>{{ permissionLevel[store.state.userInfo.role_id] }}</span>
</div>
<div class="register-date">
<label>注册日期</label>
<span>{{ store.state.userInfo.birth?.split(' ')[0] || '未知' }}</span>
</div>
</div>
</div>
<button
class="logout-btn"
@click="logout"
>登出
</button>
<div class="halving-line" />
<label class="color-mode-box">
<input type="radio" v-model="store.state.theme" value="light">亮色模式
</label>
<label class="color-mode-box">
<input type="radio" v-model="store.state.theme" value="dark">深色模式
</label>
<!-- -->
<!-- <div class="intro-box">-->
<!-- <label>个人简介</label>-->
<!-- <textarea-->
<!-- class="intro-textarea"-->
<!-- :readonly="!isEditingIntro"-->
<!-- v-model="tempIntro"-->
<!-- placeholder="空空如也~"-->
<!-- />-->
<!-- &lt;!&ndash; 修改/保存/取消 按钮组 &ndash;&gt;-->
<!-- <div class="intro-actions">-->
<!-- &lt;!&ndash; 默认只显示修改 &ndash;&gt;-->
<!-- <button-->
<!-- v-if="!isEditingIntro"-->
<!-- class="intro-edit-btn"-->
<!-- @click="editIntro"-->
<!-- >-->
<!-- 修改-->
<!-- </button>-->
<!-- &lt;!&ndash; 编辑状态下显示保存取消 &ndash;&gt;-->
<!-- <div v-else class="intro-edit-group">-->
<!-- <button class="intro-save-btn" @click="saveIntro">保存</button>-->
<!-- <button class="intro-cancel-btn" @click="cancelEditIntro">取消</button>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
</div>
</template>
<style scoped>
/* ========== 公共容器区 ========== */
.container {
//height: calc(100vh - 60px);
width: 100%;
overflow-y: auto;
display: flex;
flex-direction: column;
align-items: center;
color: #f5f6f7;
padding: 20px 0;
transition: background-color 0.3s ease, color 0.3s ease;
animation: fadeIn 0.3s ease-in-out;
}
.theme-light .container {
color: #333333;
}
input, textarea {
color: white;
background: #000000;
}
.theme-light input, .theme-light textarea {
color: #2a2a2a;
background: #ffffff;
}
/* ========== 个人信息区 ========== */
.profile-box {
display: flex;
flex-direction: row;
gap: 20px;
width: 80%;
max-width: 800px;
margin-bottom: 30px;
}
.avatar-wrapper {
position: relative;
width: 100px;
height: 100px;
}
.avatar-image {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
cursor: pointer;
box-shadow: 0 0 10px rgba(255, 255, 255, 0.4);
}
.theme-light .avatar-image {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
}
.avatar-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.4);
display: flex;
align-items: center;
justify-content: center;
color: #f5f6f7;
font-size: 12px;
transition: all 0.3s ease;
cursor: pointer;
}
.user-info {
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
.username-row,
.permission-row,
.register-date {
display: flex;
align-items: center;
gap: 8px;
margin: 6px 0;
}
.username-text {
margin: 2px;
font-weight: bold;
}
.halving-line {
width: 80%;
height: 1px;
background: linear-gradient(to bottom, rgba(217, 217, 217, 0.6), rgba(114, 114, 114, 0.6));
margin: 20px 0;
border-radius: 2px;
}
/* ========== 编辑用户名输入框 ========== */
.username-input {
padding: 4px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
outline: none;
transition: border-color 0.3s ease;
}
/* ========== 编辑笔按钮 ========== */
.edit-emoji {
cursor: pointer;
opacity: 0.7;
transition: opacity 0.2s ease;
}
.edit-emoji:hover {
opacity: 1;
}
/* ========== 确定按钮 ========== */
.confirm-btn, .cancel-btn {
margin: 0 3px;
padding: 4px 8px;
border: none;
background-color: #3b6ea8;
color: #f5f6f7;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.confirm-btn:hover {
background-color: #2f5687;
}
/* 亮色模式下的确定按钮 */
.theme-light .confirm-btn, .theme-light .cancel-btn {
background-color: #ffc107;
color: #333333;
}
.theme-light .confirm-btn:hover, .theme-light .cancel-btn:hover {
background-color: #e0a806;
}
/* ========== 颜色模式区 ========== */
.color-mode-box {
width: 80%;
max-width: 800px;
display: flex;
align-items: center;
font-size: 18px;
margin: 5px;
}
.color-mode-box input {
width: 20px;
height: 20px;
accent-color: #007bff;
margin-right: 10px;
transition: transform 0.2s ease;
}
.color-mode-box input:checked {
transform: scale(1.2);
}
.theme-light .color-mode-box input {
accent-color: #ffb74d;
}
/* ========== 个人简介区 ========== */
.intro-box {
width: 80%;
max-width: 800px;
display: flex;
flex-direction: column;
}
.intro-textarea {
width: 100%;
min-height: 100px;
margin-top: 5px;
resize: vertical;
padding: 8px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
outline: none;
transition: background-color 0.3s ease;
}
.intro-actions {
margin-top: 10px;
}
.intro-edit-group {
display: flex;
gap: 10px;
}
/* ========== 修改/保存/取消/登出 按钮 ========== */
.intro-edit-btn,
.intro-save-btn,
.intro-cancel-btn {
padding: 6px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
background-color: #3b6ea8;
color: #f5f6f7;
transition: background-color 0.3s ease;
}
.intro-edit-btn:hover,
.intro-save-btn:hover,
.intro-cancel-btn:hover {
background-color: #2f5687;
}
.theme-light .intro-edit-btn,
.theme-light .intro-save-btn,
.theme-light .intro-cancel-btn {
background-color: #ffc107;
color: #333333;
}
.theme-light .intro-edit-btn:hover,
.theme-light .intro-save-btn:hover,
.theme-light .intro-cancel-btn:hover {
background-color: #e0a806;
}
.logout-btn {
padding: 6px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
background-color: orangered;
color: white;
transition: all 0.1s ease;
}
.logout-btn:hover {
background-color: #be3300;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>