refactor: extract image form to standalone page and implement tags view store

- Created ImageForm.vue as standalone page for add/edit image functionality
- Removed dialog-based image form from VmImages.vue
- Implemented tagsViewStore for global tab state management
- Added automatic tab closing on form cancel/back
- Fixed data persistence issue when switching between image edits
- Removed quick actions section from ImageForm
- Updated router configuration for new image form route
This commit is contained in:
2025-11-28 14:15:29 +08:00
parent 067e0539ba
commit f7c3be1d30
45 changed files with 8776 additions and 6881 deletions
+156 -40
View File
@@ -3,15 +3,15 @@
<!-- 侧边栏 -->
<div class="sidebar">
<div class="logo-container">
<h1 class="title">零零七云计算后台控制面板</h1>
<img src="@/assets/logo.png" alt="Logo" class="logo-img" />
</div>
<el-scrollbar class="sidebar-scrollbar">
<el-menu
:default-active="activeMenu"
class="sidebar-menu"
background-color="#ffffff"
text-color="#333333"
active-text-color="#1890ff"
background-color="transparent"
text-color="#34495e"
active-text-color="#2c3e50"
:unique-opened="true"
router
>
@@ -143,46 +143,39 @@ const handleLogout = () => {
/* 侧边栏样式 */
.sidebar {
width: 240px;
width: 260px;
height: 100%;
background-color: #ffffff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border-right: 1px solid #e1e8ed;
overflow: hidden;
z-index: 20;
}
.logo-container {
height: 60px;
height: 70px;
display: flex;
align-items: center;
padding: 0 16px;
color: #333;
justify-content: center;
padding: 0 20px;
background-color: #ffffff;
border-bottom: 1px solid #f0f0f0;
overflow: hidden;
border-bottom: 1px solid #e1e8ed;
}
.logo {
width: 32px;
height: 32px;
margin-right: 10px;
}
.title {
font-size: 18px;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
color: #1890ff;
.logo-img {
height: 50px;
width: auto;
object-fit: contain;
}
.sidebar-scrollbar {
height: calc(100vh - 60px);
height: calc(100vh - 70px);
}
.sidebar-menu {
border-right: none;
min-height: 100%;
background-color: transparent !important;
padding: 0;
}
/* 主容器样式 */
@@ -197,9 +190,9 @@ const handleLogout = () => {
/* 顶部导航栏样式 */
.navbar {
height: 60px;
padding: 0 15px;
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
padding: 0 20px;
background-color: #ffffff;
border-bottom: 1px solid #e1e8ed;
display: flex;
align-items: center;
justify-content: space-between;
@@ -209,32 +202,35 @@ const handleLogout = () => {
.navbar-left {
display: flex;
align-items: center;
flex: 1;
}
.navbar-right {
display: flex;
align-items: center;
gap: 8px;
}
.navbar-item {
padding: 0 10px;
height: 60px;
display: flex;
align-items: center;
}
.header-btn {
height: 40px;
width: 40px;
height: 36px;
width: 36px;
display: flex;
align-items: center;
justify-content: center;
color: #606266;
color: #34495e;
transition: all 0.2s ease;
border-radius: 0;
}
.header-btn:hover {
background-color: #f5f7fa;
border-radius: 4px;
background-color: #f8f9fa;
color: #2c3e50;
}
.avatar-container {
@@ -243,16 +239,31 @@ const handleLogout = () => {
cursor: pointer;
padding: 0 12px;
height: 60px;
gap: 8px;
transition: all 0.2s ease;
border-radius: 0;
}
.avatar-container:hover {
background-color: rgba(0, 0, 0, 0.025);
background-color: #f8f9fa;
}
.username {
margin: 0 8px;
margin: 0;
font-size: 14px;
color: #606266;
font-weight: 500;
color: #2c3e50;
}
:deep(.avatar-container .el-icon--right) {
color: #7f8c8d;
font-size: 12px;
margin-left: 4px;
transition: color 0.2s ease;
}
.avatar-container:hover :deep(.el-icon--right) {
color: #34495e;
}
/* 内容区域样式 */
@@ -275,13 +286,38 @@ const handleLogout = () => {
opacity: 0;
}
:deep(.el-dropdown-menu) {
border-radius: 0;
border: 1px solid #e1e8ed;
background-color: #ffffff;
box-shadow: 0 2px 8px rgba(44, 62, 80, 0.1);
padding: 4px 0;
}
:deep(.el-dropdown-menu__item) {
display: flex;
align-items: center;
color: #34495e;
transition: all 0.2s ease;
padding: 8px 16px;
}
:deep(.el-dropdown-menu__item i) {
margin-right: 8px;
color: #7f8c8d;
}
:deep(.el-dropdown-menu__item:hover) {
background-color: #f8f9fa;
color: #2c3e50;
}
:deep(.el-dropdown-menu__item:hover i) {
color: #2c3e50;
}
:deep(.el-dropdown-menu__item.is-divided) {
border-top: 1px solid #e1e8ed;
}
/* 侧边栏滚动条样式优化 */
@@ -293,18 +329,98 @@ const handleLogout = () => {
height: 100%;
}
/* 自定义滚动条样式 */
:deep(.sidebar-scrollbar .el-scrollbar__bar) {
opacity: 0.3;
}
:deep(.sidebar-scrollbar .el-scrollbar__thumb) {
background-color: rgba(255, 255, 255, 0.2);
transition: background-color 0.2s;
}
:deep(.sidebar-scrollbar .el-scrollbar__thumb:hover) {
background-color: rgba(255, 255, 255, 0.35);
}
/* Element Plus 菜单项样式优化 */
:deep(.el-menu) {
border-right: none;
}
:deep(.el-sub-menu__title) {
height: 48px;
line-height: 48px;
height: 50px;
line-height: 50px;
margin: 0;
padding: 0 20px;
transition: background-color 0.2s ease;
color: #34495e !important;
}
:deep(.el-sub-menu__title:hover) {
background-color: #f8f9fa !important;
color: #2c3e50 !important;
}
:deep(.el-menu-item) {
height: 48px;
line-height: 48px;
height: 50px;
line-height: 50px;
margin: 0;
padding: 0 20px;
transition: background-color 0.2s ease;
color: #34495e !important;
}
:deep(.el-menu-item:hover) {
background-color: #f8f9fa !important;
color: #2c3e50 !important;
}
:deep(.el-menu-item.is-active) {
background-color: rgba(44, 62, 80, 0.1) !important;
color: #2c3e50 !important;
font-weight: 600;
position: relative;
}
:deep(.el-menu-item.is-active::before) {
content: '';
position: absolute;
left: 0;
top: 0;
width: 3px;
height: 100%;
background-color: #2c3e50;
}
:deep(.el-sub-menu.is-active > .el-sub-menu__title) {
color: #2c3e50 !important;
background-color: #f8f9fa !important;
}
:deep(.el-sub-menu .el-menu) {
background-color: #fafbfc !important;
margin: 0;
padding: 0;
}
:deep(.el-sub-menu .el-menu-item) {
margin: 0;
padding-left: 48px !important;
background-color: transparent !important;
}
:deep(.el-sub-menu .el-menu-item.is-active) {
background-color: rgba(44, 62, 80, 0.12) !important;
}
:deep(.el-sub-menu__icon-arrow) {
color: #7f8c8d !important;
transition: transform 0.2s ease;
}
:deep(.el-sub-menu.is-opened > .el-sub-menu__title .el-sub-menu__icon-arrow) {
transform: rotate(180deg);
color: #2c3e50 !important;
}
</style>