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:
Ray.Hao
2026-03-30 08:11:03 +08:00
parent 3a27da6607
commit 3fedf4943d
107 changed files with 464 additions and 8264 deletions

View File

@@ -1,4 +1,7 @@
// 全局基础重置补充 UnoCSS 预设未覆盖的项目级样式
/**
* 全局基础重置样式
* 补充 UnoCSS 预设未覆盖的项目级样式
*/
#app {
width: 100%;

View File

@@ -1,24 +1,10 @@
/**
* 项目主题变量
*
* 结构
* 1. SCSS 变量 - 布局尺寸 JS 导出和组件使用
* 2. CSS 变量 - 侧边栏/菜单主题色
* 3. 主题模式 - 深蓝侧边栏暗黑模式
* 4. 无障碍模式 - 色弱模式
* 主题变量定义
* 只放 :roothtml.darkhtml.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. 无障碍模式
// 无障碍模式
// ============================================
// 色弱模式

View 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);

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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";

View 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;
}
}
}
}

View File

@@ -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;

View 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;
}
}

View File

@@ -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
View File

@@ -0,0 +1,7 @@
/**
* NProgress 进度条样式
*/
#nprogress .bar {
background-color: var(--el-color-primary);
}