新增用户注册功能

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);
+2 -2
View File
@@ -1,5 +1,5 @@
<template>
<el-dialog :title="isEdit ? '编辑里程碑' : '新增里程碑'" v-model="visible" width="520px" @close="onClose">
<el-dialog :title="isEdit ? '编辑节点' : '新增节点'" v-model="visible" width="520px" @close="onClose">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" />
@@ -98,7 +98,7 @@ const memberOptions = computed(() => {
return memberList
.map((m: any) => {
const user = m.user || {};
const label = user.display_name || user.username || m.username || "—";
const label = user.full_name || user.display_name || user.username || user.email || m.username || m.email || "—";
return { value: m.user_id, label };
})
.filter((opt) => {
+1 -1
View File
@@ -31,7 +31,7 @@ import {
const router = useRouter();
const actions = [
{ label: "里程碑管理", path: "/study/milestones", icon: Timer, color: "#2f54eb" },
{ label: "伦理与启动", path: "/study/milestones", icon: Timer, color: "#2f54eb" },
{ label: "受试者", path: "/study/subjects", icon: UserFilled, color: "#722ed1" },
{ label: "不良事件", path: "/study/aes", icon: Warning, color: "#faad14" },
{ label: "数据问题", path: "/study/data-queries", icon: QuestionFilled, color: "#1890ff" },