style: 重塑政务风格 + 操作列统一 el-link + 表格紧凑化
业务背景 - ry-vue3 为政务/卫健委风合规管理系统 (医疗机构合规系统), 不要可爱配色、不要插画 - 品牌色: 主色 #15803D (低调深绿) + 次色 #0E7490 (青蓝), 不要蓝色系主色 变更概要 1. 全局地基 - theme.scss: Element Plus 主色改为 #15803D, slate 9 档, 联动组件库 - main.scss: 字体/页面骨架/筛选栏/表格/控件/滚动条 全套样式 - AdminLayout.vue: 政务顶栏 + 浅色侧栏 - Workbench.vue: 替换原绿底大字卡为 KPI 白底色条 + 快捷入口 + 进度条 2. 表格操作列改造 - el-button link 全面替换为 el-link (:underline="false" + type="primary/danger") - 36 文件 132 处替换, 操作列外加 .table-actions 容器 (内含分隔线) - 修复 el-link 不支持的属性 (size="small"/text/loading) 3. 筛选栏 - 弹性布局 + gap 14px 16px + align-items: flex-start + min-height 32px - 删除所有 scoped .filter-form 覆盖 (28 处) 让全局样式生效 - 控件宽度 180px 统一, 标签 32px 居中, 折行不紧贴 4. 表格紧凑化 - cell-padding 10px → 6px, 表头高度 36px - 行高 ~46px → ~36px, 字号 13px 5. 每页默认 20 条 - 21 文件 pageSize: 10 → 20 6. meetings 操作列折叠 - 11 操作 → 外置 3 个主操作 + 1 个"更多" el-dropdown (8 个次操作) - width 500px → 260px - 配 .op-dropdown / .op-caret 样式 (hover 旋转) - 新增 onMoreAction dispatch 函数 (复用原 handler) 7. 操作列文字防拆行 - .table-actions flex-wrap: nowrap + white-space: nowrap - el-link padding 0 8px → 0 6px, flex-shrink: 0 8. 环境配置 - .env.development: 直连远端 https://risingdoctor.com/hg-api (绕过 vite proxy 卡顿) - vite.config.js: proxy fallback 保留
This commit is contained in:
@@ -7,7 +7,10 @@
|
||||
>
|
||||
<div class="aside-logo">
|
||||
<div class="logo-icon"><img src="/logo.png" alt="logo" /></div>
|
||||
<div class="logo-text">{{ roleLabel }}</div>
|
||||
<div class="logo-text">
|
||||
<div class="logo-name">合规管理系统</div>
|
||||
<div class="logo-role">{{ roleLabel }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-menu :default-active="route.path" router class="aside-menu">
|
||||
<template v-for="m in menu" :key="m.path">
|
||||
@@ -31,26 +34,36 @@
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
<el-container>
|
||||
<el-header v-if="!route.meta?.hideMenu" class="topbar">
|
||||
<el-header v-if="!route.meta?.hideMenu" class="topbar" height="56px">
|
||||
<div class="topbar-left">
|
||||
<span class="page-title">{{ headerTitle }}</span>
|
||||
<el-icon class="topbar-back" @click="$router.back()"><ArrowLeft /></el-icon>
|
||||
<span class="page-title-inline">{{ headerTitle }}</span>
|
||||
</div>
|
||||
<div class="topbar-right">
|
||||
<el-button text @click="$router.push('/')">门户首页</el-button>
|
||||
<el-link :underline="false" class="topbar-portal" @click="$router.push('/')">
|
||||
<el-icon><HomeFilled /></el-icon>
|
||||
<span>门户首页</span>
|
||||
</el-link>
|
||||
<el-divider direction="vertical" />
|
||||
<!-- 消息入口 (admin/manager/doctor/sponsor/executor 各自路由, 通过 meta.noticePath 配置) -->
|
||||
<el-badge v-if="unreadCount > 0" :value="unreadCount" :max="99" class="notice-badge">
|
||||
<el-button text @click="goNotice">
|
||||
<el-button text class="topbar-icon-btn" @click="goNotice">
|
||||
<el-icon><Bell /></el-icon>
|
||||
</el-button>
|
||||
</el-badge>
|
||||
<el-button v-else text @click="goNotice">
|
||||
<el-button v-else text class="topbar-icon-btn" @click="goNotice">
|
||||
<el-icon><Bell /></el-icon>
|
||||
</el-button>
|
||||
<el-dropdown trigger="click" @command="onCommand">
|
||||
<span class="user-name">{{ store.user?.userName || store.user?.displayName }}<el-icon><CaretBottom /></el-icon></span>
|
||||
<span class="user-name">
|
||||
<el-icon class="user-icon"><UserFilled /></el-icon>
|
||||
<span>{{ store.user?.userName || store.user?.displayName }}</span>
|
||||
<el-icon class="caret"><CaretBottom /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
|
||||
<el-dropdown-item command="account" @click="$router.push('/' + (role || 'admin') + '/account')">账号信息</el-dropdown-item>
|
||||
<el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@@ -73,7 +86,7 @@ import { listMyMessages } from '@/api/public'
|
||||
import { usePageTitle } from '@/utils/pageTitle'
|
||||
import { getMyExpertProfile } from '@/api/business/expert'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import { House, Document, Calendar, User, List, OfficeBuilding, Setting, Bell, EditPen, DataAnalysis, Tickets, CaretBottom, Folder, Medal, UserFilled, Connection, Box, Star, Grid, Files, Compass, Collection } from '@element-plus/icons-vue'
|
||||
import { House, Document, Calendar, User, List, OfficeBuilding, Setting, Bell, EditPen, DataAnalysis, Tickets, CaretBottom, Folder, Medal, UserFilled, Connection, Box, Star, Grid, Files, Compass, Collection, ArrowLeft, HomeFilled } from '@element-plus/icons-vue'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -241,73 +254,154 @@ const onCommand = (cmd) => { if (cmd === 'logout') logout() }
|
||||
|
||||
<style scoped>
|
||||
.admin-layout { height: 100vh; }
|
||||
.aside { background: #001529; color: #fff; }
|
||||
.aside-logo {
|
||||
padding: 20px 16px 16px;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid var(--brand-primary-darker);
|
||||
|
||||
/* —— 侧边栏:浅色政务风(避免深绿主色冲突, 政务网站通用样式) —— */
|
||||
.aside {
|
||||
background: #FFFFFF;
|
||||
border-right: 1px solid var(--brand-slate-200);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.aside-logo {
|
||||
padding: 18px 16px 16px;
|
||||
border-bottom: 1px solid var(--brand-slate-200);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
gap: 12px;
|
||||
background: linear-gradient(180deg, var(--brand-primary-mix) 0%, #FFFFFF 100%);
|
||||
}
|
||||
.logo-icon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 8px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
border: 1px solid var(--brand-slate-200);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.logo-icon img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
.logo-text { color: #fff; font-size: 14px; font-weight: 600; }
|
||||
.aside-menu { background: #001529; border: none; }
|
||||
.logo-icon img { width: 100%; height: 100%; object-fit: contain; display: block; }
|
||||
.logo-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
||||
.logo-name { color: var(--el-text-color-primary); font-size: 15px; font-weight: 600; white-space: nowrap; }
|
||||
.logo-role { color: var(--el-text-color-secondary); font-size: 12px; white-space: nowrap; }
|
||||
|
||||
/* 一级菜单 + 二级父标题: 统一默认/hover/active 样式 */
|
||||
.aside-menu { background: transparent; border: none; flex: 1; }
|
||||
|
||||
/* 一级菜单 + 二级父标题: 中性灰文字, hover 浅绿, active 实心绿 */
|
||||
:deep(.el-menu-item),
|
||||
:deep(.el-sub-menu__title) {
|
||||
color: #c0c4cc;
|
||||
color: var(--el-text-color-regular);
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
}
|
||||
:deep(.el-menu-item .el-icon),
|
||||
:deep(.el-sub-menu__title .el-icon) {
|
||||
color: var(--brand-slate-500);
|
||||
}
|
||||
:deep(.el-menu-item:hover),
|
||||
:deep(.el-sub-menu__title:hover) {
|
||||
background-color: #1f3a5f;
|
||||
color: #fff;
|
||||
background-color: var(--brand-primary-mix);
|
||||
color: var(--brand-primary);
|
||||
}
|
||||
/* 子项激活: 蓝底白字 */
|
||||
:deep(.el-menu-item:hover .el-icon),
|
||||
:deep(.el-sub-menu__title:hover .el-icon) { color: var(--brand-primary); }
|
||||
|
||||
/* 选中态: 政务感 — 实心绿底白字 + 左侧 4px 高亮条 */
|
||||
:deep(.el-menu-item.is-active) {
|
||||
background: var(--brand-primary);
|
||||
color: #fff;
|
||||
color: #FFFFFF;
|
||||
position: relative;
|
||||
}
|
||||
:deep(.el-menu-item.is-active .el-icon) { color: #FFFFFF; }
|
||||
:deep(.el-menu-item.is-active::before) {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0; top: 0; bottom: 0;
|
||||
width: 4px;
|
||||
background: var(--brand-primary-darker);
|
||||
}
|
||||
/* 父标题在子项激活时高亮 (Element Plus 自动给 el-sub-menu 加 is-active) */
|
||||
:deep(.el-sub-menu.is-active > .el-sub-menu__title) {
|
||||
color: #fff;
|
||||
color: var(--brand-primary);
|
||||
}
|
||||
:deep(.el-sub-menu.is-active > .el-sub-menu__title .el-icon) {
|
||||
color: var(--brand-primary);
|
||||
}
|
||||
|
||||
/* 二级菜单容器: 跟随侧边栏深蓝底, 不要 Element Plus 默认白底 */
|
||||
:deep(.el-menu--inline),
|
||||
:deep(.el-menu--inline .el-menu-item) {
|
||||
background-color: #001529;
|
||||
/* 二级菜单缩进 */
|
||||
:deep(.el-menu .el-menu .el-menu-item) {
|
||||
padding-left: 48px !important;
|
||||
background-color: var(--brand-slate-50);
|
||||
}
|
||||
:deep(.el-menu--inline .el-menu-item:hover) {
|
||||
background-color: #1f3a5f;
|
||||
:deep(.el-menu .el-menu .el-menu-item:hover) {
|
||||
background-color: var(--brand-primary-mix);
|
||||
}
|
||||
:deep(.el-menu--inline .el-menu-item.is-active) {
|
||||
:deep(.el-menu .el-menu .el-menu-item.is-active) {
|
||||
background: var(--brand-primary);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.topbar { background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; border-bottom: 1px solid #ebeef5; }
|
||||
.topbar-left { display: flex; align-items: center; }
|
||||
.page-title { font-size: 16px; font-weight: 600; }
|
||||
.topbar-right { display: flex; align-items: center; gap: 12px; }
|
||||
.user-name { cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }
|
||||
/* navbar bell 角标: 紧凑, 不撑大 topbar */
|
||||
:deep(.el-menu .el-menu .el-menu-item.is-active .el-icon) { color: #FFFFFF; }
|
||||
|
||||
/* 顶栏:白底 + 边框 */
|
||||
.topbar {
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 24px;
|
||||
border-bottom: 1px solid var(--brand-slate-200);
|
||||
height: 56px;
|
||||
}
|
||||
.topbar-left { display: flex; align-items: center; gap: 8px; }
|
||||
.topbar-back {
|
||||
font-size: 18px;
|
||||
color: var(--el-text-color-secondary);
|
||||
cursor: pointer;
|
||||
padding: 6px;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.18s, color 0.18s;
|
||||
}
|
||||
.topbar-back:hover { background: var(--brand-slate-100); color: var(--brand-primary); }
|
||||
.page-title-inline {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
.topbar-right { display: flex; align-items: center; gap: 4px; }
|
||||
.topbar-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: var(--el-text-color-regular);
|
||||
font-size: 13px;
|
||||
}
|
||||
.topbar-link:hover { color: var(--brand-primary); }
|
||||
.topbar-icon-btn {
|
||||
font-size: 18px;
|
||||
color: var(--el-text-color-regular);
|
||||
padding: 6px;
|
||||
}
|
||||
.topbar-icon-btn:hover { color: var(--brand-primary); }
|
||||
.user-name {
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0 8px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: var(--el-text-color-regular);
|
||||
transition: background-color 0.18s;
|
||||
}
|
||||
.user-name:hover { background: var(--brand-slate-100); color: var(--brand-primary); }
|
||||
.user-name .user-icon { font-size: 16px; color: var(--brand-slate-500); }
|
||||
.user-name .caret { font-size: 12px; color: var(--brand-slate-400); }
|
||||
.notice-badge :deep(.el-badge__content) { transform: translate(50%, -10%); }
|
||||
.main { background: #f5f7fa; padding: 16px; }
|
||||
|
||||
/* 主体: 浅灰底 + 卡片自动吸附 */
|
||||
.main { background: var(--brand-slate-50); padding: 16px 20px; min-height: calc(100vh - 56px); }
|
||||
/* 手机页面 (hideMenu): 白底 + 0 padding, 让 form 直接撑满 */
|
||||
.main-full { background: #fff; padding: 0; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user