明树Git Lab
Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
J
jt_front
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
jt_front
Commits
c9982f32
Commit
c9982f32
authored
Apr 03, 2026
by
zhanghan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改档案库出版
parent
7a1787a8
Pipeline
#109245
passed with stage
in 21 seconds
Changes
3
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
536 additions
and
1 deletion
+536
-1
routes.js
src/router/routes.js
+7
-0
projectAllPage.vue
src/views/projectManage/projectAllPage.vue
+2
-1
xmdakDetaill.vue
src/views/projectManage/xmdakDetaill.vue
+527
-0
No files found.
src/router/routes.js
View file @
c9982f32
...
@@ -79,6 +79,13 @@ const routes = [
...
@@ -79,6 +79,13 @@ const routes = [
meta
:
{
title
:
"项目档案库"
},
meta
:
{
title
:
"项目档案库"
},
component
:
()
=>
import
(
"@/views/projectManage/projectAllPage.vue"
),
component
:
()
=>
import
(
"@/views/projectManage/projectAllPage.vue"
),
},
},
{
path
:
"/xmdakDetaill"
,
name
:
"xmdakDetaill"
,
title
:
"项目档案库"
,
meta
:
{
title
:
"项目档案库"
},
component
:
()
=>
import
(
"@/views/projectManage/xmdakDetaill.vue"
),
},
{
{
path
:
"/addProject"
,
path
:
"/addProject"
,
name
:
"addProject"
,
name
:
"addProject"
,
...
...
src/views/projectManage/projectAllPage.vue
View file @
c9982f32
...
@@ -256,7 +256,8 @@ const handleCurrentPageChange = (page) => {
...
@@ -256,7 +256,8 @@ const handleCurrentPageChange = (page) => {
const
previewProject
=
(
item
)
=>
{
const
previewProject
=
(
item
)
=>
{
router
.
push
({
router
.
push
({
name
:
"addProject"
,
name
:
"xmdakDetaill"
,
// name: "addProject",
query
:
{
query
:
{
isPreview
:
true
,
isPreview
:
true
,
projectId
:
item
.
id
,
projectId
:
item
.
id
,
...
...
src/views/projectManage/xmdakDetaill.vue
0 → 100644
View file @
c9982f32
<
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
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment