明树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
02499d44
Commit
02499d44
authored
May 26, 2026
by
zhanghan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
111
parent
c3c6bcd6
Pipeline
#111969
passed with stage
in 18 seconds
Changes
2
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
510 additions
and
496 deletions
+510
-496
settings.local.json
.claude/settings.local.json
+5
-1
InvestmentRecoveryTable.vue
src/components/InvestmentRecoveryTable.vue
+505
-495
No files found.
.claude/settings.local.json
View file @
02499d44
...
@@ -2,7 +2,11 @@
...
@@ -2,7 +2,11 @@
"permissions"
:
{
"permissions"
:
{
"allow"
:
[
"allow"
:
[
"mcp__zai-mcp-server__analyze_image"
,
"mcp__zai-mcp-server__analyze_image"
,
"mcp__zai-mcp-server__extract_text_from_screenshot"
"mcp__zai-mcp-server__extract_text_from_screenshot"
,
"Read(//Users/**)"
,
"Bash(python3 -c ' *)"
,
"Bash(where python *)"
,
"Bash(where node *)"
]
]
}
}
}
}
src/components/InvestmentRecoveryTable.vue
View file @
02499d44
...
@@ -32,29 +32,81 @@
...
@@ -32,29 +32,81 @@
<!-- 年度更新表格的列 -->
<!-- 年度更新表格的列 -->
<template
v-if=
"tableType === 'year'"
>
<template
v-if=
"tableType === 'year'"
>
<!-- 截至年底应收 -->
<el-table-column
label=
"截至年底应收"
align=
"center"
>
<el-table-column
<el-table-column
v-for=
"col in yearColumns"
label=
"决策应收"
:key=
"col.prop"
prop=
"decisionReceivable"
:label=
"col.label"
min-width=
"150"
min-width=
"180"
align=
"center"
align=
"center"
>
>
<template
#
default=
"
{ row }">
<template
#
default=
"
{ row }">
<!-- 文本输入 -->
<span
v-if=
"row.isTotalRow || row.isParentRow"
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
decisionReceivable
)
}}
</span>
<el-input
<el-input
v-if=
"col.isText"
v-else
v-model=
"row[col.prop]"
v-model=
"row.decisionReceivable"
type=
"textarea"
type=
"number"
:rows=
"2"
:disabled=
"isPreview || row.noEdit"
:disabled=
"isPreview || row.noEdit"
placeholder=
"请输入"
placeholder=
"请输入"
style=
"width: 100%"
@
input=
"handleNumberInput(row)"
@
input=
"handleTextInput"
>
/>
<template
#
suffix
>
<!-- 数字输入 -->
<span>
{{
moneyUnit
}}
</span>
</
template
>
</el-input>
</template>
</el-table-column>
<el-table-column
label=
"计划应收"
prop=
"actualReceived"
min-width=
"150"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<span
v-if=
"row.isTotalRow || row.isParentRow"
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
actualReceived
)
}}
</span>
<el-input
v-else
v-model=
"row.actualReceived"
type=
"number"
:disabled=
"isPreview || row.noEdit"
placeholder=
"请输入"
@
input=
"handleNumberInput(row)"
>
<template
#
suffix
>
<span>
{{
moneyUnit
}}
</span>
</
template
>
</el-input>
</template>
</el-table-column>
</el-table-column>
<!-- 截至年底实收 -->
<el-table-column
label=
"截至年底实收"
prop=
"jzss"
min-width=
"150"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<span
v-if=
"row.isTotalRow || row.isParentRow"
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
jzss
)
}}
</span>
<el-input
<el-input
v-else
-if=
"!col.isCalculated"
v-else
v-model=
"row
[col.prop]
"
v-model=
"row
.jzss
"
type=
"number"
type=
"number"
:disabled=
"isPreview || row.noEdit"
:disabled=
"isPreview || row.noEdit"
placeholder=
"请输入"
placeholder=
"请输入"
...
@@ -64,12 +116,104 @@
...
@@ -64,12 +116,104 @@
<span>
{{
moneyUnit
}}
</span>
<span>
{{
moneyUnit
}}
</span>
</
template
>
</
template
>
</el-input>
</el-input>
<!-- 计算字段 -->
</template>
<span
v-else
class=
"calculated-value"
>
</el-table-column>
{{ formatCalculatedValue(row[col.prop], rateUnit) }}
<!-- 截至年底欠收 -->
<el-table-column
label=
"截至年底欠收"
align=
"center"
>
<el-table-column
label=
"决策应收-实收"
prop=
"shortfallDecision"
min-width=
"150"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<span
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
shortfallDecision
)
}}
</span>
</span>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"计划应收-实收"
prop=
"shortfallPlan"
min-width=
"150"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<span
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
shortfallPlan
)
}}
</span>
</
template
>
</el-table-column>
</el-table-column>
<!-- 完成率 -->
<el-table-column
label=
"完成率"
align=
"center"
>
<el-table-column
label=
"实收/决策应收"
prop=
"completionRateDecision"
min-width=
"150"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<span
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
completionRateDecision
,
rateUnit
)
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"实收/计划应收"
prop=
"completionRatePlan"
min-width=
"150"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<span
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
completionRatePlan
,
rateUnit
)
}}
</span>
</
template
>
</el-table-column>
</el-table-column>
<!-- 存在主要问题 -->
<el-table-column
label=
"存在主要问题"
prop=
"problems"
min-width=
"200"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<el-input
v-model=
"row.problems"
type=
"textarea"
:rows=
"2"
:disabled=
"isPreview || row.noEdit"
placeholder=
"请输入"
@
input=
"handleTextInput"
/>
</
template
>
</el-table-column>
<!-- 采取措施情况 -->
<el-table-column
label=
"采取措施情况"
prop=
"measures"
min-width=
"200"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<el-input
v-model=
"row.measures"
type=
"textarea"
:rows=
"2"
:disabled=
"isPreview || row.noEdit"
placeholder=
"请输入"
@
input=
"handleTextInput"
/>
</
template
>
</el-table-column>
</template>
</template>
<!-- 月度更新表格的列 -->
<!-- 月度更新表格的列 -->
...
@@ -81,16 +225,23 @@
...
@@ -81,16 +225,23 @@
:label="`${month}月`"
:label="`${month}月`"
align="center"
align="center"
>
>
<!--
应
收 -->
<!--
实
收 -->
<el-table-column
<el-table-column
:label=
"`
应
收`"
:label=
"`
实
收`"
:prop=
"`m$
{month}Receiv
able
`"
:prop=
"`m$
{month}Receiv
ed
`"
min-width="150"
min-width="150"
align="center"
align="center"
>
>
<template
#
default=
"
{ row }">
<template
#
default=
"
{ row }">
<span
v-if=
"row.isTotalRow || row.isParentRow"
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
[
`m${month
}
Received`
])
}}
<
/span
>
<
el
-
input
<
el
-
input
v-model=
"row[`m$
{month}Receivable`]"
v
-
else
v
-
model
=
"row[`m${month
}
Received`]"
type
=
"number"
type
=
"number"
:
disabled
=
"isPreview || row.noEdit"
:
disabled
=
"isPreview || row.noEdit"
placeholder
=
"请输入"
placeholder
=
"请输入"
...
@@ -102,16 +253,23 @@
...
@@ -102,16 +253,23 @@
<
/el-input
>
<
/el-input
>
<
/template
>
<
/template
>
<
/el-table-column
>
<
/el-table-column
>
<!--
实
收 -->
<!--
应
收
-->
<
el
-
table
-
column
<
el
-
table
-
column
:label=
"`
实
收`"
:
label
=
"`
应
收`"
:prop=
"`m${month}Receiv
ed
`"
:
prop
=
"`m${month
}
Receiv
able
`"
min
-
width
=
"150"
min
-
width
=
"150"
align
=
"center"
align
=
"center"
>
>
<
template
#
default
=
"{ row
}
"
>
<
template
#
default
=
"{ row
}
"
>
<
span
v
-
if
=
"row.isTotalRow || row.isParentRow"
class
=
"calculated-value"
>
{{
formatCalculatedValue
(
row
[
`m${month
}
Receivable`
])
}}
<
/span
>
<
el
-
input
<
el
-
input
v-model=
"row[`m$
{month}Received`]"
v
-
else
v
-
model
=
"row[`m${month
}
Receivable`]"
type
=
"number"
type
=
"number"
:
disabled
=
"isPreview || row.noEdit"
:
disabled
=
"isPreview || row.noEdit"
placeholder
=
"请输入"
placeholder
=
"请输入"
...
@@ -126,36 +284,38 @@
...
@@ -126,36 +284,38 @@
<
/el-table-column
>
<
/el-table-column
>
<!--
本年累计
-->
<!--
本年累计
-->
<
el
-
table
-
column
label
=
"本年累计"
align
=
"center"
>
<
el
-
table
-
column
<
el
-
table
-
column
label=
"本年累计(实收)
"
label
=
"实收
"
prop
=
"yearTotal"
prop
=
"yearTotal"
min-width=
"18
0"
min
-
width
=
"15
0"
align
=
"center"
align
=
"center"
>
>
<
template
#
default
=
"{ row
}
"
>
<
template
#
default
=
"{ row
}
"
>
<span
v-if=
"row.isTotalRow"
class=
"calculated-value"
>
<
span
class
=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
yearTotal
)
}}
{{
formatCalculatedValue
(
row
.
yearTotal
)
}}
<
/span
>
<
/span
>
<el-input
v-else
v-model=
"row.yearTotal"
type=
"number"
:disabled=
"isPreview || row.noEdit || row.autoCalcYearTotal"
placeholder=
"自动计算"
@
input=
"handleYearTotalInput(row)"
>
<template
#
suffix
>
<span>
{{
moneyUnit
}}
</span>
<
/template
>
<
/template
>
</el-input>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"应收"
prop
=
"yearTotalReceivable"
min
-
width
=
"150"
align
=
"center"
>
<
template
#
default
=
"{ row
}
"
>
<
span
class
=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
yearTotalReceivable
)
}}
<
/span
>
<
/template
>
<
/template
>
<
/el-table-column
>
<
/el-table-column
>
<
/el-table-column
>
<!-- 本年完成率
(分组)
-->
<!--
本年完成率
-->
<
el
-
table
-
column
label
=
"本年完成率"
align
=
"center"
>
<
el
-
table
-
column
label
=
"本年完成率"
align
=
"center"
>
<
el
-
table
-
column
<
el
-
table
-
column
label=
"
本年累计/本年决策
"
label
=
"
累计实收/累计应收
"
prop=
"yearCompletionRate
Decision
"
prop
=
"yearCompletionRate
Receivable
"
min
-
width
=
"180"
min
-
width
=
"180"
align
=
"center"
align
=
"center"
>
>
...
@@ -163,7 +323,7 @@
...
@@ -163,7 +323,7 @@
<
span
class
=
"calculated-value"
>
<
span
class
=
"calculated-value"
>
{{
{{
formatCalculatedValue
(
formatCalculatedValue
(
row
.
yearCompletionRate
Decision
,
row
.
yearCompletionRate
Receivable
,
rateUnit
,
rateUnit
,
)
)
}}
}}
...
@@ -171,7 +331,7 @@
...
@@ -171,7 +331,7 @@
<
/template
>
<
/template
>
<
/el-table-column
>
<
/el-table-column
>
<
el
-
table
-
column
<
el
-
table
-
column
label=
"
本年累计
/本年计划"
label
=
"
累计实收
/本年计划"
prop
=
"yearCompletionRatePlan"
prop
=
"yearCompletionRatePlan"
min
-
width
=
"180"
min
-
width
=
"180"
align
=
"center"
align
=
"center"
...
@@ -194,69 +354,37 @@
...
@@ -194,69 +354,37 @@
align
=
"center"
align
=
"center"
>
>
<
template
#
default
=
"{ row
}
"
>
<
template
#
default
=
"{ row
}
"
>
<span
v-if=
"row.isTotalRow"
class=
"calculated-value"
>
<
span
class
=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
invoiceCompleted
)
}}
</span>
<span
v-else
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
invoiceCompleted
)
}}
{{
formatCalculatedValue
(
row
.
invoiceCompleted
)
}}
<
/span
>
<
/span
>
<
/template
>
<
/template
>
<
/el-table-column
>
<
/el-table-column
>
<!-- 开累完成率(分组) -->
<!--
开累完成率
-->
<el-table-column
label=
"开累完成率"
min-width=
"180"
align=
"center"
>
<
el
-
table
-
column
<
el
-
table
-
column
label=
"开累完成/开累决策
"
label
=
"开累完成率
"
prop=
"invoiceCompletionRateDecision
"
prop
=
"invoiceCompletionRate
"
min
-
width
=
"180"
min
-
width
=
"180"
align
=
"center"
align
=
"center"
>
>
<
template
#
default
=
"{ row
}
"
>
<
template
#
default
=
"{ row
}
"
>
<
span
class
=
"calculated-value"
>
<
span
class
=
"calculated-value"
>
{{
{{
formatCalculatedValue
(
row
.
invoiceCompletionRate
,
rateUnit
)
}}
formatCalculatedValue
(
row
.
invoiceCompletionRateDecision
,
rateUnit
,
)
}}
<
/span
>
<
/span
>
<
/template
>
<
/template
>
<
/el-table-column
>
<
/el-table-column
>
<el-table-column
label=
"开累完成/开累计划"
prop=
"invoiceCompletionRatePlan"
min-width=
"180"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<span
class=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
invoiceCompletionRatePlan
,
rateUnit
)
}}
</span>
</
template
>
</el-table-column>
</el-table-column>
<!--
欠收金额
-->
<!--
欠收金额
-->
<
el
-
table
-
column
<
el
-
table
-
column
label
=
"欠收金额"
label
=
"欠收金额"
prop
=
"shortfallAmount"
prop
=
"shortfallAmount"
min-width=
"1
8
0"
min
-
width
=
"1
5
0"
align
=
"center"
align
=
"center"
>
>
<
template
#
default
=
"{ row
}
"
>
<
template
#
default
=
"{ row
}
"
>
<el-input
<
span
class
=
"calculated-value"
>
v-model=
"row.shortfallAmount"
{{
formatCalculatedValue
(
row
.
shortfallAmount
)
}}
type=
"number"
<
/span
>
:disabled=
"isPreview || row.noEdit"
placeholder=
"请输入"
@
input=
"handleShortfallAmountInput(row)"
>
<template
#
suffix
>
<span>
{{
moneyUnit
}}
</span>
</
template
>
</el-input>
<
/template
>
<
/template
>
<
/el-table-column
>
<
/el-table-column
>
...
@@ -268,7 +396,14 @@
...
@@ -268,7 +396,14 @@
align
=
"center"
align
=
"center"
>
>
<
template
#
default
=
"{ row
}
"
>
<
template
#
default
=
"{ row
}
"
>
<
span
v
-
if
=
"row.isTotalRow || row.isParentRow"
class
=
"calculated-value"
>
{{
formatCalculatedValue
(
row
.
contractTotalAmount
)
}}
<
/span
>
<
el
-
input
<
el
-
input
v
-
else
v
-
model
=
"row.contractTotalAmount"
v
-
model
=
"row.contractTotalAmount"
type
=
"number"
type
=
"number"
:
disabled
=
"isPreview || row.noEdit"
:
disabled
=
"isPreview || row.noEdit"
...
@@ -319,7 +454,14 @@
...
@@ -319,7 +454,14 @@
align
=
"center"
align
=
"center"
>
>
<
template
#
default
=
"{ row
}
"
>
<
template
#
default
=
"{ row
}
"
>
<
span
v
-
if
=
"row.isTotalRow || row.isParentRow"
class
=
"calculated-value"
>
{{
formatCalculatedValue
(
row
[
`m${month
}
Decision`
])
}}
<
/span
>
<
el
-
input
<
el
-
input
v
-
else
v
-
model
=
"row[`m${month
}
Decision`]"
v
-
model
=
"row[`m${month
}
Decision`]"
type
=
"number"
type
=
"number"
:
disabled
=
"isPreview || row.noEdit"
:
disabled
=
"isPreview || row.noEdit"
...
@@ -340,7 +482,14 @@
...
@@ -340,7 +482,14 @@
align
=
"center"
align
=
"center"
>
>
<
template
#
default
=
"{ row
}
"
>
<
template
#
default
=
"{ row
}
"
>
<
span
v
-
if
=
"row.isTotalRow || row.isParentRow"
class
=
"calculated-value"
>
{{
formatCalculatedValue
(
row
[
`m${month
}
Plan`
])
}}
<
/span
>
<
el
-
input
<
el
-
input
v
-
else
v
-
model
=
"row[`m${month
}
Plan`]"
v
-
model
=
"row[`m${month
}
Plan`]"
type
=
"number"
type
=
"number"
:
disabled
=
"isPreview || row.noEdit"
:
disabled
=
"isPreview || row.noEdit"
...
@@ -422,49 +571,41 @@ const props = defineProps({
...
@@ -422,49 +571,41 @@ const props = defineProps({
}
,
}
,
tableType
:
{
tableType
:
{
type
:
String
,
type
:
String
,
default
:
"year"
,
// 'year' 或 'month' 或 'plan'
default
:
"year"
,
validator
:
(
val
)
=>
[
"year"
,
"month"
,
"plan"
].
includes
(
val
),
validator
:
(
val
)
=>
[
"year"
,
"month"
,
"plan"
].
includes
(
val
),
}
,
}
,
tableTitle
:
{
tableTitle
:
{
type
:
String
,
type
:
String
,
default
:
""
,
default
:
""
,
}
,
}
,
// 投资回收计划数据(用于自动填充本年计划、开累计划)
planData
:
{
planData
:
{
type
:
Object
,
type
:
Object
,
default
:
()
=>
({
}
),
default
:
()
=>
({
}
),
}
,
}
,
// 投资回收决策数据(用于自动填充本年决策、开累决策)
decisionData
:
{
decisionData
:
{
type
:
Object
,
type
:
Object
,
default
:
()
=>
({
}
),
default
:
()
=>
({
}
),
}
,
}
,
// 去年投资回收计划数据(用于获取前年数据)
lastYearPlanData
:
{
lastYearPlanData
:
{
type
:
Object
,
type
:
Object
,
default
:
()
=>
({
}
),
default
:
()
=>
({
}
),
}
,
}
,
// 当前年份
currentYear
:
{
currentYear
:
{
type
:
[
String
,
Number
],
type
:
[
String
,
Number
],
default
:
""
,
default
:
""
,
}
,
}
,
// 投资回收完成情况年度计划数据(用于获取年度计划的合计决策值)
yearlyPlanData
:
{
yearlyPlanData
:
{
type
:
Object
,
type
:
Object
,
default
:
()
=>
({
}
),
default
:
()
=>
({
}
),
}
,
}
,
// 投资回收完成情况年度更新数据(用于获取截至年底实收值)
yearlyCompletionData
:
{
yearlyCompletionData
:
{
type
:
Object
,
type
:
Object
,
default
:
()
=>
({
}
),
default
:
()
=>
({
}
),
}
,
}
,
// 金额单位(默认万元)
moneyUnit
:
{
moneyUnit
:
{
type
:
String
,
type
:
String
,
default
:
"万元"
,
default
:
"万元"
,
}
,
}
,
// 利率单位(默认%)
rateUnit
:
{
rateUnit
:
{
type
:
String
,
type
:
String
,
default
:
"%"
,
default
:
"%"
,
...
@@ -475,72 +616,19 @@ const emit = defineEmits(["update:modelValue"]);
...
@@ -475,72 +616,19 @@ const emit = defineEmits(["update:modelValue"]);
const
tableDataRef
=
ref
([]);
const
tableDataRef
=
ref
([]);
// 年度表格列配置
const
yearColumns
=
computed
(()
=>
[
{
prop
:
"decisionReceivable"
,
label
:
"截至年底应收决策应收"
,
width
:
160
,
isText
:
false
,
isCalculated
:
false
,
},
{
prop
:
"actualReceived"
,
label
:
"截至年底计划应收"
,
width
:
140
,
isText
:
false
,
isCalculated
:
false
,
},
{
prop
:
"jzss"
,
label
:
"截至(具体年份)年底实收"
,
width
:
180
,
isText
:
false
,
isCalculated
:
false
,
},
{
prop
:
"shortfall"
,
label
:
"欠收(决策应收-实收)"
,
width
:
180
,
isText
:
false
,
isCalculated
:
true
,
},
{
prop
:
"completionRate"
,
label
:
"完成率"
,
width
:
120
,
isText
:
false
,
isCalculated
:
true
,
},
{
prop
:
"problems"
,
label
:
"存在主要问题"
,
width
:
200
,
isText
:
true
,
isCalculated
:
false
,
},
{
prop
:
"measures"
,
label
:
"采取措施情况"
,
width
:
200
,
isText
:
true
,
isCalculated
:
false
,
},
]);
// 格式化计算值
const
formatCalculatedValue
=
(
value
,
suffix
=
""
)
=>
{
const
formatCalculatedValue
=
(
value
,
suffix
=
""
)
=>
{
if
(
value
===
null
||
value
===
undefined
||
isNaN
(
value
))
return
"-"
;
if
(
value
===
null
||
value
===
undefined
||
isNaN
(
value
))
return
"-"
;
return
`${Number(value).toFixed(2)
}
${suffix
}
`
;
return
`${Number(value).toFixed(2)
}
${suffix
}
`
;
}
;
}
;
// 初始化行数据
const
initRowData
=
(
indicator
,
index
,
sourceRow
=
{
}
)
=>
{
const
initRowData
=
(
indicator
,
index
,
sourceRow
=
{
}
)
=>
{
const
baseRow
=
{
const
baseRow
=
{
serialNumber
:
indicator
.
xh
||
index
+
1
,
serialNumber
:
indicator
.
xh
||
index
+
1
,
indicatorName
:
indicator
.
name
,
indicatorName
:
indicator
.
name
,
noEdit
:
indicator
.
noEdit
||
false
,
noEdit
:
indicator
.
noEdit
||
false
,
isTotalRow
:
indicator
.
isTotalRow
||
false
,
isTotalRow
:
indicator
.
isTotalRow
||
false
,
isParentRow
:
indicator
.
isParentRow
||
false
,
isChild
:
indicator
.
isChild
||
false
,
}
;
}
;
if
(
props
.
tableType
===
"year"
)
{
if
(
props
.
tableType
===
"year"
)
{
...
@@ -548,14 +636,18 @@ const initRowData = (indicator, index, sourceRow = {}) => {
...
@@ -548,14 +636,18 @@ const initRowData = (indicator, index, sourceRow = {}) => {
...
baseRow
,
...
baseRow
,
decisionReceivable
:
sourceRow
.
decisionReceivable
||
null
,
decisionReceivable
:
sourceRow
.
decisionReceivable
||
null
,
actualReceived
:
sourceRow
.
actualReceived
||
null
,
actualReceived
:
sourceRow
.
actualReceived
||
null
,
jzss
:
sourceRow
.
jzss
||
null
,
shortfallDecision
:
sourceRow
.
shortfallDecision
||
null
,
shortfallPlan
:
sourceRow
.
shortfallPlan
||
null
,
completionRateDecision
:
sourceRow
.
completionRateDecision
||
null
,
completionRatePlan
:
sourceRow
.
completionRatePlan
||
null
,
// backward compat
shortfall
:
sourceRow
.
shortfall
||
null
,
shortfall
:
sourceRow
.
shortfall
||
null
,
completionRate
:
sourceRow
.
completionRate
||
null
,
completionRate
:
sourceRow
.
completionRate
||
null
,
problems
:
sourceRow
.
problems
||
""
,
problems
:
sourceRow
.
problems
||
""
,
measures
:
sourceRow
.
measures
||
""
,
measures
:
sourceRow
.
measures
||
""
,
jzss
:
sourceRow
.
jzss
||
null
,
}
;
}
;
}
else
if
(
props
.
tableType
===
"plan"
)
{
}
else
if
(
props
.
tableType
===
"plan"
)
{
// 计划表格
const
monthData
=
{
}
;
const
monthData
=
{
}
;
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
monthData
[
`m${i
}
Decision`
]
=
sourceRow
[
`m${i
}
Decision`
]
||
null
;
monthData
[
`m${i
}
Decision`
]
=
sourceRow
[
`m${i
}
Decision`
]
||
null
;
...
@@ -569,7 +661,6 @@ const initRowData = (indicator, index, sourceRow = {}) => {
...
@@ -569,7 +661,6 @@ const initRowData = (indicator, index, sourceRow = {}) => {
differenceExplanation
:
sourceRow
.
differenceExplanation
||
""
,
differenceExplanation
:
sourceRow
.
differenceExplanation
||
""
,
}
;
}
;
}
else
{
}
else
{
// 月度表格
const
monthData
=
{
}
;
const
monthData
=
{
}
;
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
monthData
[
`m${i
}
Receivable`
]
=
sourceRow
[
`m${i
}
Receivable`
]
||
null
;
monthData
[
`m${i
}
Receivable`
]
=
sourceRow
[
`m${i
}
Receivable`
]
||
null
;
...
@@ -579,176 +670,165 @@ const initRowData = (indicator, index, sourceRow = {}) => {
...
@@ -579,176 +670,165 @@ const initRowData = (indicator, index, sourceRow = {}) => {
...
baseRow
,
...
baseRow
,
...
monthData
,
...
monthData
,
yearTotal
:
sourceRow
.
yearTotal
||
null
,
yearTotal
:
sourceRow
.
yearTotal
||
null
,
yearCompletionRateDecision
:
sourceRow
.
yearCompletionRateDecision
||
null
,
yearTotalReceivable
:
sourceRow
.
yearTotalReceivable
||
null
,
yearCompletionRateReceivable
:
sourceRow
.
yearCompletionRateReceivable
||
null
,
yearCompletionRatePlan
:
sourceRow
.
yearCompletionRatePlan
||
null
,
yearCompletionRatePlan
:
sourceRow
.
yearCompletionRatePlan
||
null
,
invoiceCompleted
:
sourceRow
.
invoiceCompleted
||
null
,
invoiceCompleted
:
sourceRow
.
invoiceCompleted
||
null
,
invoiceCompletionRateDecision
:
invoiceCompletionRate
:
sourceRow
.
invoiceCompletionRate
||
null
,
sourceRow
.
invoiceCompletionRateDecision
||
null
,
invoiceCompletionRatePlan
:
sourceRow
.
invoiceCompletionRatePlan
||
null
,
shortfallAmount
:
sourceRow
.
shortfallAmount
||
null
,
shortfallAmount
:
sourceRow
.
shortfallAmount
||
null
,
contractTotalAmount
:
sourceRow
.
contractTotalAmount
||
null
,
contractTotalAmount
:
sourceRow
.
contractTotalAmount
||
null
,
planDifference
:
sourceRow
.
planDifference
||
""
,
planDifference
:
sourceRow
.
planDifference
||
""
,
yearDecision
:
sourceRow
.
yearDecision
||
null
,
// 本年决策目标
yearPlan
:
sourceRow
.
yearPlan
||
null
,
// 本年计划目标
invoiceDecision
:
sourceRow
.
invoiceDecision
||
null
,
// 开累决策目标
invoicePlan
:
sourceRow
.
invoicePlan
||
null
,
// 开累计划目标
autoCalcYearTotal
:
indicator
.
autoCalcYearTotal
!==
false
,
// 默认自动计算本年累计
}
;
}
;
}
}
}
;
}
;
// 指标列表
const
indicators
=
[
const
indicators
=
[
{
name
:
"政府付费"
,
noEdit
:
false
,
xh
:
"1"
},
{
{
name
:
"建设期"
,
noEdit
:
false
,
xh
:
"1.1"
},
name
:
"政府付费"
,
{
name
:
"运营期"
,
noEdit
:
false
,
xh
:
"1.2"
},
noEdit
:
false
,
xh
:
"1"
,
isParentRow
:
true
,
childNames
:
[
"建设期"
,
"运营期"
],
}
,
{
name
:
"建设期"
,
noEdit
:
false
,
xh
:
"1.1"
,
isChild
:
true
}
,
{
name
:
"运营期"
,
noEdit
:
false
,
xh
:
"1.2"
,
isChild
:
true
}
,
{
name
:
"使用者付费"
,
noEdit
:
false
,
xh
:
"2"
}
,
{
name
:
"使用者付费"
,
noEdit
:
false
,
xh
:
"2"
}
,
{
name
:
"投资价
款
"
,
noEdit
:
false
,
xh
:
"3"
},
{
name
:
"投资价
差
"
,
noEdit
:
false
,
xh
:
"3"
}
,
{
name
:
"参股项目投资回收"
,
noEdit
:
false
,
xh
:
"4"
}
,
{
name
:
"参股项目投资回收"
,
noEdit
:
false
,
xh
:
"4"
}
,
{
name
:
"代建工程款"
,
noEdit
:
false
,
xh
:
"5"
}
,
{
name
:
"代建工程款"
,
noEdit
:
false
,
xh
:
"5"
}
,
{
name
:
"其他"
,
noEdit
:
false
,
xh
:
"6"
}
,
{
name
:
"其他"
,
noEdit
:
false
,
xh
:
"6"
}
,
{
name
:
"合计"
,
isTotalRow
:
true
,
noEdit
:
true
,
xh
:
"7"
}
,
{
name
:
"合计"
,
isTotalRow
:
true
,
noEdit
:
true
,
xh
:
"7"
}
,
];
];
//
从计划数据和决策数据中获取对应指标的值
//
计算父行(政府付费 = 建设期 + 运营期)
const
getIndicatorValue
=
(
indicatorName
,
dataSource
,
type
)
=>
{
const
calculateParentRows
=
(
)
=>
{
if
(
!
dataSource
||
!
dataSource
.
tableData
)
return
0
;
const
parentRows
=
tableDataRef
.
value
.
filter
((
row
)
=>
row
.
isParentRow
)
;
parentRows
.
forEach
((
parentRow
)
=>
{
const
row
=
dataSource
.
tableData
.
find
(
const
indicator
=
indicators
.
find
(
(
r
)
=>
r
.
indicatorName
===
indicatorName
,
(
i
)
=>
i
.
name
===
parentRow
.
indicatorName
,
);
);
if
(
!
row
)
return
0
;
if
(
!
indicator
||
!
indicator
.
childNames
)
return
;
// 根据类型返回对应字段的值
if
(
type
===
"yearDecision"
)
{
// 本年决策:从决策数据中获取当前年度的合计
// 决策数据的时间列表是 ["一季度", "二季度", "三季度", "四季度"]
// 合计 = 一季度 + 二季度 + 三季度 + 四季度
const
q1
=
parseFloat
(
row
[
"一季度"
])
||
0
;
const
q2
=
parseFloat
(
row
[
"二季度"
])
||
0
;
const
q3
=
parseFloat
(
row
[
"三季度"
])
||
0
;
const
q4
=
parseFloat
(
row
[
"四季度"
])
||
0
;
return
q1
+
q2
+
q3
+
q4
;
}
else
if
(
type
===
"yearPlan"
)
{
// 本年计划:从去年投资回收计划数据中获取合计值
return
parseFloat
(
row
.
a1
)
||
0
;
}
else
if
(
type
===
"invoiceDecision"
)
{
// 开累决策:从决策数据中获取开累值
// 这里可能是累计值,需要根据实际业务逻辑确定
const
q1
=
parseFloat
(
row
[
"一季度"
])
||
0
;
const
q2
=
parseFloat
(
row
[
"二季度"
])
||
0
;
const
q3
=
parseFloat
(
row
[
"三季度"
])
||
0
;
const
q4
=
parseFloat
(
row
[
"四季度"
])
||
0
;
return
q1
+
q2
+
q3
+
q4
;
// 暂时用年度合计
}
else
if
(
type
===
"invoicePlan"
)
{
// 开累计划:从计划数据中获取开累值
return
parseFloat
(
row
.
a1
)
||
0
;
// 暂时用年度合计
}
return
0
;
};
// 自动填充决策和计划数据
const
childRows
=
tableDataRef
.
value
.
filter
((
r
)
=>
const
autoFillDecisionAndPlan
=
()
=>
{
indicator
.
childNames
.
includes
(
r
.
indicatorName
),
if
(
props
.
tableType
!==
"month"
)
return
;
tableDataRef
.
value
.
forEach
((
row
)
=>
{
if
(
row
.
isTotalRow
||
row
.
noEdit
)
return
;
// 自动填充本年决策(从决策数据获取)
if
(
props
.
decisionData
&&
Object
.
keys
(
props
.
decisionData
).
length
>
0
)
{
row
.
yearDecision
=
getIndicatorValue
(
row
.
indicatorName
,
props
.
decisionData
,
"yearDecision"
,
);
);
}
// 自动填充本年计划(从去年投资回收计划数据获取)
if
(
props
.
tableType
===
"year"
)
{
if
(
parentRow
.
decisionReceivable
=
childRows
.
reduce
(
props
.
lastYearPlanData
&&
(
sum
,
r
)
=>
sum
+
(
parseFloat
(
r
.
decisionReceivable
)
||
0
),
Object
.
keys
(
props
.
lastYearPlanData
).
length
>
0
0
,
)
{
);
row
.
yearPlan
=
getIndicatorValue
(
parentRow
.
actualReceived
=
childRows
.
reduce
(
row
.
indicatorName
,
(
sum
,
r
)
=>
sum
+
(
parseFloat
(
r
.
actualReceived
)
||
0
),
props
.
lastYearPlanData
,
0
,
"yearPlan"
,
);
parentRow
.
jzss
=
childRows
.
reduce
(
(
sum
,
r
)
=>
sum
+
(
parseFloat
(
r
.
jzss
)
||
0
),
0
,
);
const
dr
=
parentRow
.
decisionReceivable
;
const
pr
=
parentRow
.
actualReceived
;
const
jz
=
parentRow
.
jzss
;
parentRow
.
shortfallDecision
=
dr
-
jz
;
parentRow
.
shortfallPlan
=
pr
-
jz
;
parentRow
.
completionRateDecision
=
dr
>
0
?
(
jz
/
dr
)
*
100
:
0
;
parentRow
.
completionRatePlan
=
pr
>
0
?
(
jz
/
pr
)
*
100
:
0
;
}
else
if
(
props
.
tableType
===
"plan"
)
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
parentRow
[
`m${i
}
Decision`
]
=
childRows
.
reduce
(
(
sum
,
r
)
=>
sum
+
(
parseFloat
(
r
[
`m${i
}
Decision`
])
||
0
),
0
,
);
);
}
else
if
(
props
.
planData
&&
Object
.
keys
(
props
.
planData
).
length
>
0
)
{
parentRow
[
`m${i
}
Plan`
]
=
childRows
.
reduce
(
// 如果没有去年数据,则使用当前年计划数据作为后备
(
sum
,
r
)
=>
sum
+
(
parseFloat
(
r
[
`m${i
}
Plan`
])
||
0
),
row
.
yearPlan
=
getIndicatorValue
(
0
,
row
.
indicatorName
,
props
.
planData
,
"yearPlan"
,
);
);
}
}
let
totalDecision
=
0
,
// 自动填充开累决策(从决策数据获取)
totalPlan
=
0
;
if
(
props
.
decisionData
&&
Object
.
keys
(
props
.
decisionData
).
length
>
0
)
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
row
.
invoiceDecision
=
getIndicatorValue
(
totalDecision
+=
parseFloat
(
parentRow
[
`m${i
}
Decision`
])
||
0
;
row
.
indicatorName
,
totalPlan
+=
parseFloat
(
parentRow
[
`m${i
}
Plan`
])
||
0
;
props
.
decisionData
,
}
"invoiceDecision"
,
parentRow
.
totalDecision
=
totalDecision
;
parentRow
.
totalPlan
=
totalPlan
;
}
else
if
(
props
.
tableType
===
"month"
)
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
parentRow
[
`m${i
}
Received`
]
=
childRows
.
reduce
(
(
sum
,
r
)
=>
sum
+
(
parseFloat
(
r
[
`m${i
}
Received`
])
||
0
),
0
,
);
parentRow
[
`m${i
}
Receivable`
]
=
childRows
.
reduce
(
(
sum
,
r
)
=>
sum
+
(
parseFloat
(
r
[
`m${i
}
Receivable`
])
||
0
),
0
,
);
);
}
}
parentRow
.
contractTotalAmount
=
childRows
.
reduce
(
// 自动填充开累计划(从计划数据获取)
(
sum
,
r
)
=>
sum
+
(
parseFloat
(
r
.
contractTotalAmount
)
||
0
),
if
(
props
.
planData
&&
Object
.
keys
(
props
.
planData
).
length
>
0
)
{
0
,
row
.
invoicePlan
=
getIndicatorValue
(
row
.
indicatorName
,
props
.
planData
,
"invoicePlan"
,
);
);
calculateMonthRowInternal
(
parentRow
);
}
}
}
);
}
);
// 重新计算完成率(不触发 emitChange,避免循环)
tableDataRef
.
value
.
forEach
((
row
)
=>
{
calculateMonthRow
(
row
);
});
// 计算合计行(不触发 emitChange,避免循环)
calculateTotalRow
();
}
;
}
;
// 年度表格计算
// 年度表格计算
const
calculateYearRow
=
(
row
)
=>
{
const
calculateYearRow
=
(
row
)
=>
{
if
(
row
.
noEdit
||
row
.
isTotalRow
)
return
;
if
(
row
.
noEdit
||
row
.
isTotalRow
||
row
.
isParentRow
)
return
;
// 欠收 = 决策应收 - 实收
const
decisionReceivable
=
parseFloat
(
row
.
decisionReceivable
)
||
0
;
const
decision
=
parseFloat
(
row
.
decisionReceivable
)
||
0
;
const
planReceivable
=
parseFloat
(
row
.
actualReceived
)
||
0
;
const
actual
=
parseFloat
(
row
.
actualReceived
)
||
0
;
const
jzss
=
parseFloat
(
row
.
jzss
)
||
0
;
row
.
shortfall
=
decision
-
actual
;
// 欠收(决策应收-实收)
// 完成率 = 实收 / 决策应收 * 100
row
.
shortfallDecision
=
decisionReceivable
-
jzss
;
if
(
decision
>
0
)
{
// 欠收(计划应收-实收)
row
.
completionRate
=
(
actual
/
decision
)
*
100
;
row
.
shortfallPlan
=
planReceivable
-
jzss
;
}
else
{
// 完成率(实收/决策应收)
row
.
completionRate
=
0
;
row
.
completionRateDecision
=
}
decisionReceivable
>
0
?
(
jzss
/
decisionReceivable
)
*
100
:
0
;
// 完成率(实收/计划应收)
row
.
completionRatePlan
=
planReceivable
>
0
?
(
jzss
/
planReceivable
)
*
100
:
0
;
}
;
}
;
// 月度表格计算
// 月度表格计算(内部,不检查 isParentRow)
const
calculateMonthRow
=
(
row
)
=>
{
const
calculateMonthRowInternal
=
(
row
)
=>
{
if
(
row
.
noEdit
||
row
.
isTotalRow
)
return
;
// 本年累计实收
let
monthReceivedSum
=
0
;
// 本年累计 = 1-12月实收之和
if
(
row
.
autoCalcYearTotal
)
{
let
monthSum
=
0
;
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
month
Sum
+=
parseFloat
(
row
[
`m
${
i
}
Received`
])
||
0
;
monthReceived
Sum
+=
parseFloat
(
row
[
`m${i
}
Received`
])
||
0
;
}
}
row
.
yearTotal
=
monthSum
;
row
.
yearTotal
=
monthReceivedSum
;
// 本年累计应收
let
monthReceivableSum
=
0
;
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
monthReceivableSum
+=
parseFloat
(
row
[
`m${i
}
Receivable`
])
||
0
;
}
}
row
.
yearTotalReceivable
=
monthReceivableSum
;
const
yearTotal
=
row
.
yearTotal
||
0
;
const
yearTotalReceivable
=
row
.
yearTotalReceivable
||
0
;
// 本年完成率: 累计实收/累计应收
row
.
yearCompletionRateReceivable
=
yearTotalReceivable
>
0
?
(
yearTotal
/
yearTotalReceivable
)
*
100
:
0
;
//
从年度计划数据中获取合计计划值
//
本年完成率: 累计实收/本年计划(从计划表获取该行的计划合计)
const
get
Yearly
PlanTotalPlan
=
()
=>
{
const
getPlanTotalPlan
=
()
=>
{
if
(
!
props
.
yearlyPlanData
||
!
props
.
yearlyPlanData
.
tableData
)
return
0
;
if
(
!
props
.
yearlyPlanData
||
!
props
.
yearlyPlanData
.
tableData
)
return
0
;
const
totalRow
=
props
.
yearlyPlanData
.
tableData
.
find
((
r
)
=>
r
.
isTotalRow
);
const
planRow
=
props
.
yearlyPlanData
.
tableData
.
find
(
return
totalRow
?
parseFloat
(
totalRow
.
totalPlan
)
||
0
:
0
;
(
r
)
=>
r
.
indicatorName
===
row
.
indicatorName
,
);
return
planRow
?
parseFloat
(
planRow
.
totalPlan
)
||
0
:
0
;
}
;
}
;
const
planTotalPlan
=
getPlanTotalPlan
();
row
.
yearCompletionRatePlan
=
planTotalPlan
>
0
?
(
yearTotal
/
planTotalPlan
)
*
100
:
0
;
//
从年度更新数据中获取截至年底实收值
//
截至本年完成(开累)= 本年累计实收 + 年度更新的实收
const
getYearlyJzss
=
()
=>
{
const
getYearlyJzss
=
()
=>
{
if
(
!
props
.
yearlyCompletionData
||
!
props
.
yearlyCompletionData
.
tableData
)
if
(
!
props
.
yearlyCompletionData
||
!
props
.
yearlyCompletionData
.
tableData
)
return
0
;
return
0
;
...
@@ -757,114 +837,85 @@ const calculateMonthRow = (row) => {
...
@@ -757,114 +837,85 @@ const calculateMonthRow = (row) => {
);
);
return
targetRow
?
parseFloat
(
targetRow
.
jzss
)
||
0
:
0
;
return
targetRow
?
parseFloat
(
targetRow
.
jzss
)
||
0
:
0
;
}
;
}
;
// 本年完成率/本年决策 = 本年累计 / 年度计划的合计计划值 * 100
const
yearlyPlanTotalPlan
=
getYearlyPlanTotalPlan
();
const
yearTotal
=
parseFloat
(
row
.
yearTotal
)
||
0
;
if
(
yearlyPlanTotalPlan
>
0
)
{
row
.
yearCompletionRateDecision
=
(
yearTotal
/
yearlyPlanTotalPlan
)
*
100
;
}
else
{
row
.
yearCompletionRateDecision
=
0
;
}
// 自动计算截至本年完成(开累)= 本年累计 + 年度更新的截至年底实收
const
yearlyJzss
=
getYearlyJzss
();
const
yearlyJzss
=
getYearlyJzss
();
row
.
invoiceCompleted
=
yearTotal
+
yearlyJzss
;
row
.
invoiceCompleted
=
yearTotal
+
yearlyJzss
;
// 从年度更新数据中获取决策应收和计划应收值
// 开累完成率 = 截至本年完成 / 合同总金额
const
getYearlyDecisionReceivable
=
()
=>
{
const
contractTotal
=
parseFloat
(
row
.
contractTotalAmount
)
||
0
;
if
(
!
props
.
yearlyCompletionData
||
!
props
.
yearlyCompletionData
.
tableData
)
row
.
invoiceCompletionRate
=
return
0
;
contractTotal
>
0
?
(
row
.
invoiceCompleted
/
contractTotal
)
*
100
:
0
;
const
targetRow
=
props
.
yearlyCompletionData
.
tableData
.
find
(
(
r
)
=>
r
.
indicatorName
===
row
.
indicatorName
,
);
return
targetRow
?
parseFloat
(
targetRow
.
decisionReceivable
)
||
0
:
0
;
};
const
getYearlyActualReceived
=
()
=>
{
if
(
!
props
.
yearlyCompletionData
||
!
props
.
yearlyCompletionData
.
tableData
)
return
0
;
const
targetRow
=
props
.
yearlyCompletionData
.
tableData
.
find
(
(
r
)
=>
r
.
indicatorName
===
row
.
indicatorName
,
);
return
targetRow
?
parseFloat
(
targetRow
.
actualReceived
)
||
0
:
0
;
};
// 本年完成率/本年计划 = 本年累计 / 年度更新的计划应收值 * 100
const
yearlyActualReceived
=
getYearlyActualReceived
();
if
(
yearlyActualReceived
>
0
)
{
row
.
yearCompletionRatePlan
=
(
yearTotal
/
yearlyActualReceived
)
*
100
;
}
else
{
row
.
yearCompletionRatePlan
=
0
;
}
// 开累完成率/开累决策 = 截至本年完成(开累) / (year的决策应收 + plan的合计决策值) * 100
const
yearlyDecisionReceivable
=
getYearlyDecisionReceivable
();
const
invoiceCompleted
=
parseFloat
(
row
.
invoiceCompleted
)
||
0
;
const
totalInvoiceDecision
=
yearlyDecisionReceivable
+
yearlyPlanTotalPlan
;
if
(
totalInvoiceDecision
>
0
)
{
row
.
invoiceCompletionRateDecision
=
(
invoiceCompleted
/
totalInvoiceDecision
)
*
100
;
}
else
{
row
.
invoiceCompletionRateDecision
=
0
;
}
// 开累完成率/开累计划 = 截至本年完成(开累) / (year的计划应收 + plan的合计计划值) * 100
// 欠收金额 = 累计应收 - 累计实收
const
totalInvoicePlan
=
yearlyActualReceived
+
yearlyPlanTotalPlan
;
row
.
shortfallAmount
=
yearTotalReceivable
-
yearTotal
;
if
(
totalInvoicePlan
>
0
)
{
}
;
row
.
invoiceCompletionRatePlan
=
(
invoiceCompleted
/
totalInvoicePlan
)
*
100
;
}
else
{
row
.
invoiceCompletionRatePlan
=
0
;
}
// 欠收金额不再自动计算,由用户手动输入
// 月度表格计算(对外,检查 isParentRow)
// row.shortfallAmount = yearDecision - yearTotal;
const
calculateMonthRow
=
(
row
)
=>
{
if
(
row
.
noEdit
||
row
.
isTotalRow
||
row
.
isParentRow
)
return
;
calculateMonthRowInternal
(
row
);
}
;
}
;
// 计算合计行
// 计算合计行
(仅汇总非子行)
const
calculateTotalRow
=
()
=>
{
const
calculateTotalRow
=
()
=>
{
const
totalRow
=
tableDataRef
.
value
.
find
((
row
)
=>
row
.
isTotalRow
);
const
totalRow
=
tableDataRef
.
value
.
find
((
row
)
=>
row
.
isTotalRow
);
if
(
!
totalRow
)
return
;
if
(
!
totalRow
)
return
;
// 获取参与合计的行(排除子行、合计行、noEdit 行)
const
sumRows
=
tableDataRef
.
value
.
filter
(
(
row
)
=>
!
row
.
isTotalRow
&&
!
row
.
noEdit
&&
!
row
.
isChild
,
);
if
(
props
.
tableType
===
"year"
)
{
if
(
props
.
tableType
===
"year"
)
{
// 年度表格合计
let
totalDecisionReceivable
=
0
;
let
totalDecision
=
0
;
let
totalPlanReceivable
=
0
;
let
totalActual
=
0
;
let
totalJzss
=
0
;
let
totalJzss
=
0
;
tableDataRef
.
value
.
forEach
((
row
)
=>
{
sumRows
.
forEach
((
row
)
=>
{
if
(
!
row
.
isTotalRow
&&
!
row
.
noEdit
)
{
totalDecisionReceivable
+=
parseFloat
(
row
.
decisionReceivable
)
||
0
;
totalDecision
+=
parseFloat
(
row
.
decisionReceivable
)
||
0
;
totalPlanReceivable
+=
parseFloat
(
row
.
actualReceived
)
||
0
;
totalActual
+=
parseFloat
(
row
.
actualReceived
)
||
0
;
totalJzss
+=
parseFloat
(
row
.
jzss
)
||
0
;
totalJzss
+=
parseFloat
(
row
.
jzss
)
||
0
;
}
}
);
}
);
totalRow
.
decisionReceivable
=
totalDecision
;
totalRow
.
decisionReceivable
=
totalDecision
Receivable
;
totalRow
.
actualReceived
=
total
Actual
;
totalRow
.
actualReceived
=
total
PlanReceivable
;
totalRow
.
jzss
=
totalJzss
;
totalRow
.
jzss
=
totalJzss
;
totalRow
.
shortfall
=
totalDecision
-
totalActual
;
totalRow
.
shortfallDecision
=
totalDecisionReceivable
-
totalJzss
;
if
(
totalDecision
>
0
)
{
totalRow
.
shortfallPlan
=
totalPlanReceivable
-
totalJzss
;
totalRow
.
completionRate
=
(
totalActual
/
totalDecision
)
*
100
;
totalRow
.
completionRateDecision
=
}
else
{
totalDecisionReceivable
>
0
totalRow
.
completionRate
=
0
;
?
(
totalJzss
/
totalDecisionReceivable
)
*
100
}
:
0
;
totalRow
.
completionRatePlan
=
totalPlanReceivable
>
0
?
(
totalJzss
/
totalPlanReceivable
)
*
100
:
0
;
}
else
if
(
props
.
tableType
===
"plan"
)
{
}
else
if
(
props
.
tableType
===
"plan"
)
{
// 计划表格合计
// 每行先算自己的合计
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
tableDataRef
.
value
.
forEach
((
row
)
=>
{
if
(
!
row
.
isTotalRow
&&
!
row
.
noEdit
&&
!
row
.
isParentRow
)
{
let
decisionSum
=
0
;
let
decisionSum
=
0
;
let
planSum
=
0
;
let
planSum
=
0
;
tableDataRef
.
value
.
forEach
((
row
)
=>
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
if
(
!
row
.
isTotalRow
&&
!
row
.
noEdit
)
{
decisionSum
+=
parseFloat
(
row
[
`m${i
}
Decision`
])
||
0
;
decisionSum
+=
parseFloat
(
row
[
`m${i
}
Decision`
])
||
0
;
planSum
+=
parseFloat
(
row
[
`m${i
}
Plan`
])
||
0
;
planSum
+=
parseFloat
(
row
[
`m${i
}
Plan`
])
||
0
;
}
}
row
.
totalDecision
=
decisionSum
;
row
.
totalPlan
=
planSum
;
}
}
);
// 合计行汇总
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
let
decisionSum
=
0
;
let
planSum
=
0
;
sumRows
.
forEach
((
row
)
=>
{
decisionSum
+=
parseFloat
(
row
[
`m${i
}
Decision`
])
||
0
;
planSum
+=
parseFloat
(
row
[
`m${i
}
Plan`
])
||
0
;
}
);
}
);
totalRow
[
`m${i
}
Decision`
]
=
decisionSum
;
totalRow
[
`m${i
}
Decision`
]
=
decisionSum
;
totalRow
[
`m${i
}
Plan`
]
=
planSum
;
totalRow
[
`m${i
}
Plan`
]
=
planSum
;
}
}
// 计算合计列
let
totalDecisionSum
=
0
;
let
totalDecisionSum
=
0
;
let
totalPlanSum
=
0
;
let
totalPlanSum
=
0
;
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
...
@@ -873,67 +924,52 @@ const calculateTotalRow = () => {
...
@@ -873,67 +924,52 @@ const calculateTotalRow = () => {
}
}
totalRow
.
totalDecision
=
totalDecisionSum
;
totalRow
.
totalDecision
=
totalDecisionSum
;
totalRow
.
totalPlan
=
totalPlanSum
;
totalRow
.
totalPlan
=
totalPlanSum
;
// 计算每行的合计值(1-12月总和)
tableDataRef
.
value
.
forEach
((
row
)
=>
{
if
(
!
row
.
isTotalRow
&&
!
row
.
noEdit
)
{
let
decisionSum
=
0
;
let
planSum
=
0
;
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
decisionSum
+=
parseFloat
(
row
[
`m
${
i
}
Decision`
])
||
0
;
planSum
+=
parseFloat
(
row
[
`m
${
i
}
Plan`
])
||
0
;
}
row
.
totalDecision
=
decisionSum
;
row
.
totalPlan
=
planSum
;
}
});
}
else
{
}
else
{
// 月度表格合计
// 月度表格合计
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
let
receivableSum
=
0
;
let
receivedSum
=
0
;
let
receivedSum
=
0
;
tableDataRef
.
value
.
forEach
((
row
)
=>
{
let
receivableSum
=
0
;
if
(
!
row
.
isTotalRow
&&
!
row
.
noEdit
)
{
sumRows
.
forEach
((
row
)
=>
{
receivableSum
+=
parseFloat
(
row
[
`m
${
i
}
Receivable`
])
||
0
;
receivedSum
+=
parseFloat
(
row
[
`m${i
}
Received`
])
||
0
;
receivedSum
+=
parseFloat
(
row
[
`m${i
}
Received`
])
||
0
;
}
receivableSum
+=
parseFloat
(
row
[
`m${i
}
Receivable`
])
||
0
;
}
);
}
);
totalRow
[
`m
${
i
}
Receivable`
]
=
receivableSum
;
totalRow
[
`m${i
}
Received`
]
=
receivedSum
;
totalRow
[
`m${i
}
Received`
]
=
receivedSum
;
totalRow
[
`m${i
}
Receivable`
]
=
receivableSum
;
}
}
// 本年累计
(实收合计)
// 本年累计
实收
let
yearTotalSum
=
0
;
let
yearTotalSum
=
0
;
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
yearTotalSum
+=
parseFloat
(
totalRow
[
`m${i
}
Received`
])
||
0
;
yearTotalSum
+=
parseFloat
(
totalRow
[
`m${i
}
Received`
])
||
0
;
}
}
totalRow
.
yearTotal
=
yearTotalSum
;
totalRow
.
yearTotal
=
yearTotalSum
;
// 计算合计行的完成率
// 本年累计应收
// 从年度计划数据中获取合计计划值
let
yearTotalReceivableSum
=
0
;
const
getYearlyPlanTotalPlan
=
()
=>
{
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
yearTotalReceivableSum
+=
parseFloat
(
totalRow
[
`m${i
}
Receivable`
])
||
0
;
}
totalRow
.
yearTotalReceivable
=
yearTotalReceivableSum
;
// 本年完成率: 累计实收/累计应收
totalRow
.
yearCompletionRateReceivable
=
yearTotalReceivableSum
>
0
?
(
yearTotalSum
/
yearTotalReceivableSum
)
*
100
:
0
;
// 本年完成率: 累计实收/本年计划
const
getPlanTotalPlan
=
()
=>
{
if
(
!
props
.
yearlyPlanData
||
!
props
.
yearlyPlanData
.
tableData
)
return
0
;
if
(
!
props
.
yearlyPlanData
||
!
props
.
yearlyPlanData
.
tableData
)
return
0
;
const
yearlyTotalRow
=
props
.
yearlyPlanData
.
tableData
.
find
(
const
yearlyTotalRow
=
props
.
yearlyPlanData
.
tableData
.
find
(
(
r
)
=>
r
.
isTotalRow
,
(
r
)
=>
r
.
isTotalRow
,
);
);
return
yearlyTotalRow
?
parseFloat
(
yearlyTotalRow
.
totalPlan
)
||
0
:
0
;
return
yearlyTotalRow
?
parseFloat
(
yearlyTotalRow
.
totalPlan
)
||
0
:
0
;
}
;
}
;
const
planTotalPlan
=
getPlanTotalPlan
();
totalRow
.
yearCompletionRatePlan
=
planTotalPlan
>
0
?
(
yearTotalSum
/
planTotalPlan
)
*
100
:
0
;
const
yearlyPlanTotalPlan
=
getYearlyPlanTotalPlan
();
// 截至本年完成(开累)
// 本年完成率/本年决策 = 本年累计 / 年度计划的合计计划值 * 100
if
(
yearlyPlanTotalPlan
>
0
)
{
totalRow
.
yearCompletionRateDecision
=
(
yearTotalSum
/
yearlyPlanTotalPlan
)
*
100
;
}
else
{
totalRow
.
yearCompletionRateDecision
=
0
;
}
// 本年完成率/本年计划 = 本年累计 / 本年计划 * 100(合计行暂不计算此值)
totalRow
.
yearCompletionRatePlan
=
0
;
// 计算合计行的截至本年完成(开累)
// 从年度更新数据中获取截至年底实收值
const
getYearlyJzss
=
()
=>
{
const
getYearlyJzss
=
()
=>
{
if
(
!
props
.
yearlyCompletionData
||
!
props
.
yearlyCompletionData
.
tableData
)
if
(
!
props
.
yearlyCompletionData
||
!
props
.
yearlyCompletionData
.
tableData
)
return
0
;
return
0
;
...
@@ -942,79 +978,43 @@ const calculateTotalRow = () => {
...
@@ -942,79 +978,43 @@ const calculateTotalRow = () => {
);
);
return
yearlyTotalRow
?
parseFloat
(
yearlyTotalRow
.
jzss
)
||
0
:
0
;
return
yearlyTotalRow
?
parseFloat
(
yearlyTotalRow
.
jzss
)
||
0
:
0
;
}
;
}
;
const
yearlyJzss
=
getYearlyJzss
();
const
yearlyJzss
=
getYearlyJzss
();
totalRow
.
invoiceCompleted
=
yearTotalSum
+
yearlyJzss
;
totalRow
.
invoiceCompleted
=
yearTotalSum
+
yearlyJzss
;
// 计算合计行的欠收金额
// 合同总金额合计
let
shortfallAmountSum
=
0
;
tableDataRef
.
value
.
forEach
((
row
)
=>
{
if
(
!
row
.
isTotalRow
&&
!
row
.
noEdit
)
{
shortfallAmountSum
+=
parseFloat
(
row
.
shortfallAmount
)
||
0
;
}
});
totalRow
.
shortfallAmount
=
shortfallAmountSum
;
// 计算合计行的合同总金额
let
contractTotalAmountSum
=
0
;
let
contractTotalAmountSum
=
0
;
tableDataRef
.
value
.
forEach
((
row
)
=>
{
sumRows
.
forEach
((
row
)
=>
{
if
(
!
row
.
isTotalRow
&&
!
row
.
noEdit
)
{
contractTotalAmountSum
+=
parseFloat
(
row
.
contractTotalAmount
)
||
0
;
contractTotalAmountSum
+=
parseFloat
(
row
.
contractTotalAmount
)
||
0
;
}
}
);
}
);
totalRow
.
contractTotalAmount
=
contractTotalAmountSum
;
totalRow
.
contractTotalAmount
=
contractTotalAmountSum
;
// 计算合计行的开累完成率
// 开累完成率 = 截至本年完成 / 合同总金额
// 从年度更新数据中获取合计的决策应收和计划应收值
totalRow
.
invoiceCompletionRate
=
const
getYearlyDecisionReceivable
=
()
=>
{
contractTotalAmountSum
>
0
if
(
!
props
.
yearlyCompletionData
||
!
props
.
yearlyCompletionData
.
tableData
)
?
(
totalRow
.
invoiceCompleted
/
contractTotalAmountSum
)
*
100
return
0
;
const
yearlyTotalRow
=
props
.
yearlyCompletionData
.
tableData
.
find
(
(
r
)
=>
r
.
isTotalRow
,
);
return
yearlyTotalRow
?
parseFloat
(
yearlyTotalRow
.
decisionReceivable
)
||
0
:
0
;
:
0
;
};
const
getYearlyActualReceived
=
()
=>
{
// 欠收金额 = 累计应收 - 累计实收
if
(
!
props
.
yearlyCompletionData
||
!
props
.
yearlyCompletionData
.
tableData
)
totalRow
.
shortfallAmount
=
yearTotalReceivableSum
-
yearTotalSum
;
return
0
;
}
const
yearlyTotalRow
=
props
.
yearlyCompletionData
.
tableData
.
find
(
}
;
(
r
)
=>
r
.
isTotalRow
,
);
return
yearlyTotalRow
?
parseFloat
(
yearlyTotalRow
.
actualReceived
)
||
0
:
0
;
};
const
yearlyDecisionReceivable
=
getYearlyDecisionReceivable
();
// 自动填充决策和计划数据
const
yearlyActualReceived
=
getYearlyActualReceived
();
const
autoFillDecisionAndPlan
=
()
=>
{
const
invoiceCompleted
=
parseFloat
(
totalRow
.
invoiceCompleted
)
||
0
;
if
(
props
.
tableType
!==
"month"
)
return
;
const
totalInvoiceDecision
=
yearlyDecisionReceivable
+
yearlyPlanTotalPlan
;
const
totalInvoicePlan
=
yearlyActualReceived
+
yearlyPlanTotalPlan
;
// 开累完成率/开累决策
tableDataRef
.
value
.
forEach
((
row
)
=>
{
if
(
totalInvoiceDecision
>
0
)
{
calculateMonthRow
(
row
);
totalRow
.
invoiceCompletionRateDecision
=
}
);
(
invoiceCompleted
/
totalInvoiceDecision
)
*
100
;
}
else
{
totalRow
.
invoiceCompletionRateDecision
=
0
;
}
// 开累完成率/开累计划
calculateParentRows
();
if
(
totalInvoicePlan
>
0
)
{
calculateTotalRow
();
totalRow
.
invoiceCompletionRatePlan
=
(
invoiceCompleted
/
totalInvoicePlan
)
*
100
;
}
else
{
totalRow
.
invoiceCompletionRatePlan
=
0
;
}
}
}
;
}
;
// 处理输入事件
// 处理输入事件
const
handleNumberInput
=
(
row
)
=>
{
const
handleNumberInput
=
(
row
)
=>
{
calculateYearRow
(
row
);
calculateYearRow
(
row
);
calculateParentRows
();
calculateTotalRow
();
calculateTotalRow
();
emitChange
();
emitChange
();
}
;
}
;
...
@@ -1025,24 +1025,21 @@ const handleTextInput = () => {
...
@@ -1025,24 +1025,21 @@ const handleTextInput = () => {
const
handleMonthInput
=
(
row
)
=>
{
const
handleMonthInput
=
(
row
)
=>
{
calculateMonthRow
(
row
);
calculateMonthRow
(
row
);
calculateTotalRow
();
calculateParentRows
();
emitChange
();
};
const
handleYearTotalInput
=
(
row
)
=>
{
calculateMonthRow
(
row
);
calculateTotalRow
();
calculateTotalRow
();
emitChange
();
emitChange
();
}
;
}
;
const
handleContractAmountInput
=
(
row
)
=>
{
const
handleContractAmountInput
=
(
row
)
=>
{
calculateMonthRow
(
row
);
calculateMonthRow
(
row
);
calculateParentRows
();
calculateTotalRow
();
calculateTotalRow
();
emitChange
();
emitChange
();
}
;
}
;
const
handleShortfallAmountInput
=
(
row
)
=>
{
const
handleShortfallAmountInput
=
(
row
)
=>
{
calculateMonthRow
(
row
);
calculateMonthRow
(
row
);
calculateParentRows
();
calculateTotalRow
();
calculateTotalRow
();
emitChange
();
emitChange
();
}
;
}
;
...
@@ -1060,11 +1057,13 @@ const emitChange = () => {
...
@@ -1060,11 +1057,13 @@ const emitChange = () => {
emit
(
"update:modelValue"
,
newModelValue
);
emit
(
"update:modelValue"
,
newModelValue
);
}
;
}
;
// 表格单元格样式
const
tableCellStyle
=
({
row
}
)
=>
{
const
tableCellStyle
=
({
row
}
)
=>
{
if
(
row
.
isTotalRow
)
{
if
(
row
.
isTotalRow
)
{
return
{
background
:
"#f5f7fa"
,
fontWeight
:
"bold"
,
textAlign
:
"center"
}
;
return
{
background
:
"#f5f7fa"
,
fontWeight
:
"bold"
,
textAlign
:
"center"
}
;
}
}
if
(
row
.
isParentRow
)
{
return
{
background
:
"#fafafa"
,
fontWeight
:
"500"
,
textAlign
:
"center"
}
;
}
return
{
textAlign
:
"center"
}
;
return
{
textAlign
:
"center"
}
;
}
;
}
;
...
@@ -1080,7 +1079,18 @@ watch(
...
@@ -1080,7 +1079,18 @@ watch(
return
initRowData
(
indicator
,
index
,
sourceRow
);
return
initRowData
(
indicator
,
index
,
sourceRow
);
}
);
}
);
tableDataRef
.
value
=
newData
;
tableDataRef
.
value
=
newData
;
// 自动填充决策和计划数据
// 重新计算
tableDataRef
.
value
.
forEach
((
row
)
=>
{
if
(
props
.
tableType
===
"year"
)
{
calculateYearRow
(
row
);
}
else
if
(
props
.
tableType
===
"month"
)
{
calculateMonthRow
(
row
);
}
}
);
calculateParentRows
();
calculateTotalRow
();
autoFillDecisionAndPlan
();
autoFillDecisionAndPlan
();
}
);
}
);
}
,
}
,
...
@@ -1111,8 +1121,8 @@ watch(
...
@@ -1111,8 +1121,8 @@ watch(
tableDataRef
.
value
.
forEach
((
row
)
=>
{
tableDataRef
.
value
.
forEach
((
row
)
=>
{
calculateMonthRow
(
row
);
calculateMonthRow
(
row
);
}
);
}
);
calculateParentRows
();
calculateTotalRow
();
calculateTotalRow
();
// 不调用 emitChange,避免无限循环
}
}
}
);
}
);
}
,
}
,
...
@@ -1128,8 +1138,8 @@ watch(
...
@@ -1128,8 +1138,8 @@ watch(
tableDataRef
.
value
.
forEach
((
row
)
=>
{
tableDataRef
.
value
.
forEach
((
row
)
=>
{
calculateMonthRow
(
row
);
calculateMonthRow
(
row
);
}
);
}
);
calculateParentRows
();
calculateTotalRow
();
calculateTotalRow
();
// 不调用 emitChange,避免无限循环
}
}
}
);
}
);
}
,
}
,
...
...
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