新增用户注册功能

This commit is contained in:
Cheng Zhou
2025-12-22 21:19:48 +08:00
parent 03fddba406
commit 6ddf9901a0
33 changed files with 1389 additions and 138 deletions
+63 -10
View File
@@ -39,7 +39,7 @@
</el-menu-item>
<el-menu-item index="/study/milestones">
<el-icon><Timer /></el-icon>
<span>里程碑管理</span>
<span>伦理与启动</span>
</el-menu-item>
<el-menu-item index="/study/subjects">
<el-icon><UserFilled /></el-icon>
@@ -94,14 +94,28 @@
</div>
<div class="header-right">
<StudySelector />
<div class="user-profile">
<div class="user-avatar">{{ auth.user?.username?.charAt(0).toUpperCase() }}</div>
<div class="user-details">
<span class="username">{{ auth.user?.username }}</span>
<span class="user-role">{{ auth.user?.role }}</span>
</div>
<el-button link type="danger" @click="onLogout" class="logout-btn">退出</el-button>
</div>
<el-dropdown trigger="click" @command="onCommand" class="user-profile">
<span class="dropdown-trigger compact">
<div class="user-avatar">
<img v-if="auth.user?.avatar_url" :src="auth.user.avatar_url" alt="avatar" />
<span v-else>{{ (auth.user?.username || auth.user?.email || "用户").charAt(0).toUpperCase() }}</span>
</div>
<span class="username">{{ auth.user?.username || auth.user?.email || "用户" }}</span>
<el-icon><ArrowDown /></el-icon>
</span>
<template #dropdown>
<el-dropdown-menu class="user-dropdown-menu">
<el-dropdown-item command="profile">
<el-icon><User /></el-icon>
<span>个人中心</span>
</el-dropdown-item>
<el-dropdown-item command="logout">
<el-icon><SwitchButton /></el-icon>
<span>退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</el-header>
@@ -110,6 +124,7 @@
<router-view />
</div>
</el-main>
</el-container>
</el-container>
</template>
@@ -123,7 +138,7 @@ import StudySelector from "./StudySelector.vue";
import {
Monitor, User, Suitcase, List, House, Timer, UserFilled,
Warning, InfoFilled, QuestionFilled, Checked, Management,
Money, Collection, Memo
Money, Collection, Memo, ArrowDown, SwitchButton
} from "@element-plus/icons-vue";
const auth = useAuthStore();
@@ -137,6 +152,15 @@ const onLogout = () => {
study.clearCurrentStudy();
router.replace("/login");
};
const onCommand = (cmd: string) => {
if (cmd === "logout") {
onLogout();
} else if (cmd === "profile") {
// 预留个人设置路由占位,如后续有页面则跳转
router.push("/profile");
}
};
</script>
<style scoped>
@@ -254,6 +278,7 @@ const onLogout = () => {
gap: 12px;
padding-left: 16px;
border-left: 1px solid var(--ctms-border-color);
cursor: pointer;
}
.user-avatar {
@@ -267,6 +292,12 @@ const onLogout = () => {
justify-content: center;
font-weight: 600;
font-size: 14px;
overflow: hidden;
}
.user-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.user-details {
@@ -290,6 +321,28 @@ const onLogout = () => {
margin-left: 8px;
}
.dropdown-trigger {
display: inline-flex;
align-items: center;
gap: 8px;
}
.dropdown-trigger.compact {
padding: 6px 10px;
border-radius: 10px;
background: #f4f6fa;
border: 1px solid #e2e6f0;
color: #333;
}
.avatar-icon {
font-size: 18px;
}
.user-dropdown-menu :deep(.el-dropdown-menu__item) {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
}
.study-tag {
font-weight: 500;
color: var(--ctms-primary);