diff --git a/clinical-web/README.md b/clinical-web/README.md index 025ec79..012eac8 100644 --- a/clinical-web/README.md +++ b/clinical-web/README.md @@ -96,19 +96,17 @@ TanStack Vue Query、PDF 预览、报表图表、自动化测试和签字板适 ClinicalLayout ├─ 工作台 -│ ├─ /workbench/home 首页总览 -│ ├─ /workbench/signing 签署工作台 -│ ├─ /management/documents 文档库管理 -│ └─ /management/reports 报表分析 +│ ├─ /workbench/home 首页 +│ └─ /workbench/signing 签署工作台 └─ 管理 + ├─ /management/documents 文档库管理 + ├─ /management/reports 报表分析 ├─ /management/users 用户与权限 ├─ /management/document-permissions 文档权限 └─ /management/settings 系统设置 ``` -菜单分组按原型呈现,与路由 path 前缀不完全对应:文档库管理和报表分析归入侧边栏「工作台」分栏,但路径仍保留在 `/management` 下。 - -布局拆分为 `Menu`、`Header` 和 `Container` 三个公共组件,页面内容由各自的 View 负责;侧边栏与顶栏共用 `components/layout/AppIcon.vue` 提供图标。 +布局拆分为 `Menu`、`Header` 和 `Container` 三个公共组件,页面内容由各自的 View 负责。 页面目录按业务域组织:`auth` 保留登录页;工作台页面位于 `views/workbench`;管理页面位于 `views/management`。每个具体页面目录都有 `index.vue` 入口和 `components` 目录,用于继续拆分当前页面组件。 diff --git a/clinical-web/src/components/layout/AppIcon.vue b/clinical-web/src/components/layout/AppIcon.vue deleted file mode 100644 index 24613eb..0000000 --- a/clinical-web/src/components/layout/AppIcon.vue +++ /dev/null @@ -1,125 +0,0 @@ - - - - - diff --git a/clinical-web/src/components/layout/Container.vue b/clinical-web/src/components/layout/Container.vue index 132a034..57e9849 100644 --- a/clinical-web/src/components/layout/Container.vue +++ b/clinical-web/src/components/layout/Container.vue @@ -8,13 +8,13 @@ .clinical-container { flex: 1; min-height: 0; - padding: 18px 30px; + padding: 18px 20px; overflow-y: auto; } @media (max-width: 1200px) { .clinical-container { - padding: 16px 20px; + padding: 16px; } } diff --git a/clinical-web/src/components/layout/Header.vue b/clinical-web/src/components/layout/Header.vue index 8268c31..6a46b16 100644 --- a/clinical-web/src/components/layout/Header.vue +++ b/clinical-web/src/components/layout/Header.vue @@ -1,9 +1,7 @@ @@ -170,237 +123,152 @@ onBeforeUnmount(() => { flex: 0 0 var(--sidebar-width); flex-direction: column; width: var(--sidebar-width); - padding: 21px 13px 14px; - color: #d8edf3; - background: linear-gradient(#0b455a 0%, #072e3e 100%); - box-shadow: 8px 0 32px rgb(5 37 49 / 7%); + color: #c8dde6; + background: var(--side); } -.brand-lockup { +.menu-brand { display: flex; flex-shrink: 0; - gap: 11px; + gap: 10px; align-items: center; - padding: 0 8px 20px; - border-bottom: 1px solid rgb(255 255 255 / 9%); + padding: 18px 16px 16px; + border-bottom: 1px solid rgb(255 255 255 / 8%); } -.brand-mark { +.menu-brand-icon { display: grid; flex-shrink: 0; - width: 40px; - height: 40px; - color: #fff; + width: 34px; + height: 34px; place-items: center; - background: linear-gradient(145deg, #0f7590, #18a6a6); - border: 1px solid rgb(255 255 255 / 20%); - border-radius: 11px; - box-shadow: 0 8px 20px rgb(0 21 31 / 33%); + border-radius: 9px; + background: linear-gradient(135deg, #18a0c0, var(--brand)); } -.brand-mark-icon { - width: 22px; - height: 22px; -} - -.brand-copy { - min-width: 0; -} - -.brand-copy strong { +.menu-brand-copy strong, +.menu-brand-copy span { display: block; +} + +.menu-brand-copy strong { color: #fff; - font-size: 18px; - letter-spacing: 0.08em; + font-size: 16px; + letter-spacing: 1px; } -.brand-copy small { - display: block; - margin-top: 2px; - color: #8fb7c4; - font-size: 9px; - letter-spacing: 0.1em; -} - -.menu-scroll { - flex: 1; - min-height: 0; - overflow-y: auto; -} - -.nav-caption { - margin: 0; - padding: 17px 12px 6px; - color: #759ba8; +.menu-brand-copy span { + color: #8fb3c2; font-size: 10px; - letter-spacing: 0.1em; + letter-spacing: 1px; } .menu-nav { - display: grid; - gap: 4px; + flex: 1; + padding: 12px 10px; + overflow-y: auto; } -.nav-item { - position: relative; +.menu-group-title { + padding: 10px 10px 6px; + color: #7ba2b3; + font-size: 11px; + letter-spacing: 1px; +} + +.menu-item { display: flex; - gap: 11px; + gap: 10px; align-items: center; - height: 42px; - padding: 0 12px; - color: #bcd3db; - font-size: 14px; - text-align: left; + margin-bottom: 2px; + padding: 10px 12px; + color: #c8dde6; + font-size: 13.5px; text-decoration: none; - border-radius: 10px; - transition: all 0.22s; + border-radius: 8px; + transition: + color 0.15s ease, + background 0.15s ease; } -.nav-item:hover { +.menu-item:hover { color: #fff; - background: rgb(255 255 255 / 5%); - transform: translateX(2px); + background: rgb(255 255 255 / 7%); } -.nav-item.is-active { +.menu-item.is-active { color: #fff; - background: linear-gradient(90deg, #137f98, #0f6a82); - box-shadow: 0 8px 20px rgb(0 20 30 / 25%); + font-weight: 700; + background: var(--brand); } -.nav-item.is-active::before { - position: absolute; - left: -13px; - width: 3px; - height: 22px; - background: #65d9d0; - border-radius: 0 3px 3px 0; - content: ''; -} - -.nav-icon { - width: 17px; - height: 17px; -} - -.nav-label { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.connection { - display: flex; - flex-shrink: 0; - gap: 7px; - align-items: center; - min-width: 0; - margin: auto 0 12px 8px; - color: #79a8b5; - font-size: 9px; -} - -.connection i { +.menu-dot { flex-shrink: 0; width: 6px; height: 6px; - background: #45d4a5; + background: transparent; border-radius: 50%; - box-shadow: 0 0 0 4px rgb(69 212 165 / 11%); } -.connection span { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; +.menu-item.is-active .menu-dot { + background: #5ee0a8; } -.menu-user { - position: relative; - flex-shrink: 0; -} - -.user-card { +.menu-profile { display: flex; - gap: 9px; + flex-shrink: 0; + gap: 10px; align-items: center; - width: 100%; - padding: 10px 9px; - color: inherit; - text-align: left; - background: rgb(255 255 255 / 3%); - border: 1px solid rgb(255 255 255 / 7%); - border-radius: 11px; - transition: all 0.2s; + padding: 14px 16px; + border-top: 1px solid rgb(255 255 255 / 8%); } -.user-card:hover { - background: rgb(255 255 255 / 6%); -} - -.user-avatar { +.menu-profile-avatar { display: grid; flex-shrink: 0; width: 34px; height: 34px; color: #fff; + font-size: 14px; font-weight: 700; place-items: center; - background: #18a5a6; border-radius: 50%; + background: #18a0c0; } -.user-copy { +.menu-profile-copy { min-width: 0; } -.user-copy strong { - display: block; - color: #fff; - font-size: 12px; -} - -.user-copy small { +.menu-profile-copy strong, +.menu-profile-copy span { display: block; overflow: hidden; - margin-top: 2px; - color: #8fb7c4; - font-size: 9px; - letter-spacing: 0.1em; text-overflow: ellipsis; white-space: nowrap; } -.user-more { +.menu-profile-copy strong { + color: #fff; + font-size: 13px; +} + +.menu-profile-copy span { + margin-top: 2px; + color: #8fb3c2; + font-size: 11px; +} + +.menu-logout { flex-shrink: 0; - width: 15px; - height: 15px; margin-left: auto; - color: #78a0ac; -} - -.user-pop { - position: absolute; - right: 0; - bottom: calc(100% + 8px); - left: 0; - padding: 6px; - background: #fff; - border-radius: 11px; - box-shadow: 0 18px 45px rgb(3 25 34 / 45%); -} - -.user-pop button { - width: 100%; - padding: 9px 10px; - color: #25505f; - font-size: 12px; - text-align: left; + padding: 0; + color: #8fb3c2; + font-size: 11px; background: transparent; - border-radius: 8px; } -.user-pop button:hover { - background: #eef6f8; +.menu-logout:hover { + color: #fff; } diff --git a/clinical-web/src/router/index.ts b/clinical-web/src/router/index.ts index af536bb..889bfff 100644 --- a/clinical-web/src/router/index.ts +++ b/clinical-web/src/router/index.ts @@ -36,7 +36,7 @@ const router = createRouter({ path: 'home', name: 'workbench-home', component: DashboardView, - meta: { title: '首页总览', group: '工作台' }, + meta: { title: '首页', group: '工作台' }, }, { path: 'signing', diff --git a/clinical-web/src/styles/theme.css b/clinical-web/src/styles/theme.css index 8a123e8..2dd1283 100644 --- a/clinical-web/src/styles/theme.css +++ b/clinical-web/src/styles/theme.css @@ -26,6 +26,6 @@ --font-sans: 'Microsoft YaHei', 'PingFang SC', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; - --sidebar-width: 220px; - --header-height: 72px; + --sidebar-width: 200px; + --header-height: 54px; }