refactor: 重构 API 层目录结构 & 样式模块化拆分
- API 层按业务域拆分(api/auth/, api/file/, api/system/*) - 类型定义从 types/api/ 移入对应 api 模块内(就近原则) - 公共类型统一为 api/common.ts,移除冗余类型重导出 - 样式文件按职责拆分(base/, layout/, vendors/),移除 common.scss - 移除失效的单元测试文件
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
// 全局基础重置:补充 UnoCSS 预设未覆盖的项目级样式
|
||||
/**
|
||||
* 全局基础重置样式
|
||||
* 补充 UnoCSS 预设未覆盖的项目级样式
|
||||
*/
|
||||
|
||||
#app {
|
||||
width: 100%;
|
||||
@@ -1,24 +1,10 @@
|
||||
/**
|
||||
* 项目主题变量
|
||||
*
|
||||
* 结构:
|
||||
* 1. SCSS 变量 - 布局尺寸(供 JS 导出和组件使用)
|
||||
* 2. CSS 变量 - 侧边栏/菜单主题色
|
||||
* 3. 主题模式 - 深蓝侧边栏、暗黑模式
|
||||
* 4. 无障碍模式 - 色弱模式
|
||||
* 主题变量定义
|
||||
* 只放 :root、html.dark、html.sidebar-color-blue 等定义真实颜色的 CSS 变量
|
||||
*/
|
||||
|
||||
// ============================================
|
||||
// 1. SCSS 变量 - 布局尺寸
|
||||
// ============================================
|
||||
|
||||
$sidebar-width: 210px;
|
||||
$sidebar-width-collapsed: 54px;
|
||||
$navbar-height: 50px;
|
||||
$tags-view-height: 34px;
|
||||
|
||||
// ============================================
|
||||
// 2. CSS 变量 - 默认主题(浅色 + 白色侧边栏)
|
||||
// 默认主题(浅色 + 白色侧边栏)
|
||||
// ============================================
|
||||
|
||||
:root {
|
||||
@@ -33,19 +19,10 @@ $tags-view-height: 34px;
|
||||
--sidebar-logo-text-color: #303133;
|
||||
}
|
||||
|
||||
// SCSS 变量映射(供组件使用)
|
||||
$menu-background: var(--menu-background);
|
||||
$menu-text: var(--menu-text);
|
||||
$menu-active-text: var(--menu-active-text);
|
||||
$menu-hover: var(--menu-hover);
|
||||
$sidebar-logo-background: var(--sidebar-logo-background);
|
||||
$sidebar-logo-text-color: var(--sidebar-logo-text-color);
|
||||
|
||||
// ============================================
|
||||
// 3. 主题模式
|
||||
// 深蓝色侧边栏主题
|
||||
// ============================================
|
||||
|
||||
// 浅色主题 - 深蓝色侧边栏
|
||||
html.sidebar-color-blue {
|
||||
--menu-background: #304156;
|
||||
--menu-text: #bfcbd9;
|
||||
@@ -55,7 +32,10 @@ html.sidebar-color-blue {
|
||||
--sidebar-logo-text-color: #fff;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 暗黑主题
|
||||
// ============================================
|
||||
|
||||
html.dark {
|
||||
--menu-background: var(--el-bg-color-overlay);
|
||||
--menu-text: #fff;
|
||||
@@ -71,7 +51,7 @@ html.dark {
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 4. 无障碍模式
|
||||
// 无障碍模式
|
||||
// ============================================
|
||||
|
||||
// 色弱模式
|
||||
24
src/styles/base/_variables.scss
Normal file
24
src/styles/base/_variables.scss
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* SCSS 变量定义
|
||||
* 只放数学变量和 CSS 变量映射
|
||||
*/
|
||||
|
||||
// ============================================
|
||||
// 布局尺寸变量
|
||||
// ============================================
|
||||
|
||||
$sidebar-width: 210px;
|
||||
$sidebar-width-collapsed: 54px;
|
||||
$navbar-height: 50px;
|
||||
$tags-view-height: 34px;
|
||||
|
||||
// ============================================
|
||||
// CSS 变量映射(供组件和 SCSS 使用)
|
||||
// ============================================
|
||||
|
||||
$menu-background: var(--menu-background);
|
||||
$menu-text: var(--menu-text);
|
||||
$menu-active-text: var(--menu-active-text);
|
||||
$menu-hover: var(--menu-hover);
|
||||
$sidebar-logo-background: var(--sidebar-logo-background);
|
||||
$sidebar-logo-text-color: var(--sidebar-logo-text-color);
|
||||
@@ -1,142 +0,0 @@
|
||||
/* 全局业务通用样式 */
|
||||
|
||||
.app-container {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
/* 进度条颜色 */
|
||||
#nprogress .bar {
|
||||
background-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
/* 弹出菜单统一使用主题变量(简化 hover 色) */
|
||||
.el-menu--popup {
|
||||
--el-menu-bg-color: var(--menu-background);
|
||||
--el-menu-text-color: var(--menu-text);
|
||||
--el-menu-active-color: var(--menu-active-text);
|
||||
--el-menu-hover-bg-color: var(--menu-hover);
|
||||
|
||||
background-color: var(--menu-background);
|
||||
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
color: var(--menu-text) !important;
|
||||
}
|
||||
|
||||
.el-menu-item:hover,
|
||||
.el-sub-menu__title:hover {
|
||||
color: var(--menu-active-text) !important;
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
|
||||
.el-menu-item.is-active {
|
||||
color: var(--menu-active-text) !important;
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
混合布局左侧菜单 hover 样式
|
||||
============================================ */
|
||||
.layout-mix .layout__sidebar--left .el-menu {
|
||||
.el-menu-item {
|
||||
&:hover {
|
||||
background-color: var(--el-fill-color-light) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-sub-menu__title {
|
||||
&:hover {
|
||||
background-color: var(--el-fill-color-light) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 深色或深蓝侧边栏的 hover 样式 */
|
||||
html.dark .layout-mix .layout__sidebar--left .el-menu,
|
||||
html.sidebar-color-blue .layout-mix .layout__sidebar--left .el-menu {
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
&:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Top layout: let horizontal menu fill the remaining header space */
|
||||
.layout-top .layout__header-left .el-menu--horizontal,
|
||||
.layout-mix .layout__header-menu .el-menu--horizontal {
|
||||
display: flex;
|
||||
flex: 1 1 0% !important;
|
||||
align-items: center;
|
||||
width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 窄屏隐藏菜单文字,仅保留图标 */
|
||||
.hideSidebar {
|
||||
&.layout-top .layout__header .el-menu--horizontal,
|
||||
&.layout-mix .layout__header .el-menu--horizontal {
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
.menu-title,
|
||||
span:not([class*="i-svg"]):not(.el-icon) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.layout-mix .layout__sidebar--left .el-menu {
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
.menu-title,
|
||||
span:not([class*="i-svg"]):not(.el-icon) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 全局筛选区域 */
|
||||
.filter-section {
|
||||
padding: 8px 12px 0;
|
||||
margin-bottom: 8px;
|
||||
background-color: var(--el-bg-color-overlay);
|
||||
border: 1px solid var(--el-border-color-light);
|
||||
border-radius: 4px;
|
||||
|
||||
.search-buttons {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格区域 */
|
||||
.table-section {
|
||||
margin-bottom: 12px;
|
||||
|
||||
&__toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 4px;
|
||||
|
||||
&--actions,
|
||||
&--tools {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.el-pagination {
|
||||
justify-content: flex-end;
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// Element Plus 变量覆盖(必须在最前面)
|
||||
@use "./element-plus-vars";
|
||||
|
||||
$border: 1px solid var(--el-border-color-light);
|
||||
|
||||
/* el-dialog */
|
||||
.el-dialog {
|
||||
.el-dialog__header {
|
||||
padding: 15px 20px;
|
||||
margin: 0;
|
||||
border-bottom: $border;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
padding: 15px;
|
||||
border-top: $border;
|
||||
}
|
||||
}
|
||||
|
||||
/* el-drawer */
|
||||
.el-drawer {
|
||||
.el-drawer__header {
|
||||
padding: 15px 20px;
|
||||
margin: 0;
|
||||
color: inherit;
|
||||
border-bottom: $border;
|
||||
}
|
||||
|
||||
.el-drawer__body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.el-drawer__footer {
|
||||
padding: 15px;
|
||||
border-top: $border;
|
||||
}
|
||||
}
|
||||
|
||||
// 抽屉和对话框底部按钮区域
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
// 1. 基础重置
|
||||
@use "./reset";
|
||||
/**
|
||||
* 样式总入口
|
||||
* 严格按照 ITCSS 架构顺序导入
|
||||
*/
|
||||
|
||||
// 2. 主题变量
|
||||
@use "./variables" as *;
|
||||
// 1. 基础层
|
||||
@use "./base/variables" as *;
|
||||
@use "./base/theme";
|
||||
@use "./base/reset";
|
||||
|
||||
// 3. UI 框架适配
|
||||
@use "./element-plus";
|
||||
@use "./vxe-table";
|
||||
@use "./wangeditor";
|
||||
// 2. 第三方适配层
|
||||
@use "./vendors/element-plus";
|
||||
@use "./vendors/element-plus-override";
|
||||
@use "./vendors/vxe-table";
|
||||
@use "./vendors/wangeditor";
|
||||
@use "./vendors/nprogress";
|
||||
|
||||
// 4. 业务通用样式
|
||||
@use "./common";
|
||||
// 3. 布局层
|
||||
@use "./layout/layout";
|
||||
|
||||
103
src/styles/layout/_layout.scss
Normal file
103
src/styles/layout/_layout.scss
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* 全局标准布局样式
|
||||
*/
|
||||
|
||||
.page-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.page-aside {
|
||||
margin-bottom: 16px;
|
||||
|
||||
@media (min-width: 992px) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.page-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.page-search {
|
||||
margin-bottom: 16px;
|
||||
|
||||
/* 覆盖 el-card 内部 padding */
|
||||
.el-card__body {
|
||||
padding: 12px 12px 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.page-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
|
||||
&__left,
|
||||
&__right {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 混合布局左侧菜单 hover 样式 */
|
||||
.layout-mix .layout__sidebar--left .el-menu {
|
||||
.el-menu-item:hover,
|
||||
.el-sub-menu__title:hover {
|
||||
background-color: var(--el-fill-color-light) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 深色或深蓝侧边栏的 hover 样式 */
|
||||
html.dark .layout-mix .layout__sidebar--left .el-menu,
|
||||
html.sidebar-color-blue .layout-mix .layout__sidebar--left .el-menu {
|
||||
.el-menu-item:hover,
|
||||
.el-sub-menu__title:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 顶部布局菜单填充空间 */
|
||||
.layout-top .layout__header-left .el-menu--horizontal,
|
||||
.layout-mix .layout__header-menu .el-menu--horizontal {
|
||||
display: flex;
|
||||
flex: 1 1 0% !important;
|
||||
align-items: center;
|
||||
width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 窄屏隐藏菜单文字,仅保留图标 */
|
||||
.hideSidebar {
|
||||
&.layout-top .layout__header .el-menu--horizontal,
|
||||
&.layout-mix .layout__header .el-menu--horizontal {
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
.menu-title,
|
||||
span:not([class*="i-svg"]):not(.el-icon) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.layout-mix .layout__sidebar--left .el-menu {
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
.menu-title,
|
||||
span:not([class*="i-svg"]):not(.el-icon) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
/* stylelint-disable property-no-unknown */
|
||||
|
||||
// 通过 SCSS 变量导出给 JS/TS 使用的模块文件
|
||||
// 注意:依赖 src/styles/variables.scss 中定义的 SCSS 变量
|
||||
// 注意:依赖 src/styles/base/_variables.scss 中定义的 SCSS 变量
|
||||
|
||||
@use "./base/variables" as *;
|
||||
|
||||
:export {
|
||||
sidebar-width: $sidebar-width;
|
||||
|
||||
75
src/styles/vendors/_element-plus-override.scss
vendored
Normal file
75
src/styles/vendors/_element-plus-override.scss
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Element Plus 组件样式定制
|
||||
*/
|
||||
|
||||
$border: 1px solid var(--el-border-color-light);
|
||||
|
||||
/* el-dialog */
|
||||
.el-dialog {
|
||||
.el-dialog__header {
|
||||
padding: 15px 20px;
|
||||
margin: 0;
|
||||
border-bottom: $border;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
padding: 15px;
|
||||
border-top: $border;
|
||||
}
|
||||
}
|
||||
|
||||
/* el-drawer */
|
||||
.el-drawer {
|
||||
.el-drawer__header {
|
||||
padding: 15px 20px;
|
||||
margin: 0;
|
||||
color: inherit;
|
||||
border-bottom: $border;
|
||||
}
|
||||
|
||||
.el-drawer__body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.el-drawer__footer {
|
||||
padding: 15px;
|
||||
border-top: $border;
|
||||
}
|
||||
}
|
||||
|
||||
/* 抽屉和对话框底部按钮区域 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* 弹出菜单统一使用主题变量 */
|
||||
.el-menu--popup {
|
||||
--el-menu-bg-color: var(--menu-background);
|
||||
--el-menu-text-color: var(--menu-text);
|
||||
--el-menu-active-color: var(--menu-active-text);
|
||||
--el-menu-hover-bg-color: var(--menu-hover);
|
||||
|
||||
background-color: var(--menu-background);
|
||||
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
color: var(--menu-text) !important;
|
||||
}
|
||||
|
||||
.el-menu-item:hover,
|
||||
.el-sub-menu__title:hover {
|
||||
color: var(--menu-active-text) !important;
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
|
||||
.el-menu-item.is-active {
|
||||
color: var(--menu-active-text) !important;
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
/**
|
||||
* Element Plus 变量覆盖
|
||||
*
|
||||
* 此文件用于覆盖 Element Plus 的默认主题变量
|
||||
* 需要在 element-plus.scss 中导入,而不是在 variables.scss 中
|
||||
* Element Plus 主题变量覆盖
|
||||
* 必须在组件样式之前导入
|
||||
*/
|
||||
@forward "element-plus/theme-chalk/src/common/var.scss" with (
|
||||
$colors: (
|
||||
7
src/styles/vendors/_nprogress.scss
vendored
Normal file
7
src/styles/vendors/_nprogress.scss
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* NProgress 进度条样式
|
||||
*/
|
||||
|
||||
#nprogress .bar {
|
||||
background-color: var(--el-color-primary);
|
||||
}
|
||||
Reference in New Issue
Block a user