feat(布局): 重构侧边栏、顶栏与页面布局样式

This commit is contained in:
yelan
2026-09-15 17:36:16 +08:00
parent e45449b7c8
commit d0dc73c182
7 changed files with 551 additions and 231 deletions
+116 -55
View File
@@ -1,7 +1,9 @@
<script setup lang="ts">
import { computed, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import AppIcon from '@/components/layout/AppIcon.vue'
import { useAppStore } from '@/stores/app'
const route = useRoute()
@@ -21,6 +23,17 @@ const campusPlaceholder = computed(() => {
return appStore.campusLoadFailed ? '院区加载失败' : '暂无可用院区'
})
const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
const todayText = computed(() => {
const now = new Date()
return `${now.getFullYear()}年${now.getMonth() + 1}月${now.getDate()}日 ${weekdays[now.getDay()]}`
})
function handleMessages() {
ElMessage.info('暂无新消息')
}
onMounted(() => {
void appStore.loadCampuses()
})
@@ -29,26 +42,34 @@ onMounted(() => {
<template>
<header class="clinical-header">
<div class="header-page">
<span class="header-title">{{ pageTitle }}</span>
<span class="header-breadcrumb">{{ pageGroup }} / {{ pageTitle }}</span>
<p class="header-subtitle">{{ pageGroup }} · 医签通平台</p>
<h1 class="header-title">{{ pageTitle }}</h1>
</div>
<div class="header-actions">
<label class="campus-scope">
<AppIcon name="building-2" class="scope-icon" />
<select
v-model="selectedCampusId"
:disabled="appStore.campusLoading || !appStore.campusRecords.length"
aria-label="选择院区"
>
<option v-if="!appStore.campusRecords.length" value="">
{{ campusPlaceholder }}
</option>
<option v-for="campus in appStore.campusRecords" :key="campus.id" :value="campus.id">
{{ campus.name }}
</option>
</select>
<AppIcon name="chevron-down" class="scope-arrow" />
</label>
<button class="icon-button" type="button" aria-label="查看消息" @click="handleMessages">
<AppIcon name="bell" class="icon-button-icon" />
</button>
<span class="header-date">{{ todayText }}</span>
</div>
<span class="header-spacer" />
<label class="campus-selector">
<span class="campus-label">院区</span>
<select
v-model="selectedCampusId"
:disabled="appStore.campusLoading || !appStore.campusRecords.length"
aria-label="选择院区"
>
<option v-if="!appStore.campusRecords.length" value="">
{{ campusPlaceholder }}
</option>
<option v-for="campus in appStore.campusRecords" :key="campus.id" :value="campus.id">
{{ campus.name }}
</option>
</select>
</label>
<span class="environment-badge">{{ appStore.environment }}</span>
</header>
</template>
@@ -56,69 +77,109 @@ onMounted(() => {
.clinical-header {
display: flex;
flex-shrink: 0;
gap: 14px;
align-items: center;
justify-content: space-between;
height: var(--header-height);
padding: 0 20px;
background: #fff;
padding: 0 30px;
background: rgb(255 255 255 / 93%);
border-bottom: 1px solid var(--line);
backdrop-filter: blur(14px);
}
.header-page {
display: flex;
gap: 14px;
align-items: baseline;
min-width: 0;
}
.header-title {
flex-shrink: 0;
color: var(--ink);
font-size: 16px;
font-weight: 700;
.header-subtitle {
margin: 0;
color: #82969f;
font-size: 10px;
}
.header-breadcrumb {
.header-title {
margin: 3px 0 0;
overflow: hidden;
color: var(--mut);
font-size: 12px;
color: var(--ink);
font-size: 17px;
font-weight: 700;
text-overflow: ellipsis;
white-space: nowrap;
}
.header-spacer {
flex: 1;
}
.campus-selector {
.header-actions {
display: flex;
flex-shrink: 0;
gap: 14px;
align-items: center;
color: #6e828b;
font-size: 11px;
}
.campus-scope {
display: flex;
gap: 6px;
align-items: center;
height: 32px;
padding: 0 9px;
background: #fff;
border: 1px solid var(--line);
border-radius: 9px;
}
.campus-label {
color: var(--mut);
font-size: 12px;
.scope-icon {
width: 14px;
height: 14px;
}
.campus-selector select {
.scope-arrow {
width: 11px;
height: 11px;
}
.campus-scope select {
width: auto;
padding: 4px 8px;
color: var(--brand-d);
font-size: 12.5px;
font-weight: 700;
background: var(--brand-l);
border: 1px solid var(--brand);
border-radius: 6px;
max-width: 150px;
padding: 0;
overflow: hidden;
color: #4d6873;
font-size: 11px;
text-overflow: ellipsis;
background: transparent;
border: 0;
outline: 0;
appearance: none;
}
.environment-badge {
flex-shrink: 0;
padding: 3px 8px;
color: var(--warn);
.campus-scope select:disabled {
color: #9aabb3;
}
.icon-button {
position: relative;
display: grid;
width: 34px;
height: 34px;
color: #506c77;
place-items: center;
background: #edf4f6;
border: 0;
border-radius: 9px;
transition: all 0.2s;
}
.icon-button:hover {
color: #08788d;
background: #def0f3;
transform: translateY(-1px);
}
.icon-button-icon {
width: 17px;
height: 17px;
}
.header-date {
color: #6e828b;
font-size: 11px;
background: var(--warn-l);
border-radius: 20px;
}
</style>