明树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
bc9d6526
Commit
bc9d6526
authored
Feb 02, 2026
by
zhanghan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
年度计划开发完毕
parent
826a8f44
Pipeline
#106881
passed with stage
in 20 seconds
Changes
3
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
811 additions
and
258 deletions
+811
-258
annual.vue
src/views/everydayPage/annual.vue
+33
-3
annualAdd.vue
src/views/everydayPage/annualAdd.vue
+479
-255
annualPlan.vue
src/views/everydayPage/annualPlan.vue
+299
-0
No files found.
src/views/everydayPage/annual.vue
View file @
bc9d6526
...
@@ -65,7 +65,37 @@ let tableData = ref([]);
...
@@ -65,7 +65,37 @@ let tableData = ref([]);
let
tableColumns
=
ref
([
let
tableColumns
=
ref
([
{
{
prop
:
"projectName"
,
prop
:
"projectName"
,
label
:
"项目信息"
,
label
:
"项目名称"
,
showOverflowTooltip
:
true
,
},
{
prop
:
"projectForeignName"
,
label
:
"项目外文名称"
,
showOverflowTooltip
:
true
,
},
{
prop
:
"sbdw"
,
label
:
"申报单位"
,
showOverflowTooltip
:
true
,
},
{
prop
:
"ssejqy"
,
label
:
"所属二级企业"
,
showOverflowTooltip
:
true
,
},
{
prop
:
"xmgsmc"
,
label
:
"项目公司名称"
,
showOverflowTooltip
:
true
,
},
{
prop
:
"xmkgsjyj"
,
label
:
"项目预计起始时间"
,
showOverflowTooltip
:
true
,
},
{
prop
:
"xmjgsjyj"
,
label
:
"目预计完成时间"
,
showOverflowTooltip
:
true
,
showOverflowTooltip
:
true
,
},
},
...
@@ -86,7 +116,7 @@ let pageSize = ref(10);
...
@@ -86,7 +116,7 @@ let pageSize = ref(10);
const
getStatementData
=
()
=>
{
const
getStatementData
=
()
=>
{
loading
.
value
=
true
;
loading
.
value
=
true
;
proxy
.
$post
({
proxy
.
$post
({
url
:
"/api/project/get
Jsqtzjc
List"
,
url
:
"/api/project/get
Tzjh
List"
,
data
:
{
data
:
{
page
:
currentPage
.
value
,
page
:
currentPage
.
value
,
pagesize
:
pageSize
.
value
,
pagesize
:
pageSize
.
value
,
...
@@ -136,7 +166,7 @@ const deleteStatement = (item) => {
...
@@ -136,7 +166,7 @@ const deleteStatement = (item) => {
})
})
.
then
(()
=>
{
.
then
(()
=>
{
proxy
.
$post
({
proxy
.
$post
({
url
:
"/api/project/delete
Jsqtzjc
"
,
url
:
"/api/project/delete
Tzjh
"
,
data
:
{
data
:
{
id
:
item
.
id
,
id
:
item
.
id
,
},
},
...
...
src/views/everydayPage/annualAdd.vue
View file @
bc9d6526
...
@@ -106,7 +106,7 @@
...
@@ -106,7 +106,7 @@
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"项目建设期 (月)"
>
<el-form-item
label=
"项目建设期 (月)"
>
<el-input
-number
<el-input
v-model=
"formData.xmjsqy"
v-model=
"formData.xmjsqy"
:min=
"0"
:min=
"0"
placeholder=
"请输入项目建设期 (月)"
placeholder=
"请输入项目建设期 (月)"
...
@@ -115,39 +115,23 @@
...
@@ -115,39 +115,23 @@
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"项目流转状态(审批状态)"
>
<el-form-item
label=
"项目流转状态(审批状态)"
>
<
el-select
<
CommonSelector
v-model=
"formData.projectLzType"
v-model=
"formData.projectLzType"
placeholder=
"请选择项目流转状态"
dictName=
"xmlzzt"
>
></CommonSelector>
<el-option
label=
"待立项"
value=
"1"
/>
<el-option
label=
"立项审批中"
value=
"3"
/>
<el-option
label=
"已立项"
value=
"5"
/>
<el-option
label=
"决策填报中"
value=
"7"
/>
<el-option
label=
"决策审批中"
value=
"8"
/>
<el-option
label=
"已决策"
value=
"9"
/>
<el-option
label=
"再决策填报中"
value=
"11"
/>
<el-option
label=
"再决策审批中"
value=
"12"
/>
<el-option
label=
"再决策审批通过"
value=
"13"
/>
<el-option
label=
"再决策审批不通过"
value=
"15"
/>
</el-select>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"项目阶段"
>
<el-form-item
label=
"项目阶段"
>
<
el-select
<
CommonSelector
v-model=
"formData.xmjd"
v-model=
"formData.xmjd"
placeholder=
"请选择项目阶段"
dictName=
"project_phase"
>
/>
<el-option
label=
"筹备期"
value=
"筹备期"
/>
<el-option
label=
"建设期"
value=
"建设期"
/>
<el-option
label=
"运营期"
value=
"运营期"
/>
<el-option
label=
"收尾期"
value=
"收尾期"
/>
</el-select>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"运营年限(年)"
>
<el-form-item
label=
"运营年限(年)"
>
<el-input
-number
<el-input
v-model=
"formData.yynxn"
v-model=
"formData.yynxn"
:min=
"0"
:min=
"0"
placeholder=
"请输入运营年限(年)"
placeholder=
"请输入运营年限(年)"
...
@@ -164,39 +148,6 @@
...
@@ -164,39 +148,6 @@
/>
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"计划年份"
>
<el-input
v-model=
"formData.jhnf"
placeholder=
"请输入计划年份(如2026)"
maxlength=
"4"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"新建/续建"
>
<el-select
v-model=
"formData.xjXj"
placeholder=
"请选择"
>
<el-option
label=
"新建"
value=
"新建"
/>
<el-option
label=
"续建"
value=
"续建"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"年度投资目标"
>
<el-input
v-model=
"formData.ndTzMb"
placeholder=
"请输入年度投资目标"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"项目预计工期"
>
<el-input
v-model=
"formData.xmYjGq"
placeholder=
"请输入项目预计工期"
/>
</el-form-item>
</el-col>
</el-row>
</el-row>
</el-collapse-item>
</el-collapse-item>
...
@@ -454,7 +405,7 @@
...
@@ -454,7 +405,7 @@
</el-row>
</el-row>
</el-collapse-item>
</el-collapse-item>
<!-- 可研/决策信息(单位:万元):
保留原有功能,提交字段改为kyjcxx
-->
<!-- 可研/决策信息(单位:万元):
独立表格,专属方法/数据源
-->
<el-collapse-item
<el-collapse-item
title=
"可研/决策信息(单位:万元)"
title=
"可研/决策信息(单位:万元)"
name=
"可研/决策信息(单位:万元)"
name=
"可研/决策信息(单位:万元)"
...
@@ -464,6 +415,7 @@
...
@@ -464,6 +415,7 @@
style=
"width: 100%"
style=
"width: 100%"
border
border
:cell-style=
"tableCellStyle"
:cell-style=
"tableCellStyle"
row-key=
"serialNumber"
>
>
<!-- 序号列 -->
<!-- 序号列 -->
<el-table-column
<el-table-column
...
@@ -503,12 +455,12 @@
...
@@ -503,12 +455,12 @@
align=
"center"
align=
"center"
>
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
<el-input
-number
<el-input
v-model=
"row[time]"
v-model=
"row[time]"
:min=
"0"
:min=
"0"
:precision=
"2"
:precision=
"2"
controls-position=
"right"
controls-position=
"right"
@
change=
"handle
Data
Change(row)"
@
change=
"handle
Financial
Change(row)"
:disabled=
"isPreview"
:disabled=
"isPreview"
style=
"width: 100%"
style=
"width: 100%"
/>
/>
...
@@ -517,11 +469,305 @@
...
@@ -517,11 +469,305 @@
</el-table>
</el-table>
</el-collapse-item>
</el-collapse-item>
<!-- 新增:项目年度计划表格(单位:万元) -->
<!-- 年度投资计划:基础信息 -->
<el-collapse-item
title=
"年度投资计划"
name=
"年度投资计划"
>
<el-row
:gutter=
"20"
>
<!-- 基础短字段:span12分栏 -->
<el-col
:span=
"12"
>
<el-form-item
label=
"计划年份"
>
<el-date-picker
v-model=
"formData.jhnf"
type=
"year"
format=
"YYYY"
value-format=
"YYYY"
placeholder=
"请选择计划年份"
picker-options=
"{ disabledDate: (date) => date > new Date() }"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"新建/续建"
>
<CommonSelector
v-model=
"formData.xjXj"
dictName=
"sf"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"年度投资目标"
>
<el-input
v-model=
"formData.ndTzMb"
placeholder=
"请输入年度投资目标"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"项目预计工期"
>
<el-input
v-model=
"formData.xmYjGq"
placeholder=
"请输入项目预计工期(如12个月)"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"项目融资落地时间或预计落地时间"
>
<el-date-picker
v-model=
"formData.xmRzLdSjHyyjLdSj"
type=
"date"
placeholder=
"请选择时间"
value-format=
"YYYY-MM-DD"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"预计实现资本金内部收益率(%)"
>
<el-input
v-model=
"formData.yjSxZbjNbsyl"
:min=
"0"
:precision=
"2"
:max=
"999.99"
controls-position=
"right"
placeholder=
"请输入收益率"
style=
"width: 100%"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"项目计划总投资类型"
>
<el-input
v-model=
"formData.xmTzZeXmJhZtzLx"
placeholder=
"请输入项目计划总投资类型"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"计划类型"
>
<el-input
v-model=
"formData.jhLx"
placeholder=
"请输入计划类型"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"当前进展阶段"
>
<el-input
v-model=
"formData.dqJzJd"
placeholder=
"请输入当前进展阶段"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"项目融资是否已经落地"
>
<CommonSelector
v-model=
"formData.xmRzSfYjLd"
dictName=
"sf"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"当前进展情况"
>
<el-input
v-model=
"formData.dqJzQk"
placeholder=
"请输入当前进展情况"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"项目实际开工时间"
>
<el-date-picker
v-model=
"formData.xmSjKgSj"
type=
"date"
placeholder=
"请选择时间"
value-format=
"YYYY-MM-DD"
/>
</el-form-item>
</el-col>
<!-- 长文本字段:span24通栏,用文本域 -->
<el-col
:span=
"24"
>
<el-form-item
label=
"预期实现效果"
>
<el-input
v-model=
"formData.yqSxXg"
type=
"textarea"
:rows=
"3"
placeholder=
"请输入预期实现效果详细说明"
/>
</el-form-item>
</el-col>
<el-col
:span=
"24"
>
<el-form-item
label=
"2025年投资金额(全口径)目标(决算)与计划差异说明"
>
<el-input
v-model=
"formData.nTzJqMbjyYjhCySm"
type=
"textarea"
:rows=
"3"
placeholder=
"请输入差异说明"
/>
</el-form-item>
</el-col>
<el-col
:span=
"24"
>
<el-form-item
label=
"2025年计划投资目标(决算)与计划差异说明"
>
<el-input
v-model=
"formData.nJhTzMbjyYjhCySm"
type=
"textarea"
:rows=
"3"
placeholder=
"请输入差异说明"
/>
</el-form-item>
</el-col>
<el-col
:span=
"24"
>
<el-form-item
label=
"项目主要风险及主要风险应对举措"
>
<el-input
v-model=
"formData.xmZyFxJzyFxYdcj"
type=
"textarea"
:rows=
"4"
placeholder=
"请输入主要风险及对应的应对举措"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<!-- 项目年度计划表格(单位:万元):独立子组件表格,专属方法/数据源 -->
<el-collapse-item
<el-collapse-item
title=
"项目年度计划表格(单位:万元)"
title=
"项目年度计划表格(单位:万元)"
name=
"项目年度计划表格(单位:万元)"
name=
"项目年度计划表格(单位:万元)"
>
>
<div
class=
"annualPlans"
>
<annualPlan
v-model=
"formData.xmndjh"
:dynamic-time-list=
"dynamicTimeList"
:is-preview=
"isPreview"
@
handleAnnualPlanChange=
"handleAnnualPlanTableChange"
></annualPlan>
</div>
</el-collapse-item>
<!-- 项目年度计划(资金支付口径):金额类字段统一用数字输入框,精度2,单位万元 -->
<el-collapse-item
title=
"项目年度计划(资金支付口径)"
name=
"项目年度计划(资金支付口径)"
>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"资金支付比例(%)"
>
<el-input
v-model=
"formData.zjfzBl"
:min=
"0"
:max=
"100"
:precision=
"2"
controls-position=
"right"
placeholder=
"0.00"
style=
"width: 100%"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"债权融资(万元)"
>
<el-input
v-model=
"formData.zqRz"
:min=
"0"
:precision=
"2"
controls-position=
"right"
placeholder=
"0.00"
style=
"width: 100%"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"年度计划总额(万元)"
>
<el-input
v-model=
"formData.ndJhZe"
:min=
"0"
:precision=
"2"
controls-position=
"right"
placeholder=
"0.00"
style=
"width: 100%"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"回款再投入(万元)"
>
<el-input
v-model=
"formData.hkZtr"
:min=
"0"
:precision=
"2"
controls-position=
"right"
placeholder=
"0.00"
style=
"width: 100%"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"资本金-配套方(万元)"
>
<el-input
v-model=
"formData.zbjPtF"
:min=
"0"
:precision=
"2"
controls-position=
"right"
placeholder=
"0.00"
style=
"width: 100%"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"其他(万元)"
>
<el-input
v-model=
"formData.qt"
:min=
"0"
:precision=
"2"
controls-position=
"right"
placeholder=
"0.00"
style=
"width: 100%"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"资本金-外部股东(万元)"
>
<el-input
v-model=
"formData.zbjWbGd"
:min=
"0"
:precision=
"2"
controls-position=
"right"
placeholder=
"0.00"
style=
"width: 100%"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"我方仅指本单位出资(万元)"
>
<el-input
v-model=
"formData.wfJzBdwCz"
:min=
"0"
:precision=
"2"
controls-position=
"right"
placeholder=
"0.00"
style=
"width: 100%"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<!-- 2026年参股单位出资情况修正 -->
<el-collapse-item
title=
"2026年参股单位出资情况修正(单位:万元)"
name=
"2026年参股单位出资情况修正(单位:万元)"
>
<el-row
:gutter=
"20"
>
<el-col
:span=
"24"
>
<el-form-item
label=
"参股单位出资情况修正"
>
<DynamicTable
:columns=
"transferColumns"
:disabled=
"isPreview"
v-model=
"formData.cgdwczqkxz"
:default-row=
"{
mc: '',
fj: '',
bz: '',
}"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
</el-collapse-item>
</el-collapse>
</el-collapse>
</el-form>
</el-form>
...
@@ -536,14 +782,46 @@
...
@@ -536,14 +782,46 @@
import
{
reactive
,
ref
,
onMounted
,
getCurrentInstance
}
from
"vue"
;
import
{
reactive
,
ref
,
onMounted
,
getCurrentInstance
}
from
"vue"
;
import
{
useRouter
,
useRoute
}
from
"vue-router"
;
import
{
useRouter
,
useRoute
}
from
"vue-router"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
ElMessage
}
from
"element-plus"
;
// 初始化全局变量
import
annualPlan
from
"./annualPlan.vue"
;
import
DynamicTable
from
"@/components/FormDynamicTable/index.vue"
;
// ========== 动态表格列配置(参股单位出资修正) ==========
const
transferColumns
=
ref
([
{
prop
:
"mc"
,
label
:
"单位名称"
,
type
:
"input"
,
placeholder
:
"请填写单位名称"
,
},
{
prop
:
"fj"
,
label
:
"我方出资额(万元)"
,
type
:
"input"
,
placeholder
:
"请输入我方出资额(万元)"
,
min
:
0
,
precision
:
2
,
},
{
prop
:
"bz"
,
label
:
"差异说明"
,
type
:
"textarea"
,
rows
:
2
,
placeholder
:
"请输入差异说明"
,
},
]);
const
cgdwczqkxz
=
ref
([]);
// ========== 路由/实例/全局方法 ==========
const
router
=
useRouter
();
const
router
=
useRouter
();
const
route
=
useRoute
();
const
route
=
useRoute
();
const
{
proxy
}
=
getCurrentInstance
();
const
{
proxy
}
=
getCurrentInstance
();
// ========== 基础配置 ==========
// ========== 基础配置
:两个表格共用(仅时间列表,无其他关联)
==========
const
activeCollapse
=
ref
([
const
activeCollapse
=
ref
([
"基本信息"
,
"基本信息"
,
"年度投资计划"
,
"项目年度计划(资金支付口径)"
,
"2026年参股单位出资情况修正(单位:万元)"
,
"可研/决策信息(单位:万元)"
,
"可研/决策信息(单位:万元)"
,
"项目年度计划表格(单位:万元)"
,
"项目年度计划表格(单位:万元)"
,
"战略类A"
,
"战略类A"
,
...
@@ -557,11 +835,14 @@ const isPreview = ref(!!route.query.isPreview);
...
@@ -557,11 +835,14 @@ const isPreview = ref(!!route.query.isPreview);
const
projectList
=
ref
([]);
const
projectList
=
ref
([]);
const
rcCgqyglId
=
ref
(
route
.
query
.
id
||
""
);
const
rcCgqyglId
=
ref
(
route
.
query
.
id
||
""
);
const
timeHeaderType
=
ref
(
"year"
);
// year/ month 切换时间表头类型
const
timeHeaderType
=
ref
(
"year"
);
// year/ month 切换时间表头类型
const
dynamicTimeList
=
ref
([]);
// 动态时间列表(表头)
const
dynamicTimeList
=
ref
([]);
// 动态时间列表(两个表格共用表头,无其他数据关联)
const
financialIndicators
=
ref
([]);
// 财务表格渲染数据
const
annualPlanIndicators
=
ref
([]);
// 年度计划表格渲染数据
// ========== 数据源完全隔离:可研表格 & 年度计划表格 各自独立 ==========
// 1. 可研/决策信息表格:专属数据源(独立)
const
financialIndicators
=
ref
([]);
// 可研表格渲染数据源
// 2. 项目年度计划表格:仅用子组件双向绑定的formData.xmndjh,移除冗余的annualPlanIndicators(彻底解耦)
// ==========
财务指标原始配置(不可修改,用于回填匹配
) ==========
// ==========
可研/决策信息表格:原始配置+专属初始化/方法(完全独立
) ==========
const
financialOriginConfig
=
ref
([
const
financialOriginConfig
=
ref
([
{
{
serialNumber
:
"1"
,
serialNumber
:
"1"
,
...
@@ -774,72 +1055,7 @@ const financialOriginConfig = ref([
...
@@ -774,72 +1055,7 @@ const financialOriginConfig = ref([
},
},
]);
]);
// ========== 年度计划表格原始配置(完全还原截图结构) ==========
// ========== 表单数据:完全对齐数据库,两个表格的JSON字段完全独立 ==========
const
annualPlanOriginConfig
=
ref
([
{
level
:
0
,
indicatorName
:
"年度投资计划"
,
isTotal
:
false
},
{
level
:
1
,
indicatorName
:
"计划投资完成及资金来源"
,
isTotal
:
false
},
{
level
:
2
,
indicatorName
:
"计划资金来源(全口径)"
,
isTotal
:
false
},
{
level
:
3
,
indicatorName
:
"合计"
,
isTotal
:
true
,
parentCode
:
[
"资本金"
,
"债权融资"
,
"回款再投入"
,
"其他"
],
},
{
level
:
3
,
indicatorName
:
"资本金"
,
isTotal
:
false
},
{
level
:
4
,
indicatorName
:
"小计"
,
isTotal
:
true
,
parentCode
:
[
"能建方"
,
"外部股东"
],
},
{
level
:
4
,
indicatorName
:
"能建方"
,
isTotal
:
false
},
{
level
:
4
,
indicatorName
:
"外部股东"
,
isTotal
:
false
},
{
level
:
3
,
indicatorName
:
"债权融资"
,
isTotal
:
false
},
{
level
:
4
,
indicatorName
:
"小计"
,
isTotal
:
true
,
parentCode
:
[
"其中:非并表项目我方贷款/担保额"
],
},
{
level
:
4
,
indicatorName
:
"其中:非并表项目我方贷款/担保额"
,
isTotal
:
false
},
{
level
:
3
,
indicatorName
:
"回款再投入"
,
isTotal
:
false
},
{
level
:
3
,
indicatorName
:
"其他"
,
isTotal
:
false
},
{
level
:
4
,
indicatorName
:
"小计"
,
isTotal
:
true
,
parentCode
:
[
"其中:我方其他出资"
],
},
{
level
:
4
,
indicatorName
:
"其中:我方其他出资"
,
isTotal
:
false
},
{
level
:
2
,
indicatorName
:
"资金来源(新口径)"
,
isTotal
:
false
},
{
level
:
3
,
indicatorName
:
"合计"
,
isTotal
:
true
,
parentCode
:
[
"资本金"
,
"债权融资"
,
"回款再投入"
,
"其他"
],
},
{
level
:
3
,
indicatorName
:
"资本金"
,
isTotal
:
false
},
{
level
:
4
,
indicatorName
:
"小计"
,
isTotal
:
true
,
parentCode
:
[
"能建方"
,
"外部股东"
],
},
{
level
:
4
,
indicatorName
:
"能建方"
,
isTotal
:
false
},
{
level
:
4
,
indicatorName
:
"外部股东"
,
isTotal
:
false
},
{
level
:
3
,
indicatorName
:
"债权融资"
,
isTotal
:
false
},
{
level
:
3
,
indicatorName
:
"回款再投入"
,
isTotal
:
false
},
{
level
:
3
,
indicatorName
:
"其他"
,
isTotal
:
false
},
{
level
:
1
,
indicatorName
:
"合计"
,
isTotal
:
true
,
parentCode
:
[
"计划投资完成及资金来源"
],
},
{
level
:
1
,
indicatorName
:
"政府付费"
,
isTotal
:
false
},
]);
// ========== 表单数据:完全对齐数据库字段,无冗余! ==========
const
formData
=
reactive
({
const
formData
=
reactive
({
// 基础字段
// 基础字段
projectId
:
""
,
projectId
:
""
,
...
@@ -895,18 +1111,17 @@ const formData = reactive({
...
@@ -895,18 +1111,17 @@ const formData = reactive({
// 最终分类
// 最终分类
zzflqk
:
""
,
zzflqk
:
""
,
// 可研/决策信息(JSON,与财务表格绑定)
// 两个表格的JSON字段:完全独立,无任何关联
kyjcxx
:
[],
kyjcxx
:
[],
// 可研/决策信息表格:专属提交字段
// 年度计划信息(JSON,与新增表格绑定)
xmndjh
:
[],
// 项目年度计划表格:专属提交字段(子组件双向绑定)
xmndjh
:
[],
//
其他扩展字段
//
年度投资计划基础信息
jhnf
:
""
,
jhnf
:
""
,
xjXj
:
""
,
xjXj
:
""
,
ndTzMb
:
""
,
ndTzMb
:
""
,
xmYjGq
:
""
,
xmYjGq
:
""
,
xmRzLdSjHyyjLdSj
:
""
,
xmRzLdSjHyyjLdSj
:
""
,
yjSxZbjNbsyl
:
0.0
,
yjSxZbjNbsyl
:
""
,
xmTzZeXmJhZtzLx
:
""
,
xmTzZeXmJhZtzLx
:
""
,
jhLx
:
""
,
jhLx
:
""
,
dqJzJd
:
""
,
dqJzJd
:
""
,
...
@@ -918,7 +1133,7 @@ const formData = reactive({
...
@@ -918,7 +1133,7 @@ const formData = reactive({
nJhTzMbjyYjhCySm
:
""
,
nJhTzMbjyYjhCySm
:
""
,
xmZyFxJzyFxYdcj
:
""
,
xmZyFxJzyFxYdcj
:
""
,
//
金额类JSON
字段
//
项目年度计划(资金支付口径) 金额类
字段
zjfzBl
:
0.0
,
zjfzBl
:
0.0
,
zqRz
:
0.0
,
zqRz
:
0.0
,
ndJhZe
:
0.0
,
ndJhZe
:
0.0
,
...
@@ -927,72 +1142,47 @@ const formData = reactive({
...
@@ -927,72 +1142,47 @@ const formData = reactive({
qt
:
0.0
,
qt
:
0.0
,
zbjWbGd
:
0.0
,
zbjWbGd
:
0.0
,
wfJzBdwCz
:
0.0
,
wfJzBdwCz
:
0.0
,
cgdwczqkxz
:
{},
});
// ========== 核心方法:生成动态时间表头 ==========
// 参股单位出资修正
const
generateDynamicTime
=
()
=>
{
cgdwczqkxz
:
[],
const
now
=
new
Date
();
});
const
currentYear
=
now
.
getFullYear
();
const
currentMonth
=
now
.
getMonth
()
+
1
;
const
timeList
=
[];
for
(
let
i
=
0
;
i
<=
15
;
i
++
)
{
if
(
timeHeaderType
.
value
===
"year"
)
{
timeList
.
push
(
String
(
currentYear
+
i
));
}
else
{
const
calcYear
=
currentYear
+
Math
.
floor
((
currentMonth
+
i
-
1
)
/
12
);
const
calcMonth
=
((
currentMonth
+
i
-
1
)
%
12
)
+
1
;
timeList
.
push
(
`
${
calcYear
}
-
${
calcMonth
.
toString
().
padStart
(
2
,
"0"
)}
`
);
}
}
dynamicTimeList
.
value
=
timeList
;
initFinancialTable
();
// 生成表头后初始化财务表格
initAnnualPlanTable
();
// 生成表头后初始化年度计划表格
};
// ==========
初始化财务表格数据
==========
// ==========
【专属方法】可研/决策信息表格:初始化(独立)
==========
const
initFinancialTable
=
()
=>
{
const
initFinancialTable
=
()
=>
{
if
(
dynamicTimeList
.
value
.
length
===
0
)
return
;
if
(
dynamicTimeList
.
value
.
length
===
0
)
return
;
const
tableData
=
financialOriginConfig
.
value
.
map
((
item
)
=>
{
const
tableData
=
financialOriginConfig
.
value
.
map
((
item
)
=>
{
const
row
=
{
...
item
,
total
:
0
};
const
row
=
{
...
item
,
total
:
0
};
// 仅为可研表格的行赋值时间字段,与年度计划无关
dynamicTimeList
.
value
.
forEach
((
time
)
=>
(
row
[
time
]
=
0
));
dynamicTimeList
.
value
.
forEach
((
time
)
=>
(
row
[
time
]
=
0
));
return
row
;
return
row
;
});
});
financialIndicators
.
value
=
tableData
;
financialIndicators
.
value
=
tableData
;
// 初始化可研表格的合计
initFinancialRowTotal
();
};
};
// ==========
初始化年度计划表格数据
==========
// ==========
【专属方法】项目年度计划表格:初始化(独立,子组件专属17行)
==========
const
initAnnualPlanTable
=
()
=>
{
const
initAnnualPlanTable
=
()
=>
{
if
(
dynamicTimeList
.
value
.
length
===
0
)
return
;
if
(
dynamicTimeList
.
value
.
length
===
0
)
return
;
const
tableData
=
annualPlanOriginConfig
.
value
.
map
((
item
)
=>
{
// 生成17行带唯一id的独立数据(子组件专属,与可研表格无任何关联)
const
row
=
{
...
item
,
total
:
0
};
const
tableData
=
Array
.
from
({
length
:
17
},
(
_
,
index
)
=>
({
dynamicTimeList
.
value
.
forEach
((
time
)
=>
(
row
[
time
]
=
0
));
id
:
index
+
1
,
// 子组件row-key="id" 专属,唯一标识
return
row
;
total
:
0
,
});
...
dynamicTimeList
.
value
.
reduce
((
obj
,
time
)
=>
({
...
obj
,
[
time
]:
0
}),
{}),
annualPlanIndicators
.
value
=
tableData
;
}));
};
// 仅赋值给年度计划表格的绑定字段,与可研表格无任何引用
formData
.
xmndjh
=
tableData
;
// ========== 财务表格数据变更:更新行合计+父项合计 ==========
const
handleDataChange
=
(
currentRow
)
=>
{
updateRowTotal
(
currentRow
);
updateAllTotalRow
();
};
// ========== 年度计划表格数据变更:更新行合计+父项合计 ==========
const
handleAnnualPlanChange
=
(
currentRow
)
=>
{
updateRowTotal
(
currentRow
);
updateAnnualPlanTotalRow
();
};
};
// ==========
更新单行合计
==========
// ==========
【专属方法】可研/决策信息表格:单行合计计算(独立)
==========
const
updateRowTotal
=
(
row
)
=>
{
const
update
Financial
RowTotal
=
(
row
)
=>
{
row
.
total
=
dynamicTimeList
.
value
.
reduce
((
sum
,
time
)
=>
{
row
.
total
=
dynamicTimeList
.
value
.
reduce
((
sum
,
time
)
=>
{
return
sum
+
(
Number
(
row
[
time
])
||
0
);
return
sum
+
(
Number
(
row
[
time
])
||
0
);
},
0
);
},
0
);
};
};
// ==========
更新财务表格所有父项合计行
==========
// ==========
【专属方法】可研/决策信息表格:全量合计行更新(独立)
==========
const
updateAllTotalRow
=
()
=>
{
const
updateAll
Financial
TotalRow
=
()
=>
{
financialIndicators
.
value
.
forEach
((
totalRow
)
=>
{
financialIndicators
.
value
.
forEach
((
totalRow
)
=>
{
if
(
!
totalRow
.
isTotal
||
!
totalRow
.
parentCode
)
return
;
if
(
!
totalRow
.
isTotal
||
!
totalRow
.
parentCode
)
return
;
totalRow
.
total
=
0
;
totalRow
.
total
=
0
;
...
@@ -1011,40 +1201,59 @@ const updateAllTotalRow = () => {
...
@@ -1011,40 +1201,59 @@ const updateAllTotalRow = () => {
});
});
};
};
// ========== 更新年度计划表格所有父项合计行 ==========
// ========== 【专属方法】可研/决策信息表格:批量初始化合计(独立) ==========
const
updateAnnualPlanTotalRow
=
()
=>
{
const
initFinancialRowTotal
=
()
=>
{
annualPlanIndicators
.
value
.
forEach
((
totalRow
)
=>
{
// 仅计算可研表格的非合计行
if
(
!
totalRow
.
isTotal
||
!
totalRow
.
parentCode
)
return
;
financialIndicators
.
value
.
forEach
(
totalRow
.
total
=
0
;
(
row
)
=>
!
row
.
isTotal
&&
updateFinancialRowTotal
(
row
),
dynamicTimeList
.
value
.
forEach
((
time
)
=>
(
totalRow
[
time
]
=
0
));
totalRow
.
parentCode
.
forEach
((
code
)
=>
{
const
childRow
=
annualPlanIndicators
.
value
.
find
(
(
item
)
=>
item
.
indicatorName
===
code
,
);
);
if
(
childRow
)
{
// 仅更新可研表格的合计行
totalRow
.
total
+=
Number
(
childRow
.
total
)
||
0
;
updateAllFinancialTotalRow
();
dynamicTimeList
.
value
.
forEach
((
time
)
=>
{
// 同步到可研的提交字段
totalRow
[
time
]
+=
Number
(
childRow
[
time
])
||
0
;
formData
.
kyjcxx
=
[...
financialIndicators
.
value
];
});
}
});
});
};
};
// ========== 批量初始化所有行合计 ==========
// ========== 【专属方法】可研/决策信息表格:数据变更回调(独立,仅影响自身) ==========
const
initAllRowTotal
=
()
=>
{
const
handleFinancialChange
=
(
currentRow
)
=>
{
financialIndicators
.
value
.
forEach
(
if
(
isPreview
.
value
)
return
;
(
row
)
=>
!
row
.
isTotal
&&
updateRowTotal
(
row
),
// 仅更新可研表格的当前行合计
);
updateFinancialRowTotal
(
currentRow
);
updateAllTotalRow
();
// 仅更新可研表格的全量合计行
updateAllFinancialTotalRow
();
// 仅同步可研表格的提交字段
formData
.
kyjcxx
=
[...
financialIndicators
.
value
];
};
annualPlanIndicators
.
value
.
forEach
(
// ========== 【专属方法】项目年度计划表格:子组件回调(独立,仅影响自身) ==========
(
row
)
=>
!
row
.
isTotal
&&
updateRowTotal
(
row
),
const
handleAnnualPlanTableChange
=
(
newData
)
=>
{
);
if
(
isPreview
.
value
)
return
;
updateAnnualPlanTotalRow
();
// 仅接收子组件的年度计划数据,与可研表格无任何交互
formData
.
xmndjh
=
[...
newData
];
};
};
// ========== 回填财务表格数据(按序号+指标名双匹配,避免错位) ==========
// ========== 动态时间生成:仅生成一次,两个表格共用表头(无数据关联) ==========
const
generateDynamicTime
=
()
=>
{
const
now
=
new
Date
();
const
currentYear
=
now
.
getFullYear
();
const
currentMonth
=
now
.
getMonth
()
+
1
;
const
timeList
=
[];
for
(
let
i
=
0
;
i
<=
15
;
i
++
)
{
if
(
timeHeaderType
.
value
===
"year"
)
{
timeList
.
push
(
String
(
currentYear
+
i
));
}
else
{
const
calcYear
=
currentYear
+
Math
.
floor
((
currentMonth
+
i
-
1
)
/
12
);
const
calcMonth
=
((
currentMonth
+
i
-
1
)
%
12
)
+
1
;
timeList
.
push
(
`
${
calcYear
}
-
${
calcMonth
.
toString
().
padStart
(
2
,
"0"
)}
`
);
}
}
dynamicTimeList
.
value
=
timeList
;
// 两个表格分别独立初始化,无互相调用
initFinancialTable
();
initAnnualPlanTable
();
};
// ========== 回填逻辑:完全隔离,各自处理自身表格 ==========
// 1. 可研/决策信息表格:专属回填(独立)
const
fillFinancialTable
=
(
backfillData
)
=>
{
const
fillFinancialTable
=
(
backfillData
)
=>
{
if
(
!
Array
.
isArray
(
backfillData
)
||
backfillData
.
length
===
0
)
return
;
if
(
!
Array
.
isArray
(
backfillData
)
||
backfillData
.
length
===
0
)
return
;
financialIndicators
.
value
.
forEach
((
frontRow
)
=>
{
financialIndicators
.
value
.
forEach
((
frontRow
)
=>
{
...
@@ -1059,26 +1268,28 @@ const fillFinancialTable = (backfillData) => {
...
@@ -1059,26 +1268,28 @@ const fillFinancialTable = (backfillData) => {
frontRow
[
time
]
=
Number
(
backfillRow
[
time
])
||
0
;
frontRow
[
time
]
=
Number
(
backfillRow
[
time
])
||
0
;
});
});
});
});
initAllRowTotal
();
// 仅初始化可研表格的合计
initFinancialRowTotal
();
};
};
//
========== 回填年度计划表格数据(按指标名匹配,避免错位) ==========
//
2. 项目年度计划表格:专属回填(独立,按id匹配,精准无错位)
const
fillAnnualPlanTable
=
(
backfillData
)
=>
{
const
fillAnnualPlanTable
=
(
backfillData
)
=>
{
if
(
!
Array
.
isArray
(
backfillData
)
||
backfillData
.
length
===
0
)
return
;
if
(
!
Array
.
isArray
(
backfillData
)
||
backfillData
.
length
===
0
)
return
;
annualPlanIndicators
.
value
.
forEach
((
frontRow
)
=>
{
// 先初始化年度计划表格的空数据
const
backfillRow
=
backfillData
.
find
(
initAnnualPlanTable
();
(
item
)
=>
item
.
indicatorName
===
frontRow
.
indicatorName
,
// 按唯一id匹配回填,避免indicatorName重复导致的错位
);
formData
.
xmndjh
.
forEach
((
frontRow
)
=>
{
const
backfillRow
=
backfillData
.
find
((
item
)
=>
item
.
id
===
frontRow
.
id
);
if
(
!
backfillRow
)
return
;
if
(
!
backfillRow
)
return
;
frontRow
.
total
=
Number
(
backfillRow
.
total
)
||
0
;
frontRow
.
total
=
Number
(
backfillRow
.
total
)
||
0
;
dynamicTimeList
.
value
.
forEach
((
time
)
=>
{
dynamicTimeList
.
value
.
forEach
((
time
)
=>
{
frontRow
[
time
]
=
Number
(
backfillRow
[
time
])
||
0
;
frontRow
[
time
]
=
backfillRow
[
time
]
!==
undefined
?
Number
(
backfillRow
[
time
])
||
0
:
0
;
});
});
});
});
initAllRowTotal
();
};
};
// ========== 业务方法:获取项目列表 ==========
// ========== 业务方法:获取项目列表
(通用)
==========
const
getProjectData
=
()
=>
{
const
getProjectData
=
()
=>
{
proxy
.
$post
({
proxy
.
$post
({
url
:
"/api/project/listProject"
,
url
:
"/api/project/listProject"
,
...
@@ -1090,80 +1301,86 @@ const getProjectData = () => {
...
@@ -1090,80 +1301,86 @@ const getProjectData = () => {
});
});
};
};
// ========== 选择项目同步名称 ==========
// ========== 选择项目同步名称
(通用)
==========
const
changeProject
=
(
val
)
=>
{
const
changeProject
=
(
val
)
=>
{
proxy
.
$post
({
proxy
.
$post
({
url
:
"/api/project/getProjectFinalInfo"
,
url
:
"/api/project/getProjectFinalInfo"
,
data
:
{
id
:
val
},
data
:
{
id
:
val
},
callback
:
(
data
)
=>
{
callback
:
(
data
)
=>
{
loading
.
value
=
false
;
loading
.
value
=
false
;
if
(
!
data
)
return
ElMessage
.
error
(
"未查询到
数据"
);
console
.
log
(
data
,
"项目详情
数据"
);
console
.
log
(
data
,
"data"
);
formData
.
projectName
=
data
.
projectName
||
""
;
formData
.
sbdw
=
data
.
sbdw
||
""
;
formData
.
xmgsmc
=
data
.
xmgsmc
||
""
;
formData
.
xmkgsjyj
=
data
.
xmkgsjyj
||
""
;
formData
.
xmjgsjyj
=
data
.
xmjgsjyj
||
""
;
formData
.
xmjd
=
data
.
xmjd
||
""
;
formData
.
yynxn
=
data
.
yynxn
||
""
;
formData
.
xmjsqy
=
data
.
xmjsqy
||
""
;
},
},
error
:
()
=>
{
error
:
()
=>
{
loading
.
value
=
false
;
loading
.
value
=
false
;
ElMessage
.
error
(
"获取
数据
失败"
);
ElMessage
.
error
(
"获取
项目详情
失败"
);
},
},
});
});
const
selectItem
=
projectList
.
value
.
find
((
item
)
=>
item
.
id
===
val
);
const
selectItem
=
projectList
.
value
.
find
((
item
)
=>
item
.
id
===
val
);
if
(
selectItem
)
formData
.
projectName
=
selectItem
.
projectName
;
if
(
selectItem
)
formData
.
projectName
=
selectItem
.
projectName
;
};
};
// ==========
核心修复:获取详情(编辑/预览),解决timeList未定义BUG
==========
// ==========
获取详情(编辑/预览):两个表格分别独立回填
==========
const
getJsqtzjcDetail
=
()
=>
{
const
getJsqtzjcDetail
=
()
=>
{
if
(
!
rcCgqyglId
.
value
)
return
;
if
(
!
rcCgqyglId
.
value
)
return
;
loading
.
value
=
true
;
loading
.
value
=
true
;
proxy
.
$post
({
proxy
.
$post
({
url
:
"/api/project/get
JsqtzjcInfo
"
,
url
:
"/api/project/get
Tzjh
"
,
data
:
{
id
:
rcCgqyglId
.
value
},
data
:
{
id
:
rcCgqyglId
.
value
},
callback
:
(
data
)
=>
{
callback
:
(
data
)
=>
{
loading
.
value
=
false
;
loading
.
value
=
false
;
if
(
!
data
)
return
ElMessage
.
error
(
"未查询到数据"
);
if
(
!
data
)
return
ElMessage
.
error
(
"未查询到数据"
);
Object
.
assign
(
formData
,
data
);
// 回填所有表单数据
console
.
log
(
data
,
"data"
);
// 核心修复:从后端kyjcxx提取时间列表,无则生成默认时间
Object
.
assign
(
formData
,
data
);
// 回填基础字段
// 步骤1:提取/生成时间列表(共用表头)
if
(
data
.
kyjcxx
&&
Array
.
isArray
(
data
.
kyjcxx
)
&&
data
.
kyjcxx
.
length
>
0
)
{
if
(
data
.
kyjcxx
&&
Array
.
isArray
(
data
.
kyjcxx
)
&&
data
.
kyjcxx
.
length
>
0
)
{
// 提取后端已有的时间字段(过滤非时间字段)
dynamicTimeList
.
value
=
Object
.
keys
(
data
.
kyjcxx
[
0
]).
filter
((
key
)
=>
const
firstRow
=
data
.
kyjcxx
[
0
];
dynamicTimeList
.
value
=
Object
.
keys
(
firstRow
).
filter
((
key
)
=>
/^
\d{4}(
-
\d{2})?
$/
.
test
(
key
),
/^
\d{4}(
-
\d{2})?
$/
.
test
(
key
),
);
);
}
else
{
}
else
{
generateDynamicTime
();
// 无数据则生成默认时间
generateDynamicTime
();
}
}
// 初始化表格后再回填数据
// 步骤2:两个表格分别独立初始化
if
(
dynamicTimeList
.
value
.
length
===
0
)
generateDynamicTime
();
if
(
dynamicTimeList
.
value
.
length
>
0
)
{
else
{
initFinancialTable
();
initFinancialTable
();
initAnnualPlanTable
();
initAnnualPlanTable
();
}
}
//
回填财务数据
//
步骤3:两个表格分别独立回填(完全隔离)
if
(
data
.
kyjcxx
)
fillFinancialTable
(
data
.
kyjcxx
);
if
(
data
.
kyjcxx
)
fillFinancialTable
(
data
.
kyjcxx
);
// 回填年度计划数据
if
(
data
.
xmndjh
)
fillAnnualPlanTable
(
data
.
xmndjh
);
if
(
data
.
xmndjh
)
fillAnnualPlanTable
(
data
.
xmndjh
);
},
},
error
:
()
=>
{
error
:
()
=>
{
loading
.
value
=
false
;
loading
.
value
=
false
;
ElMessage
.
error
(
"获取
数据
失败"
);
ElMessage
.
error
(
"获取
投资计划详情
失败"
);
},
},
});
});
};
};
// ==========
核心修改:保存表单,提交字段改为kyjcxx和xmndjh
==========
// ==========
保存表单:两个表格的提交数据完全独立拆分
==========
const
saveClick
=
()
=>
{
const
saveClick
=
()
=>
{
if
(
!
formData
.
projectId
)
return
ElMessage
.
warning
(
"请选择项目信息"
);
if
(
!
formData
.
projectId
)
return
ElMessage
.
warning
(
"请选择项目信息"
);
loading
.
value
=
true
;
loading
.
value
=
true
;
const
url
=
rcCgqyglId
.
value
const
url
=
rcCgqyglId
.
value
?
"/api/project/update
Jsqtzjc
"
?
"/api/project/update
Tzjh
"
:
"/api/project/create
Jsqtzjc
"
;
:
"/api/project/create
Tzjh
"
;
// 组装提交数据:
财务数据赋值给kyjcxx,年度计划数据赋值给xmndjh
// 组装提交数据:
两个表格的字段完全独立拆分,无任何混叠
const
submitData
=
{
const
submitData
=
{
...
formData
,
...
formData
,
projectId
:
String
(
formData
.
projectId
),
projectId
:
String
(
formData
.
projectId
),
// 1. 可研/决策信息表格:专属提交数据(仅自身字段)
kyjcxx
:
financialIndicators
.
value
.
map
((
row
)
=>
{
kyjcxx
:
financialIndicators
.
value
.
map
((
row
)
=>
{
const
filterRow
=
{
const
filterRow
=
{
serialNumber
:
row
.
serialNumber
,
serialNumber
:
row
.
serialNumber
,
...
@@ -1174,12 +1391,9 @@ const saveClick = () => {
...
@@ -1174,12 +1391,9 @@ const saveClick = () => {
dynamicTimeList
.
value
.
forEach
((
time
)
=>
(
filterRow
[
time
]
=
row
[
time
]));
dynamicTimeList
.
value
.
forEach
((
time
)
=>
(
filterRow
[
time
]
=
row
[
time
]));
return
filterRow
;
return
filterRow
;
}),
}),
xmndjh
:
annualPlanIndicators
.
value
.
map
((
row
)
=>
{
// 2. 项目年度计划表格:专属提交数据(仅自身字段,子组件绑定的xmndjh)
const
filterRow
=
{
xmndjh
:
formData
.
xmndjh
.
map
((
row
)
=>
{
indicatorName
:
row
.
indicatorName
,
const
filterRow
=
{
id
:
row
.
id
,
total
:
row
.
total
};
level
:
row
.
level
,
total
:
row
.
total
,
};
dynamicTimeList
.
value
.
forEach
((
time
)
=>
(
filterRow
[
time
]
=
row
[
time
]));
dynamicTimeList
.
value
.
forEach
((
time
)
=>
(
filterRow
[
time
]
=
row
[
time
]));
return
filterRow
;
return
filterRow
;
}),
}),
...
@@ -1200,18 +1414,19 @@ const saveClick = () => {
...
@@ -1200,18 +1414,19 @@ const saveClick = () => {
});
});
};
};
// ========== 辅助方法 ==========
// ========== 辅助方法
(通用)
==========
const
backClick
=
()
=>
router
.
back
(
-
1
);
const
backClick
=
()
=>
router
.
back
(
-
1
);
const
tableCellStyle
=
({
row
})
=>
const
tableCellStyle
=
({
row
})
=>
row
.
isTotal
?
{
background
:
"#f5f7fa"
,
fontWeight
:
"bold"
}
:
{};
row
.
isTotal
?
{
background
:
"#f5f7fa"
,
fontWeight
:
"bold"
}
:
{};
// ========== 页面初始化 ==========
// ========== 页面初始化
:两个表格分别独立处理
==========
onMounted
(()
=>
{
onMounted
(()
=>
{
getProjectData
();
getProjectData
();
if
(
rcCgqyglId
.
value
)
{
if
(
rcCgqyglId
.
value
)
{
setTimeout
(()
=>
getJsqtzjcDetail
(),
100
);
setTimeout
(()
=>
getJsqtzjcDetail
(),
100
);
}
else
{
}
else
{
generateDynamicTime
();
// 新增模式直接生成时间
// 新增模式:仅生成一次时间,两个表格分别独立初始化
generateDynamicTime
();
}
}
});
});
</
script
>
</
script
>
...
@@ -1239,7 +1454,7 @@ onMounted(() => {
...
@@ -1239,7 +1454,7 @@ onMounted(() => {
border-radius: 4px;
border-radius: 4px;
}
}
// 表格样式优化
// 表格样式优化
:两个表格统一样式,逻辑独立
:deep(.el-table-cell) {
:deep(.el-table-cell) {
padding-left: 8px !important;
padding-left: 8px !important;
box-sizing: border-box;
box-sizing: border-box;
...
@@ -1258,4 +1473,13 @@ onMounted(() => {
...
@@ -1258,4 +1473,13 @@ onMounted(() => {
:deep(.el-textarea__inner) {
:deep(.el-textarea__inner) {
width: 100% !important;
width: 100% !important;
}
}
// 年度计划表格子组件容器
.annualPlans {
width: 100%;
overflow-x: auto;
}
// 修复数字输入框样式
:deep(.el-input-number) {
width: 100%;
}
</
style
>
</
style
>
src/views/everydayPage/annualPlan.vue
0 → 100644
View file @
bc9d6526
<
template
>
<!-- 外层左右布局flex容器 -->
<div
class=
"annual-plan-wrap"
>
<!-- 左侧:数据驱动的原生表格(绑定右侧行合计值) -->
<div
class=
"left-table"
>
<table
class=
"investment-table"
>
<tbody>
<!-- 计划资金来源(全口径)模块 -->
<tr>
<td
rowspan=
"18"
class=
"first-col"
>
年度投资计划
</td>
<td
rowspan=
"16"
class=
"second-col"
>
计划投资完成及资金来源
</td>
<td
rowspan=
"9"
class=
"third-col"
>
计划资金来源(全口径)
</td>
<td
style=
"height: 48px"
></td>
<td
style=
"height: 48px"
></td>
<td
style=
"height: 48px"
>
合计
</td>
</tr>
<tr>
<td
rowspan=
"3"
>
资本金
</td>
<td>
小计
</td>
<td>
{{
getRowTotal
(
1
)
}}
万元
</td>
</tr>
<tr>
<td>
能建方*
</td>
<td>
{{
getRowTotal
(
2
)
}}
万元
</td>
</tr>
<tr>
<td>
外部股东*
</td>
<td>
{{
getRowTotal
(
3
)
}}
万元
</td>
</tr>
<tr>
<td
rowspan=
"2"
>
债权融资*
</td>
<td>
小计*
</td>
<td>
{{
getRowTotal
(
4
)
}}
万元
</td>
</tr>
<tr>
<td>
其中:非并表项目我方贷款/担保额*
</td>
<td>
{{
getRowTotal
(
5
)
}}
万元
</td>
</tr>
<tr>
<td>
回款再投入*
</td>
<td></td>
<td>
{{
getRowTotal
(
6
)
}}
万元
</td>
</tr>
<tr>
<td
rowspan=
"2"
>
其他*
</td>
<td>
小计*
</td>
<td>
{{
getRowTotal
(
7
)
}}
万元
</td>
</tr>
<tr>
<td>
其中:我方其他出资*
</td>
<td>
{{
getRowTotal
(
8
)
}}
万元
</td>
</tr>
<!-- 资金来源(新口径)模块 -->
<tr>
<td
rowspan=
"6"
class=
"third-col"
>
资金来源(新口径)
</td>
<td>
合计
</td>
<td></td>
<td>
{{
getRowTotal
(
9
)
}}
万元
</td>
</tr>
<tr>
<td
rowspan=
"3"
>
资本金
</td>
<td>
小计
</td>
<td>
{{
getRowTotal
(
10
)
}}
万元
</td>
</tr>
<tr>
<td>
能建方
</td>
<td>
{{
getRowTotal
(
11
)
}}
万元
</td>
</tr>
<tr>
<td>
外部股东
</td>
<td>
{{
getRowTotal
(
12
)
}}
万元
</td>
</tr>
<tr>
<td>
债权融资
</td>
<td></td>
<td>
{{
getRowTotal
(
13
)
}}
万元
</td>
</tr>
<tr>
<td>
回款再投入
</td>
<td></td>
<td>
{{
getRowTotal
(
14
)
}}
万元
</td>
</tr>
<tr>
<td>
其他
</td>
<td></td>
<td></td>
<td>
{{
getRowTotal
(
15
)
}}
万元
</td>
</tr>
<!-- 合计与政府付费模块 -->
<tr>
<td>
合计
</td>
<td></td>
<td></td>
<td></td>
<td>
{{
getRowTotal
(
16
)
}}
万元
</td>
</tr>
<tr>
<td>
政府付费*
</td>
<td></td>
<td></td>
<td></td>
<td>
{{
getRowTotal
(
17
)
}}
万元
</td>
</tr>
</tbody>
</table>
</div>
<!-- 右侧:Element 时间输入表格(绑定父组件传递的数据源+动态时间) -->
<div
class=
"right-table"
>
<el-table
:data=
"modelValue"
style=
"width: 100%"
border
:cell-style=
"tableCellStyle"
:row-style=
"
{ height: '48px' }"
:header-row-style="{ height: '48px' }"
>
<el-table-column
v-for=
"time in dynamicTimeList"
:key=
"time"
:label=
"time"
width=
"160"
align=
"center"
>
<template
#
default=
"
{ row }">
<el-input-number
v-model=
"row[time]"
:min=
"0"
:precision=
"2"
controls-position=
"right"
@
change=
"handleChange(row)"
:disabled=
"isPreview"
style=
"width: 100%"
/>
</
template
>
</el-table-column>
</el-table>
</div>
</div>
</template>
<
script
setup
>
import
{
defineProps
,
defineEmits
,
watch
,
onMounted
}
from
"vue"
;
// 🔥 核心:接收父组件参数,v-model双向绑定核心(modelValue对应父组件v-model值)
const
props
=
defineProps
({
// 双向绑定的表格数据源(父组件formData.xmndjh)
modelValue
:
{
type
:
Array
,
default
:
()
=>
[],
},
// 父组件传递的动态时间列表(替代子组件内部定义)
dynamicTimeList
:
{
type
:
Array
,
default
:
()
=>
[],
},
// 预览状态(禁用输入)
isPreview
:
{
type
:
Boolean
,
default
:
false
,
},
});
// 🔥 核心:触发双向绑定更新+原有事件兼容
const
emit
=
defineEmits
([
"update:modelValue"
,
// v-model必须的更新事件,同步数据给父组件
"handleAnnualPlanChange"
,
// 保留原有事件,兼容父组件逻辑
]);
// 监听数据源变化(父组件回填时触发),确保合计值正确
watch
(
()
=>
props
.
modelValue
,
(
newVal
)
=>
{
if
(
newVal
.
length
===
0
)
return
;
// 父组件回填数据后,重新计算所有行合计
newVal
.
forEach
((
row
)
=>
{
if
(
row
)
{
row
.
total
=
props
.
dynamicTimeList
.
reduce
((
sum
,
time
)
=>
{
return
sum
+
(
Number
(
row
[
time
])
||
0
);
},
0
);
}
});
// 同步更新父组件数据
emit
(
"update:modelValue"
,
newVal
);
},
{
deep
:
true
,
immediate
:
true
},
);
// 获取对应行的合计值(父组件数据源,保留2位小数)
const
getRowTotal
=
(
index
)
=>
{
const
row
=
props
.
modelValue
[
index
-
1
];
return
row
?.
total
?
row
.
total
.
toFixed
(
2
)
:
"0.00"
;
};
onMounted
(()
=>
{
console
.
log
(
props
.
dynamicTimeList
,
" props.dynamicTimeList"
);
});
// 右侧数据变更:计算行合计 + 双向同步父组件 + 触发原有事件
const
handleChange
=
(
row
)
=>
{
// 计算当前行合计(适配父组件动态时间列表)
row
.
total
=
props
.
dynamicTimeList
.
reduce
((
sum
,
time
)
=>
{
return
sum
+
(
Number
(
row
[
time
])
||
0
);
},
0
);
};
// 合计行样式(和父组件表格样式统一)
const
tableCellStyle
=
({
row
})
=>
row
.
isTotal
?
{
background
:
"#f5f7fa"
,
fontWeight
:
"bold"
}
:
{};
</
script
>
<
style
scoped
lang=
"scss"
>
// 核心:左右布局样式
.annual-plan-wrap
{
display
:
flex
;
align-items
:
flex-start
;
gap
:
0
;
// 左右无缝衔接,视觉成一个整体
width
:
100%
;
box-sizing
:
border-box
;
padding
:
0
;
margin
:
0
;
overflow-x
:
auto
;
// 整体横向滚动,避免左右分离滚动
}
// 左侧原生表格容器:固定宽度不挤压
.left-table
{
flex-shrink
:
0
;
}
// 左侧原生表格样式(160px列宽 + 48px行高 + 无缝边框)
.investment-table
{
width
:
fit-content
;
border-collapse
:
collapse
;
border
:
1px
solid
#ebeef5
;
// 和父组件表格边框色统一
border-right
:
0
;
// 取消右侧边框,和右侧EL表格无缝衔接
}
.investment-table
td
{
width
:
160px
;
// 和右侧EL表格列宽完全统一
height
:
49px
;
// 匹配原有行高,避免错位
border
:
1px
solid
#ebeef5
;
// 和父组件表格边框色统一
padding
:
0
!
important
;
// 取消内边距,文字居中更整齐
text-align
:
center
;
vertical-align
:
middle
;
word-break
:
break-all
;
box-sizing
:
border-box
;
}
// 左侧表格层级背景色(保留原有样式)
.first-col
{
font-weight
:
bold
;
background-color
:
#f5f7fa
;
// 和父组件合计行背景统一
}
.second-col
{
background-color
:
#f5f7fa
;
}
.third-col
{
font-weight
:
500
;
background-color
:
#f5f7fa
;
}
// 右侧EL表格样式优化(和父组件完全统一:行高/边框/内边距)
:deep
(
.el-table
)
{
--el-table-border-color
:
#ebeef5
;
// 边框色和父组件表格一致
--el-table-row-height
:
48px
!
important
;
// 行高和左侧强制统一
border-left
:
0
;
// 取消左侧边框,和左侧无缝衔接
}
// 表头行高也强制48px,避免表头错位
:deep
(
.el-table__header
tr
),
:deep
(
.el-table__body
tr
)
{
height
:
48px
!
important
;
}
:deep
(
.el-table-cell
)
{
padding
:
0
!
important
;
// 内边距和左侧一致
text-align
:
center
;
vertical-align
:
middle
;
box-sizing
:
border-box
;
}
// 输入框适配行高,居中显示
:deep
(
.el-input-number
)
{
width
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
:deep
(
.el-input-number__input
)
{
text-align
:
right
;
padding-right
:
25px
;
width
:
90%
;
// 微调宽度,避免输入框溢出
}
// 去除多余样式
.flex
{
display
:
flex
;
}
</
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