明树Git Lab

Commit ffdc2ddb authored by zhanghan's avatar zhanghan

1

parent 2d120db9
Pipeline #109376 passed with stage
in 21 seconds
......@@ -136,9 +136,7 @@
</DynamicTable>
</el-collapse-item>
<el-collapse-item
title="投资额完成情况(单位:万元)"
name="投资额完成情况(单位:万元)"
<el-collapse-item title="投资额完成情况" name="投资额完成情况"
><el-row gutter="20">
<el-col :span="12">
<el-form-item
......@@ -1240,12 +1238,11 @@ const getActiveCollapseItems = () => [
"出资情况",
"合同约定权益获取",
"分红情况",
"投资额完成情况(万元)",
"投资额完成情况",
"投资回收(决策)",
"投资回收(计划)",
dynamicTitles.value.yearlyUpdateTitle,
"净现金流",
"投资额完成情况(单位:万元)",
"截止12月末累计实收",
"资金流出",
"分红情况",
......
......@@ -136,9 +136,7 @@
</DynamicTable>
</el-collapse-item>
<el-collapse-item
title="投资额完成情况(单位:万元)"
name="投资额完成情况(单位:万元)"
<el-collapse-item title="投资额完成情况" name="投资额完成情况"
><el-row gutter="20">
<el-col :span="12">
<el-form-item
......@@ -1236,7 +1234,7 @@ const getActiveCollapseItems = () => [
"出资情况",
"合同约定权益获取",
"分红情况",
"投资额完成情况(万元)",
"投资额完成情况",
"投资回收(决策)",
"投资回收(计划)",
dynamicTitles.value.yearlyUpdateTitle,
......
<template>
<div class="xmdak-detail-container">
<!-- Tab 切换区域 -->
<div class="tab-wrapper">
<div class="tab-container">
<!-- Tab 切换区域 -->
<div class="main-tab-wrapper">
<div class="main-tab-container">
<div
v-for="(tab, index) in tabs"
:key="index"
:class="['tab-item', { active: activeTab === index }]"
:class="['main-tab-item', { active: activeTab === index }]"
@click="switchTab(index)"
>
<div class="tab-icon">
<component :is="tab.icon" />
</div>
<span class="tab-label">{{ tab.label }}</span>
</div>
</div>
</div>
<!-- 内容区域 -->
<div class="content-section">
<!-- 子项列表 -->
<div v-if="!showComponentView" class="sub-items-section">
<div class="sub-items-grid">
<div
v-for="(item, idx) in currentTabChildren"
:key="idx"
class="sub-item-card"
@click="handleSubItemClick(item)"
>
<div class="card-icon">
<el-icon><Document /></el-icon>
</div>
<div class="card-content">
<h3 class="card-title">{{ item.title }}</h3>
<p class="card-desc">{{ item.desc }}</p>
</div>
<div class="card-arrow">
<el-icon><ArrowRight /></el-icon>
</div>
</div>
<!-- 子项导航区域 -->
<div class="sub-tab-wrapper">
<div class="sub-tab-container">
<div
v-for="(item, idx) in currentTabChildren"
:key="idx"
:class="['sub-tab-item', { active: activeSubItem === item.name }]"
@click="handleSubItemClick(item)"
>
<span class="sub-tab-label">{{ item.title }}</span>
</div>
</div>
</div>
<!-- 详情组件区域 -->
<div v-else class="component-view-section">
<div v-if="isLoading" class="loading-overlay">
<el-icon class="is-loading"><Loading /></el-icon>
<span>正在加载...</span>
</div>
<div v-else class="view-content">
<component
:is="currentComponent"
v-if="currentComponent"
:project-id="projectId"
/>
<div v-else class="error-content">
<el-empty description="组件加载失败">
<el-button type="primary" @click="backToList">返回列表</el-button>
</el-empty>
</div>
<!-- 详情内容区域 -->
<div class="detail-section">
<div v-if="isLoading" class="loading-overlay">
<el-icon class="is-loading"><Loading /></el-icon>
<span>正在加载...</span>
</div>
<div v-else class="detail-content">
<component
:is="currentComponent"
v-if="currentComponent"
:project-id="projectId"
:key="activeTab + activeSubItem"
/>
<div v-else class="empty-content">
<el-empty description="请选择上方功能模块">
<template #image>
<el-icon :size="80"><Document /></el-icon>
</template>
</el-empty>
</div>
</div>
</div>
......@@ -70,7 +58,6 @@ import { ref, computed, markRaw } from "vue";
import { useRoute } from "vue-router";
import {
Document,
ArrowRight,
FolderOpened,
Management,
Finished,
......@@ -100,9 +87,9 @@ const tabs = ref([
// 当前激活的 Tab
const activeTab = ref(0);
// 显示组件视图
const showComponentView = ref(false);
// 当前激活的子项
const activeSubItem = ref("");
// 当前组件
const currentComponent = ref(null);
const isLoading = ref(false);
......@@ -233,7 +220,8 @@ const currentTabChildren = computed(() => {
// 切换 Tab
const switchTab = (index) => {
activeTab.value = index;
backToList();
activeSubItem.value = "";
currentComponent.value = null;
};
// 处理子项点击 - 直接加载详情组件
......@@ -243,7 +231,7 @@ const handleSubItemClick = async (item) => {
return;
}
showComponentView.value = true;
activeSubItem.value = item.name;
isLoading.value = true;
currentComponent.value = null;
......@@ -257,271 +245,247 @@ const handleSubItemClick = async (item) => {
isLoading.value = false;
}
};
// 返回列表
const backToList = () => {
showComponentView.value = false;
currentComponent.value = null;
isLoading.value = false;
};
</script>
<style scoped lang="scss">
.xmdak-detail-container {
min-height: 100vh;
background: #f5f7fa;
padding: 0;
}
// 简洁的头部
.page-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 16px 20px;
text-align: center;
color: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
.page-title {
font-size: 20px;
font-weight: 600;
margin: 0;
letter-spacing: 1px;
}
display: flex;
flex-direction: column;
}
// Tab 容器
.tab-wrapper {
// 主 Tab 切换区域 - 现代政府风格
.main-tab-wrapper {
background: white;
padding: 12px 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
padding: 0;
box-shadow: 0 2px 12px rgba(0, 86, 179, 0.08);
position: sticky;
top: 0;
z-index: 100;
border-bottom: 2px solid #e8f4fd;
}
.tab-container {
.main-tab-container {
display: flex;
max-width: 1200px;
max-width: 1400px;
margin: 0 auto;
gap: 8px;
background: #f8f9fa;
padding: 6px;
border-radius: 12px;
gap: 4px;
background: transparent;
padding: 0 20px;
}
.tab-item {
.main-tab-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 12px 20px;
border-radius: 8px;
padding: 18px 24px;
cursor: pointer;
transition: all 0.2s ease;
transition: all 0.3s ease;
position: relative;
.tab-icon {
font-size: 18px;
transition: transform 0.2s ease;
}
border-radius: 8px 8px 0 0;
margin-top: 4px;
.tab-label {
font-size: 14px;
font-size: 15px;
font-weight: 500;
color: #495057;
transition: all 0.2s ease;
color: #5a6c7d;
letter-spacing: 0.5px;
transition: all 0.3s ease;
position: relative;
z-index: 1;
}
&::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 3px;
background: transparent;
transition: all 0.3s ease;
border-radius: 3px 3px 0 0;
}
&:hover {
background: rgba(102, 126, 234, 0.08);
transform: translateY(-1px);
background: linear-gradient(to bottom, #f8fbff, #ffffff);
.tab-label {
color: #0056b3;
}
.tab-icon {
transform: scale(1.05);
&::before {
background: linear-gradient(to right, #4dabf7, #0056b3);
opacity: 0.6;
}
}
&.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
background: white;
margin-top: 0;
padding-top: 22px;
.tab-icon,
.tab-label {
color: white;
color: #0056b3;
font-weight: 600;
}
}
}
// 内容区域
.content-section {
max-width: 1440px;
margin: 24px auto;
padding: 0 20px;
}
.sub-items-section {
min-height: 300px;
&::before {
background: linear-gradient(to right, #4dabf7, #0056b3);
box-shadow: 0 -2px 8px rgba(0, 86, 179, 0.15);
}
}
}
.tab-content {
min-height: 300px;
// 子项导航区域
.sub-tab-wrapper {
background: linear-gradient(to bottom, #f8fbff, #ffffff);
border-bottom: 1px solid #d4e8fc;
padding: 16px 24px;
box-shadow: 0 2px 8px rgba(0, 86, 179, 0.04);
}
// 子项网格 - 增加宽度
.sub-items-grid {
.sub-tab-container {
display: flex;
gap: 14px;
gap: 12px;
flex-wrap: wrap;
max-width: 1400px;
margin: 0 auto;
justify-content: center;
}
.sub-item-card {
background: white;
border-radius: 10px;
padding: 16px;
.sub-tab-item {
padding: 12px 24px;
border-radius: 20px;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
display: flex;
align-items: center;
gap: 12px;
transition: all 0.3s ease;
background: white;
border: 1.5px solid #e8f4fd;
position: relative;
overflow: hidden;
&::before {
content: "";
content: '';
position: absolute;
top: 0;
left: 0;
width: 3px;
height: 100%;
background: linear-gradient(180deg, #667eea, #764ba2);
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(77, 171, 247, 0.05), rgba(0, 86, 179, 0.05));
opacity: 0;
transition: opacity 0.2s ease;
transition: opacity 0.3s ease;
}
.sub-tab-label {
font-size: 14px;
color: #5a6c7d;
font-weight: 500;
transition: all 0.3s ease;
position: relative;
z-index: 1;
letter-spacing: 0.3px;
}
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
border-color: #4dabf7;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(77, 171, 247, 0.15);
&::before {
opacity: 1;
}
.card-arrow {
transform: translateX(2px);
color: #667eea;
}
.card-icon {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
transform: scale(1.05);
.sub-tab-label {
color: #0056b3;
}
}
.card-icon {
width: 42px;
height: 42px;
border-radius: 8px;
background: #f8f9fa;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
color: #667eea;
transition: all 0.2s ease;
flex-shrink: 0;
}
&.active {
background: linear-gradient(135deg, #4dabf7, #0056b3);
border-color: transparent;
box-shadow: 0 4px 16px rgba(0, 86, 179, 0.25);
transform: translateY(-2px);
.card-content {
flex: 1;
min-width: 0;
}
&::before {
background: transparent;
}
.card-title {
font-size: 14px;
font-weight: 600;
color: #212529;
margin: 0 0 3px 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.sub-tab-label {
color: white;
font-weight: 600;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
}
}
.card-desc {
font-size: 12px;
color: #868e96;
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
// 详情内容区域
.detail-section {
flex: 1;
background: #f5f7fa;
overflow: hidden;
display: flex;
flex-direction: column;
}
.card-arrow {
color: #adb5bd;
font-size: 16px;
transition: all 0.2s ease;
flex-shrink: 0;
.loading-overlay {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80px 20px;
color: #0056b3;
font-size: 16px;
.el-icon {
font-size: 40px;
margin-bottom: 16px;
color: #0056b3;
}
}
// 详情组件区域
.component-view-section {
max-width: 100%;
width: 100%;
margin: 16px 0 24px;
padding: 0 20px;
.loading-overlay {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
color: #667eea;
font-size: 16px;
.el-icon {
font-size: 32px;
margin-bottom: 12px;
}
}
.detail-content {
flex: 1;
overflow-y: auto;
padding: 20px;
min-height: 500px;
}
.view-content {
background: white;
border-radius: 12px;
padding: 20px;
min-height: 500px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}
.empty-content {
display: flex;
align-items: center;
justify-content: center;
min-height: 500px;
background: white;
border-radius: 4px;
.error-content {
display: flex;
align-items: center;
justify-content: center;
min-height: 300px;
.el-icon {
color: #0056b3;
opacity: 0.3;
}
}
// 响应式设计
@media (max-width: 768px) {
.tab-container {
flex-direction: column;
}
.main-tab-item {
padding: 12px 16px;
.sub-items-grid {
grid-template-columns: 1fr;
.tab-label {
font-size: 13px;
}
}
.tab-item {
padding: 10px 16px;
.sub-tab-container {
gap: 6px;
}
.tab-label {
font-size: 13px;
.sub-tab-item {
padding: 8px 14px;
.sub-tab-label {
font-size: 13px;
}
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment