明树Git Lab

Commit c9982f32 authored by zhanghan's avatar zhanghan

修改档案库出版

parent 7a1787a8
Pipeline #109245 passed with stage
in 21 seconds
......@@ -79,6 +79,13 @@ const routes = [
meta: { title: "项目档案库" },
component: () => import("@/views/projectManage/projectAllPage.vue"),
},
{
path: "/xmdakDetaill",
name: "xmdakDetaill",
title: "项目档案库",
meta: { title: "项目档案库" },
component: () => import("@/views/projectManage/xmdakDetaill.vue"),
},
{
path: "/addProject",
name: "addProject",
......
......@@ -256,7 +256,8 @@ const handleCurrentPageChange = (page) => {
const previewProject = (item) => {
router.push({
name: "addProject",
name: "xmdakDetaill",
// name: "addProject",
query: {
isPreview: true,
projectId: item.id,
......
<template>
<div class="xmdak-detail-container">
<!-- Tab 切换区域 -->
<div class="tab-wrapper">
<div class="tab-container">
<div
v-for="(tab, index) in tabs"
:key="index"
:class="['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>
</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>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, markRaw } from "vue";
import { useRoute } from "vue-router";
import {
Document,
ArrowRight,
FolderOpened,
Management,
Finished,
Loading,
} from "@element-plus/icons-vue";
const route = useRoute();
// Tab 配置
const tabs = ref([
{
label: "投前管理",
key: "projectManage",
icon: markRaw(FolderOpened),
},
{
label: "投中管理",
key: "investingManage",
icon: markRaw(Management),
},
{
label: "投后管理",
key: "castbehind",
icon: markRaw(Finished),
},
]);
// 当前激活的 Tab
const activeTab = ref(0);
// 显示组件视图
const showComponentView = ref(false);
const currentComponent = ref(null);
const isLoading = ref(false);
// 获取 projectId
const projectId = ref(route.query.projectId || "");
// 路由配置 - 使用Add结尾的详情组件
const routeChildren = {
projectManage: [
{
name: "projectDraft",
title: "项目遴选",
desc: "项目初选与评估",
importFn: () => import("@/views/projectManage/projectDraft.vue"),
},
{
name: "projectSetUp",
title: "项目立项",
desc: "项目立项申请",
importFn: () => import("@/views/projectManage/projectSetUp.vue"),
},
{
name: "projectArgument",
title: "项目论证",
desc: "项目论证分析",
importFn: () => import("@/views/projectManage/projectArgument.vue"),
},
{
name: "projectDecision",
title: "项目决策",
desc: "项目投资决策",
importFn: () => import("@/views/projectManage/projectDecision.vue"),
},
{
name: "projectAllPage",
title: "项目档案库",
desc: "项目档案管理",
importFn: () => import("@/views/projectManage/addProject.vue"),
},
],
investingManage: [
{
name: "targetLiabilityStatement",
title: "投资目标责任书",
desc: "投资目标责任管理",
importFn: () =>
import("@/views/investingManage/addStatement.vue"),
},
{
name: "targetControl",
title: "投资控制",
desc: "投资过程控制",
importFn: () => import("@/views/investingManage/addControl.vue"),
},
{
name: "majorRisk",
title: "重大风险防控",
desc: "风险识别与防控",
importFn: () => import("@/views/investingManage/addRisk.vue"),
},
{
name: "constructionTime",
title: "建设期投资回收",
desc: "建设期资金回收",
importFn: () =>
import("@/views/investingManage/constructionTimeAdd.vue"),
},
{
name: "construction",
title: "建设期投资检查",
desc: "建设期投资监督",
importFn: () => import("@/views/investingManage/constructionAdd.vue"),
},
{
name: "bigIssues",
title: "重大事项审批",
desc: "重大事项审批流程",
importFn: () => import("@/views/investingManage/bigIssuesAdd.vue"),
},
{
name: "quit",
title: "项目退出",
desc: "项目退出管理",
importFn: () => import("@/views/investingManage/quitAdd.vue"),
},
{
name: "decision",
title: "重新决策",
desc: "重新决策评估",
importFn: () => import("@/views/investingManage/decisionAdd.vue"),
},
],
castbehind: [
{
name: "investmentCecovery",
title: "运营期投资回收",
desc: "运营期收益回收",
importFn: () =>
import("@/views/castbehind/investmentCecoveryAdd.vue"),
},
{
name: "runningPeriod",
title: "运营期投资检查",
desc: "运营期监督检查",
importFn: () => import("@/views/castbehind/runningPeriodAdd.vue"),
},
{
name: "evaluate",
title: "投资后评价",
desc: "投资效果评价",
importFn: () => import("@/views/castbehind/evaluateAdd.vue"),
},
{
name: "turnover",
title: "移交管理",
desc: "项目移交管理",
importFn: () => import("@/views/castbehind/turnoverAdd.vue"),
},
],
};
// 获取当前 Tab 的子项
const currentTabChildren = computed(() => {
const currentKey = tabs.value[activeTab.value].key;
return routeChildren[currentKey] || [];
});
// 切换 Tab
const switchTab = (index) => {
activeTab.value = index;
backToList();
};
// 处理子项点击 - 直接加载详情组件
const handleSubItemClick = async (item) => {
if (!projectId.value) {
console.warn("缺少 projectId 参数");
return;
}
showComponentView.value = true;
isLoading.value = true;
currentComponent.value = null;
try {
const module = await item.importFn();
currentComponent.value = markRaw(module.default);
} catch (error) {
console.error("组件加载失败:", error);
currentComponent.value = null;
} finally {
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;
}
}
// Tab 容器
.tab-wrapper {
background: white;
padding: 12px 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
position: sticky;
top: 0;
z-index: 100;
}
.tab-container {
display: flex;
max-width: 1200px;
margin: 0 auto;
gap: 8px;
background: #f8f9fa;
padding: 6px;
border-radius: 12px;
}
.tab-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 12px 20px;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
position: relative;
.tab-icon {
font-size: 18px;
transition: transform 0.2s ease;
}
.tab-label {
font-size: 14px;
font-weight: 500;
color: #495057;
transition: all 0.2s ease;
}
&:hover {
background: rgba(102, 126, 234, 0.08);
transform: translateY(-1px);
.tab-icon {
transform: scale(1.05);
}
}
&.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
.tab-icon,
.tab-label {
color: white;
}
}
}
// 内容区域
.content-section {
max-width: 1440px;
margin: 24px auto;
padding: 0 20px;
}
.sub-items-section {
min-height: 300px;
}
.tab-content {
min-height: 300px;
}
// 子项网格 - 增加宽度
.sub-items-grid {
display: flex;
gap: 14px;
flex-wrap: wrap;
margin: 0 auto;
justify-content: center;
}
.sub-item-card {
background: white;
border-radius: 10px;
padding: 16px;
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;
position: relative;
overflow: hidden;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 3px;
height: 100%;
background: linear-gradient(180deg, #667eea, #764ba2);
opacity: 0;
transition: opacity 0.2s ease;
}
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 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);
}
}
.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;
}
.card-content {
flex: 1;
min-width: 0;
}
.card-title {
font-size: 14px;
font-weight: 600;
color: #212529;
margin: 0 0 3px 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-desc {
font-size: 12px;
color: #868e96;
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-arrow {
color: #adb5bd;
font-size: 16px;
transition: all 0.2s ease;
flex-shrink: 0;
}
}
// 详情组件区域
.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;
}
}
.view-content {
background: white;
border-radius: 12px;
padding: 20px;
min-height: 500px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}
.error-content {
display: flex;
align-items: center;
justify-content: center;
min-height: 300px;
}
}
// 响应式设计
@media (max-width: 768px) {
.tab-container {
flex-direction: column;
}
.sub-items-grid {
grid-template-columns: 1fr;
}
.tab-item {
padding: 10px 16px;
}
.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