cyber/src/pages/accountPages/Account_setting.vue
2025-02-14 23:16:09 +08:00

485 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>