更新
This commit is contained in:
+2
-2
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>后台管理系统</title>
|
||||
<title>中医问诊管理后台</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
@@ -29,7 +29,7 @@
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke: #0EA5E9;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
|
||||
+15
-12
@@ -1,28 +1,31 @@
|
||||
const defaultSetting = {
|
||||
showCrumb: true, // 是否显示面包屑
|
||||
showLogo: false, // 是否显示logo
|
||||
showLogo: true, // 是否显示logo
|
||||
isUniqueOpened: true, //只展开一个一级菜单
|
||||
sideWidth: 183, //侧边栏宽度
|
||||
sideTheme: 'dark', //侧边栏主题
|
||||
sideDarkColor: '#1d2124', //侧边栏深色主题颜色
|
||||
sideWidth: 200, //侧边栏宽度
|
||||
sideTheme: 'light', //侧边栏主题
|
||||
sideDarkColor: '#0369A1', //侧边栏深色主题颜色(深天蓝)
|
||||
openMultipleTabs: true, // 是否开启多标签tab栏
|
||||
theme: '#4A5DFF', //主题色
|
||||
successTheme: '#67c23a', //成功主题色
|
||||
warningTheme: '#e6a23c', //警告主题色
|
||||
dangerTheme: '#f56c6c', //危险主题色
|
||||
errorTheme: '#f56c6c', //错误主题色
|
||||
infoTheme: '#909399' //信息主题色
|
||||
theme: '#0EA5E9', //主题色(天蓝)
|
||||
successTheme: '#16A34A', //成功主题色
|
||||
warningTheme: '#D97706', //警告主题色
|
||||
dangerTheme: '#DC2626', //危险主题色
|
||||
errorTheme: '#DC2626', //错误主题色
|
||||
infoTheme: '#64748B' //信息主题色
|
||||
}
|
||||
|
||||
/** 本地 setting 缓存结构版本。提升后仅对低于该版本的老缓存执行 SETTING_SCHEMA_MIGRATIONS */
|
||||
export const SETTING_SCHEMA_VERSION = 1
|
||||
export const SETTING_SCHEMA_VERSION = 4
|
||||
|
||||
/**
|
||||
* 按版本写入 defaultSetting 中的键(老用户 localStorage 会长期盖住 config 默认值)。
|
||||
* 以后若要再推一批新默认值:把 SETTING_SCHEMA_VERSION +1,并为本版本追加一条迁移键列表。
|
||||
*/
|
||||
export const SETTING_SCHEMA_MIGRATIONS: Record<number, (keyof typeof defaultSetting)[]> = {
|
||||
1: ['sideTheme', 'sideDarkColor']
|
||||
1: ['sideTheme', 'sideDarkColor'],
|
||||
2: ['theme', 'successTheme', 'warningTheme', 'dangerTheme', 'errorTheme', 'infoTheme', 'sideTheme', 'sideDarkColor', 'showLogo', 'sideWidth'],
|
||||
3: ['theme', 'sideTheme', 'sideDarkColor', 'sideWidth'],
|
||||
4: ['theme', 'sideDarkColor']
|
||||
}
|
||||
|
||||
export default defaultSetting
|
||||
|
||||
@@ -26,17 +26,19 @@ useWatchRoute((route) => {
|
||||
.app-breadcrumb {
|
||||
:deep(.el-breadcrumb__item) {
|
||||
.el-breadcrumb__inner {
|
||||
color: #303133;
|
||||
color: var(--el-text-color-regular);
|
||||
font-weight: 400;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
&:last-child .el-breadcrumb__inner {
|
||||
color: var(--health-primary-dark, var(--el-color-primary));
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&:last-child .el-breadcrumb__inner {
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
:deep(.el-breadcrumb__separator) {
|
||||
color: #606266;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
<template>
|
||||
<header class="header">
|
||||
<div class="navbar">
|
||||
<div class="flex-1 flex">
|
||||
<div class="navbar-item">
|
||||
<div class="navbar-left flex-1 flex items-center min-w-0">
|
||||
<side-logo
|
||||
v-if="settingStore.showLogo"
|
||||
class="navbar-logo shrink-0"
|
||||
:show-title="!isCollapsed || isMobile"
|
||||
theme="light"
|
||||
/>
|
||||
<div class="navbar-item shrink-0">
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
@@ -12,16 +18,19 @@
|
||||
<fold />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="navbar-item">
|
||||
<div class="navbar-item shrink-0">
|
||||
<el-tooltip class="box-item" effect="dark" content="刷新" placement="bottom">
|
||||
<refresh />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="flex items-center px-2" v-if="!isMobile && settingStore.showCrumb">
|
||||
<div
|
||||
class="flex items-center px-2 min-w-0"
|
||||
v-if="!isMobile && settingStore.showCrumb"
|
||||
>
|
||||
<breadcrumb />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<div class="navbar-right flex shrink-0">
|
||||
<div class="navbar-item" v-if="!isMobile">
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
@@ -47,7 +56,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<multiple-tabs v-if="settingStore.openMultipleTabs" />
|
||||
</header>
|
||||
</template>
|
||||
|
||||
@@ -57,11 +65,11 @@ import { useFullscreen } from '@vueuse/core'
|
||||
import useAppStore from '@/stores/modules/app'
|
||||
import useSettingStore from '@/stores/modules/setting'
|
||||
|
||||
import SideLogo from '../sidebar/logo.vue'
|
||||
import Setting from '../setting/index.vue'
|
||||
import Breadcrumb from './breadcrumb.vue'
|
||||
import Fold from './fold.vue'
|
||||
import FullScreen from './full-screen.vue'
|
||||
import MultipleTabs from './multiple-tabs.vue'
|
||||
import Refresh from './refresh.vue'
|
||||
import UserDropDown from './user-drop-down.vue'
|
||||
|
||||
@@ -73,11 +81,31 @@ const { isFullscreen } = useFullscreen()
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.header {
|
||||
background: var(--el-bg-color);
|
||||
border-bottom: 1px solid var(--health-border, var(--el-border-color-lighter));
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
|
||||
}
|
||||
|
||||
.navbar {
|
||||
height: var(--navbar-height);
|
||||
@apply flex px-2 bg-body;
|
||||
@apply flex px-4;
|
||||
|
||||
.navbar-logo {
|
||||
margin-right: 4px;
|
||||
border-bottom: none !important;
|
||||
padding-right: 8px !important;
|
||||
}
|
||||
|
||||
.navbar-item {
|
||||
@apply h-full flex justify-center items-center hover:bg-page;
|
||||
@apply h-10 flex justify-center items-center cursor-pointer;
|
||||
min-width: 40px;
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-fill-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="app-tabs pl-4 flex bg-body">
|
||||
<div class="app-tabs flex bg-body">
|
||||
<div class="flex-1 min-w-0">
|
||||
<el-tabs
|
||||
:model-value="currentTab"
|
||||
@@ -13,7 +13,7 @@
|
||||
</el-tabs>
|
||||
</div>
|
||||
<el-dropdown @command="handleCommand">
|
||||
<span class="flex items-center px-3">
|
||||
<span class="flex items-center px-3 cursor-pointer tab-dropdown">
|
||||
<icon :size="16" name="el-icon-arrow-down" />
|
||||
</span>
|
||||
<template #dropdown>
|
||||
@@ -58,9 +58,22 @@ const handleCommand = (command: any) => {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-tabs {
|
||||
@apply border-t border-br;
|
||||
padding: 0 16px;
|
||||
background: var(--el-bg-color);
|
||||
border-bottom: 1px solid var(--health-border, var(--el-border-color-lighter));
|
||||
|
||||
.tab-dropdown {
|
||||
height: 40px;
|
||||
border-radius: 6px;
|
||||
transition: background-color 0.2s ease;
|
||||
&:hover {
|
||||
background-color: var(--el-fill-color);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-tabs) {
|
||||
height: 40px;
|
||||
.el-tabs {
|
||||
@@ -80,35 +93,19 @@ const handleCommand = (command: any) => {
|
||||
}
|
||||
&__item {
|
||||
font-weight: normal;
|
||||
padding: 0 15px !important;
|
||||
padding: 0 16px !important;
|
||||
box-sizing: border-box;
|
||||
color: var(--el-text-color-secondary);
|
||||
transition: color 0.2s ease;
|
||||
&.is-active {
|
||||
color: var(--el-text-color-primary);
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: var(--el-color-primary);
|
||||
margin-right: 6px;
|
||||
border-radius: 50%;
|
||||
vertical-align: 2px;
|
||||
}
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
display: block;
|
||||
top: 0;
|
||||
height: 2px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: var(--el-color-primary);
|
||||
}
|
||||
color: var(--health-primary-dark, var(--el-color-primary));
|
||||
font-weight: 500;
|
||||
}
|
||||
.is-icon-close {
|
||||
color: var(--el-text-color-regular);
|
||||
color: var(--el-text-color-secondary);
|
||||
vertical-align: -2px;
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s ease;
|
||||
&:hover {
|
||||
color: var(--color-white);
|
||||
background-color: var(--el-color-danger);
|
||||
@@ -116,7 +113,9 @@ const handleCommand = (command: any) => {
|
||||
}
|
||||
}
|
||||
&__active-bar {
|
||||
display: none;
|
||||
height: 2px;
|
||||
border-radius: 2px;
|
||||
background-color: var(--health-primary, var(--el-color-primary));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<main class="main-wrap h-full bg-page">
|
||||
<main class="main-wrap h-full">
|
||||
<el-scrollbar>
|
||||
<div class="px-2 py-4">
|
||||
<div class="main-content">
|
||||
<router-view v-if="isRouteShow" v-slot="{ Component, route }">
|
||||
<keep-alive :include="includeList" :max="20">
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
@@ -24,4 +24,14 @@ const isRouteShow = computed(() => appStore.isRouteShow)
|
||||
const includeList = computed(() => (settingStore.openMultipleTabs ? tabsStore.getCacheTabList : []))
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
<style lang="scss" scoped>
|
||||
.main-wrap {
|
||||
height: 100%;
|
||||
background: var(--el-bg-color);
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 16px 20px 24px;
|
||||
min-height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -100,7 +100,7 @@ import theme_light from '@/assets/images/theme_white.png'
|
||||
import useSettingStore from '@/stores/modules/setting'
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
const predefineColors = ref(['#409EFF', '#28C76F', '#EA5455', '#FF9F43', '#01CFE8', '#4A5DFF'])
|
||||
const predefineColors = ref(['#0EA5E9', '#38BDF8', '#0284C7', '#16A34A', '#DC2626', '#0369A1'])
|
||||
const sideThemeList = [
|
||||
{
|
||||
type: 'dark',
|
||||
|
||||
@@ -44,11 +44,13 @@ const handleClick = () => {
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
@apply flex items-center p-2 relative;
|
||||
@apply flex items-center px-3 relative;
|
||||
|
||||
.logo-title {
|
||||
width: 70%;
|
||||
position: absolute;
|
||||
@apply text-xl;
|
||||
@apply text-base font-medium;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.title-width-enter-active {
|
||||
|
||||
@@ -67,33 +67,53 @@ const themeClass = computed(() => `theme-${props.theme}`)
|
||||
&.theme-dark {
|
||||
.el-menu {
|
||||
:deep(.el-menu-item) {
|
||||
margin: 2px 10px;
|
||||
border-radius: 6px;
|
||||
&.is-active {
|
||||
@apply bg-primary border-primary;
|
||||
background-color: rgba(255, 255, 255, 0.12);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
:deep(.el-sub-menu__title) {
|
||||
margin: 2px 10px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
:deep(.el-menu--collapse) {
|
||||
.el-sub-menu.is-active .el-sub-menu__title {
|
||||
@apply bg-primary #{!important};
|
||||
background-color: rgba(255, 255, 255, 0.12) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.theme-light {
|
||||
:deep(.el-menu) {
|
||||
.el-menu-item {
|
||||
border-color: transparent;
|
||||
margin: 2px 10px;
|
||||
border-radius: 6px;
|
||||
color: var(--el-text-color-regular);
|
||||
&.is-active {
|
||||
@apply bg-primary-light-9 border-r-2 border-primary;
|
||||
background-color: var(--health-primary-light, var(--el-color-primary-light-9));
|
||||
color: var(--health-primary-dark, var(--el-color-primary));
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.el-sub-menu__title {
|
||||
margin: 2px 10px;
|
||||
border-radius: 6px;
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
.el-menu-item:hover,
|
||||
.el-sub-menu__title:hover {
|
||||
color: var(--el-color-primary);
|
||||
background-color: var(--el-fill-color);
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-menu {
|
||||
border-right: none;
|
||||
background: transparent;
|
||||
padding: 10px 0;
|
||||
&:not(.el-menu--collapse) {
|
||||
width: var(--aside-width);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<div class="side" :style="sideStyle">
|
||||
<side-logo v-if="settingStore.showLogo" :show-title="!isCollapsed" :theme="sideTheme" />
|
||||
<side-logo
|
||||
v-if="settingStore.showLogo && appStore.isMobile"
|
||||
:show-title="!isCollapsed"
|
||||
:theme="sideTheme"
|
||||
/>
|
||||
<side-menu
|
||||
:routes="routes"
|
||||
:is-collapsed="isCollapsed"
|
||||
@@ -45,9 +49,9 @@ const sideStyle = computed(() => {
|
||||
})
|
||||
const menuProp = computed(() => {
|
||||
return {
|
||||
backgroundColor: sideTheme.value == 'dark' ? settingStore.sideDarkColor : '',
|
||||
textColor: sideTheme.value == 'dark' ? 'var(--el-color-white)' : '',
|
||||
activeTextColor: sideTheme.value == 'dark' ? 'var(--el-color-white)' : ''
|
||||
backgroundColor: sideTheme.value == 'dark' ? settingStore.sideDarkColor : 'transparent',
|
||||
textColor: sideTheme.value == 'dark' ? 'rgba(255,255,255,0.85)' : '',
|
||||
activeTextColor: sideTheme.value == 'dark' ? '#ffffff' : ''
|
||||
}
|
||||
})
|
||||
const handleSelect = () => {
|
||||
@@ -60,8 +64,8 @@ const handleSelect = () => {
|
||||
<style lang="scss" scoped>
|
||||
.side {
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
@apply border-r border-br-light h-full flex flex-col;
|
||||
background-color: var(--side-dark-color, var(--el-bg-color));
|
||||
z-index: 10;
|
||||
@apply h-full flex flex-col;
|
||||
background-color: var(--side-dark-color, var(--health-bg-sidebar, var(--el-bg-color)));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,23 +1,42 @@
|
||||
<template>
|
||||
<div class="layout-default flex h-screen w-full">
|
||||
<!-- shrink-0:避免主内容区(宽表格/图表)把侧栏压缩到折叠宽度 -->
|
||||
<div class="app-aside shrink-0">
|
||||
<layout-sidebar />
|
||||
<div class="layout-default flex flex-col h-screen w-full bg-page">
|
||||
<div class="app-header shrink-0">
|
||||
<layout-header />
|
||||
</div>
|
||||
|
||||
<div class="flex-1 flex flex-col min-w-0">
|
||||
<div class="app-header">
|
||||
<layout-header />
|
||||
<div class="layout-body flex flex-1 min-h-0">
|
||||
<div class="app-aside shrink-0">
|
||||
<layout-sidebar />
|
||||
</div>
|
||||
<div class="app-main flex-1 min-h-0">
|
||||
<layout-main />
|
||||
|
||||
<div class="app-content flex flex-1 flex-col min-w-0 bg-body">
|
||||
<multiple-tabs v-if="settingStore.openMultipleTabs" />
|
||||
<div class="app-main flex-1 min-h-0">
|
||||
<layout-main />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import useSettingStore from '@/stores/modules/setting'
|
||||
|
||||
import LayoutHeader from './components/header/index.vue'
|
||||
import MultipleTabs from './components/header/multiple-tabs.vue'
|
||||
import LayoutMain from './components/main.vue'
|
||||
import LayoutSidebar from './components/sidebar/index.vue'
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.layout-body {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.app-content {
|
||||
border-left: 1px solid var(--health-border, var(--el-border-color-lighter));
|
||||
}
|
||||
</style>
|
||||
|
||||
+34
-31
@@ -1,43 +1,46 @@
|
||||
:root.dark {
|
||||
color-scheme: dark;
|
||||
--table-header-bg-color: var(--el-bg-color);
|
||||
--el-bg-color-page: #0a0a0a;
|
||||
--el-bg-color: #1d2124;
|
||||
--el-bg-color-overlay: #1d1e1f;
|
||||
--el-text-color-primary: #e5eaf3;
|
||||
--el-text-color-regular: #cfd3dc;
|
||||
--el-text-color-secondary: #a3a6ad;
|
||||
--el-text-color-placeholder: #8d9095;
|
||||
--el-text-color-disabled: #6c6e72;
|
||||
--el-border-color-darker: #636466;
|
||||
--el-border-color-dark: #58585b;
|
||||
--el-border-color: #4c4d4f;
|
||||
--el-border-color-light: #414243;
|
||||
--el-border-color-lighter: #363637;
|
||||
--el-border-color-extra-light: #2b2b2c;
|
||||
--el-fill-color-darker: #424243;
|
||||
--el-fill-color-dark: #39393a;
|
||||
--el-fill-color: #303030;
|
||||
--el-fill-color-light: #262727;
|
||||
--el-fill-color-lighter: #1d1d1d;
|
||||
--el-fill-color-extra-light: #191919;
|
||||
--table-header-bg-color: #1E293B;
|
||||
--health-bg-page: #0F1419;
|
||||
--health-bg-sidebar: #151B23;
|
||||
--health-text-primary: #F1F5F9;
|
||||
--health-text-secondary: #94A3B8;
|
||||
--health-border: #334155;
|
||||
--health-border-light: #1E293B;
|
||||
--health-primary-light: rgba(14, 165, 233, 0.15);
|
||||
--el-bg-color-page: var(--health-bg-page);
|
||||
--el-bg-color: #151B23;
|
||||
--el-bg-color-overlay: #1E293B;
|
||||
--el-text-color-primary: var(--health-text-primary);
|
||||
--el-text-color-regular: #CBD5E1;
|
||||
--el-text-color-secondary: #94A3B8;
|
||||
--el-text-color-placeholder: #64748B;
|
||||
--el-text-color-disabled: #475569;
|
||||
--el-border-color-darker: #475569;
|
||||
--el-border-color-dark: #334155;
|
||||
--el-border-color: #334155;
|
||||
--el-border-color-light: #334155;
|
||||
--el-border-color-lighter: #1E293B;
|
||||
--el-border-color-extra-light: #151B23;
|
||||
--el-fill-color-darker: #334155;
|
||||
--el-fill-color-dark: #1E293B;
|
||||
--el-fill-color: #1E293B;
|
||||
--el-fill-color-light: #151B23;
|
||||
--el-fill-color-lighter: #0F1419;
|
||||
--el-fill-color-extra-light: #1E293B;
|
||||
--el-fill-color-blank: var(--el-bg-color);
|
||||
--el-mask-color: rgba(0, 0, 0, 0.8);
|
||||
--el-mask-color-extra-light: rgba(0, 0, 0, 0.3);
|
||||
--el-box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, 0.36), 0px 8px 20px rgba(0, 0, 0, 0.72);
|
||||
--el-box-shadow-light: 0px 0px 12px rgba(0, 0, 0, 0.72);
|
||||
--el-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, 0.72);
|
||||
--el-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, 0.72), 0px 12px 32px #000000,
|
||||
0px 8px 16px -8px #000000 !important;
|
||||
/* wangeditor主题 */
|
||||
--el-mask-color: rgba(0, 0, 0, 0.72);
|
||||
--el-mask-color-extra-light: rgba(0, 0, 0, 0.36);
|
||||
--el-box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
--el-box-shadow-light: 0 1px 4px rgba(0, 0, 0, 0.25);
|
||||
--el-box-shadow-lighter: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
--el-box-shadow-dark: 0 4px 16px rgba(0, 0, 0, 0.4);
|
||||
--w-e-textarea-bg-color: var(--el-bg-color);
|
||||
--w-e-textarea-color: var(--el-text-color-primary);
|
||||
--w-e-textarea-border-color: var(--el-border-color);
|
||||
--w-e-textarea-slight-border-color: var(--el-border-color-light);
|
||||
--w-e-textarea-slight-color: var(--el-border-color);
|
||||
--w-e-textarea-slight-bg-color: var(--el-bg-color-page);
|
||||
/* --w-e-textarea-selected-border-color: #b4d5ff;
|
||||
--w-e-textarea-handler-bg-color: #4290f7; */
|
||||
--w-e-toolbar-color: var(--el-text-color-primary);
|
||||
--w-e-toolbar-bg-color: var(--el-bg-color);
|
||||
--w-e-toolbar-active-color: var(--el-text-color-primary);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
flex: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 5px;
|
||||
border-radius: 8px;
|
||||
|
||||
&.body-padding .el-dialog__body {
|
||||
padding: 0;
|
||||
@@ -56,17 +56,27 @@
|
||||
}
|
||||
|
||||
.el-table {
|
||||
--el-table-header-text-color: var(--el-text-color-primary);
|
||||
--el-table-header-text-color: var(--el-text-color-regular);
|
||||
--el-table-header-bg-color: var(--table-header-bg-color);
|
||||
--el-table-border-color: var(--health-border, var(--el-border-color-lighter));
|
||||
--el-table-row-hover-bg-color: var(--el-fill-color-light);
|
||||
font-size: var(--el-font-size-base);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
|
||||
thead {
|
||||
th {
|
||||
font-weight: 400;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border-radius: 8px;
|
||||
border-color: var(--health-border, var(--el-border-color-lighter));
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.el-input-group__prepend {
|
||||
background-color: var(--el-fill-color-blank);
|
||||
}
|
||||
@@ -78,22 +88,30 @@
|
||||
.el-menu--popup-container {
|
||||
&.theme-light {
|
||||
.el-menu {
|
||||
border-radius: 8px;
|
||||
padding: 4px;
|
||||
.el-menu-item {
|
||||
border-radius: 6px;
|
||||
&.is-active {
|
||||
@apply bg-primary-light-9 border-primary border-r-2;
|
||||
background-color: var(--health-primary-light, var(--el-color-primary-light-9));
|
||||
color: var(--health-primary-dark, var(--el-color-primary));
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.el-menu-item:hover,
|
||||
.el-sub-menu__title:hover {
|
||||
color: var(--el-color-primary);
|
||||
background-color: var(--el-fill-color-light);
|
||||
}
|
||||
}
|
||||
}
|
||||
&.theme-dark {
|
||||
.el-menu {
|
||||
border-radius: 8px;
|
||||
padding: 4px;
|
||||
.el-menu-item {
|
||||
border-radius: 6px;
|
||||
&.is-active {
|
||||
@apply bg-primary;
|
||||
background-color: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,6 +128,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.el-button--primary {
|
||||
--el-button-hover-link-text-color: var(--el-color-primary-light-3);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;600;700&display=swap');
|
||||
|
||||
body {
|
||||
@apply text-base text-tx-primary overflow-hidden min-w-[375px];
|
||||
font-feature-settings: 'tnum' 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.form-tips {
|
||||
@apply text-tx-secondary text-xs leading-6 mt-1;
|
||||
}
|
||||
@@ -15,4 +21,9 @@ body {
|
||||
/* NProgress */
|
||||
#nprogress .bar {
|
||||
@apply bg-primary #{!important};
|
||||
height: 3px !important;
|
||||
}
|
||||
|
||||
#nprogress .peg {
|
||||
box-shadow: 0 0 8px var(--el-color-primary), 0 0 4px var(--el-color-primary) !important;
|
||||
}
|
||||
|
||||
+40
-31
@@ -1,49 +1,58 @@
|
||||
:root {
|
||||
--el-font-family: theme(fontFamily.sans);
|
||||
--el-font-weight-primary: 400;
|
||||
--el-menu-item-height: 46px;
|
||||
--el-menu-item-height: 42px;
|
||||
--el-menu-sub-item-height: var(--el-menu-item-height);
|
||||
--el-menu-icon-width: 18px;
|
||||
--aside-width: 200px;
|
||||
--navbar-height: 50px;
|
||||
--navbar-height: 52px;
|
||||
--color-white: #ffffff;
|
||||
--table-header-bg-color: #f8f8f8;
|
||||
--table-header-bg-color: #F8FAFC;
|
||||
--el-font-size-extra-large: 18px;
|
||||
--el-menu-base-level-padding: 16px;
|
||||
--el-menu-level-padding: 26px;
|
||||
--el-menu-base-level-padding: 14px;
|
||||
--el-menu-level-padding: 24px;
|
||||
--el-font-size-large: 16px;
|
||||
--el-font-size-medium: 15px;
|
||||
--el-font-size-base: 14px;
|
||||
--el-font-size-small: 13px;
|
||||
--el-font-size-extra-small: 12px;
|
||||
|
||||
/* 天蓝点缀 + 中性底色(天蓝仅用于主色/激活态,不铺满全局) */
|
||||
--health-primary: #0EA5E9;
|
||||
--health-primary-light: #E0F2FE;
|
||||
--health-primary-dark: #0284C7;
|
||||
--health-bg-page: #F1F5F9;
|
||||
--health-bg-sidebar: #FFFFFF;
|
||||
--health-text-primary: #1E293B;
|
||||
--health-text-secondary: #64748B;
|
||||
--health-border: #E2E8F0;
|
||||
--health-border-light: #EEF2F6;
|
||||
|
||||
--el-bg-color: var(--color-white);
|
||||
--el-bg-color-page: #f6f6f6;
|
||||
--el-bg-color-page: var(--health-bg-page);
|
||||
--el-bg-color-overlay: #ffffff;
|
||||
--el-text-color-primary: #333333;
|
||||
--el-text-color-regular: #666666;
|
||||
--el-text-color-secondary: #999999;
|
||||
--el-text-color-placeholder: #a8abb2;
|
||||
--el-text-color-disabled: #c0c4cc;
|
||||
--el-border-color: #dcdfe6;
|
||||
--el-border-color-light: #e4e7ed;
|
||||
--el-border-color-lighter: #ebeef5;
|
||||
--el-border-color-extra-light: #f2f2f2;
|
||||
--el-border-color-dark: #d4d7de;
|
||||
--el-border-color-darker: #cdd0d6;
|
||||
--el-fill-color: #f0f2f5;
|
||||
--el-fill-color-light: #f8f8f8;
|
||||
--el-fill-color-lighter: #fafafa;
|
||||
--el-fill-color-extra-light: #fafcff;
|
||||
--el-fill-color-dark: #ebedf0;
|
||||
--el-fill-color-darker: #e6e8eb;
|
||||
--el-text-color-primary: var(--health-text-primary);
|
||||
--el-text-color-regular: var(--health-text-secondary);
|
||||
--el-text-color-secondary: #94A3B8;
|
||||
--el-text-color-placeholder: #94A3B8;
|
||||
--el-text-color-disabled: #CBD5E1;
|
||||
--el-border-color: var(--health-border);
|
||||
--el-border-color-light: var(--health-border);
|
||||
--el-border-color-lighter: var(--health-border-light);
|
||||
--el-border-color-extra-light: #F8FAFC;
|
||||
--el-border-color-dark: #CBD5E1;
|
||||
--el-border-color-darker: #94A3B8;
|
||||
--el-fill-color: #F1F5F9;
|
||||
--el-fill-color-light: #F8FAFC;
|
||||
--el-fill-color-lighter: #FAFBFC;
|
||||
--el-fill-color-extra-light: #F8FAFC;
|
||||
--el-fill-color-dark: #E2E8F0;
|
||||
--el-fill-color-darker: #CBD5E1;
|
||||
--el-fill-color-blank: #ffffff;
|
||||
/* 过亮会盖住抽屉/弹窗下的内容;Element Loading 与部分蒙层共用此变量 */
|
||||
--el-mask-color: rgba(255, 255, 255, 0.5);
|
||||
--el-mask-color-extra-light: rgba(255, 255, 255, 0.22);
|
||||
-el-box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, 0.04), 0px 8px 20px rgba(0, 0, 0, 0.08);
|
||||
--el-box-shadow-light: 0px 0px 12px rgba(0, 0, 0, 0.12);
|
||||
--el-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, 0.12);
|
||||
--el-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, 0.08), 0px 12px 32px rgba(0, 0, 0, 0.12),
|
||||
0px 8px 16px -8px rgba(0, 0, 0, 0.16);
|
||||
--el-mask-color: rgba(255, 255, 255, 0.65);
|
||||
--el-mask-color-extra-light: rgba(255, 255, 255, 0.28);
|
||||
--el-box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
|
||||
--el-box-shadow-light: 0 1px 3px rgba(15, 23, 42, 0.06);
|
||||
--el-box-shadow-lighter: 0 1px 2px rgba(15, 23, 42, 0.04);
|
||||
--el-box-shadow-dark: 0 4px 12px rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,27 @@
|
||||
<template>
|
||||
<div class="login flex flex-col">
|
||||
<div class="flex-1 flex items-center justify-center">
|
||||
<div class="login-card flex rounded-md overflow-hidden">
|
||||
<div class="flex-1 h-full hidden md:inline-block">
|
||||
<image-contain :src="config.login_image" :width="400" height="100%" />
|
||||
<div class="login-bg-decoration"></div>
|
||||
<div class="flex-1 flex items-center justify-center relative z-10">
|
||||
<div class="login-card flex rounded-xl overflow-hidden shadow-lg">
|
||||
<div class="login-visual hidden md:flex flex-col justify-center items-center relative">
|
||||
<div class="login-visual-content">
|
||||
<div class="login-visual-icon">
|
||||
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="20" y="8" width="8" height="32" rx="2" fill="currentColor" opacity="0.9"/>
|
||||
<rect x="8" y="20" width="32" height="8" rx="2" fill="currentColor" opacity="0.9"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="login-visual-title">中医在线问诊平台</h2>
|
||||
<p class="login-visual-desc">专业 · 安全 · 可信赖的医疗管理系统</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="login-form bg-body flex flex-col justify-center px-10 py-10 md:w-[420px] w-[380px] flex-none mx-auto"
|
||||
>
|
||||
<div class="text-center text-3xl font-medium mb-8">{{ config.web_name }}</div>
|
||||
<div class="text-center mb-8">
|
||||
<div class="login-form-badge">管理后台</div>
|
||||
<div class="text-2xl font-semibold text-tx-primary mt-3">{{ config.web_name }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 企业微信自动授权中 -->
|
||||
<div v-if="wxWorkAutoLogin" class="text-center py-10">
|
||||
@@ -287,11 +300,68 @@ onMounted(async () => {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login {
|
||||
background-image: url('./images/login_bg.png');
|
||||
@apply min-h-screen bg-no-repeat bg-center bg-cover;
|
||||
position: relative;
|
||||
@apply min-h-screen overflow-hidden;
|
||||
background: var(--health-bg-page, #F1F5F9);
|
||||
|
||||
.login-bg-decoration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
height: auto;
|
||||
min-height: 400px;
|
||||
min-height: 440px;
|
||||
border: 1px solid var(--health-border, var(--el-border-color-lighter));
|
||||
box-shadow: var(--el-box-shadow-light);
|
||||
background: var(--el-bg-color);
|
||||
}
|
||||
|
||||
.login-visual {
|
||||
width: 400px;
|
||||
background: var(--el-bg-color);
|
||||
color: var(--el-text-color-primary);
|
||||
padding: 48px 40px;
|
||||
border-right: 1px solid var(--health-border, var(--el-border-color-lighter));
|
||||
|
||||
.login-visual-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 14px;
|
||||
background: var(--el-color-primary-light-9);
|
||||
color: var(--el-color-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 24px;
|
||||
|
||||
svg {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-visual-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.login-visual-desc {
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-secondary);
|
||||
line-height: 1.7;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form-badge {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--el-color-primary);
|
||||
background: var(--el-color-primary-light-9);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,14 @@ module.exports = {
|
||||
mask: 'var(--el-mask-color)'
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['PingFang SC', 'Arial', 'Hiragino Sans GB', 'Microsoft YaHei', 'sans-serif']
|
||||
sans: [
|
||||
'Noto Sans SC',
|
||||
'PingFang SC',
|
||||
'Microsoft YaHei',
|
||||
'Hiragino Sans GB',
|
||||
'Arial',
|
||||
'sans-serif'
|
||||
]
|
||||
},
|
||||
boxShadow: {
|
||||
DEFAULT: 'var(--el-box-shadow)',
|
||||
|
||||
Reference in New Issue
Block a user