@nstc-business/imes 1.0.21 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/measureCalc/MeasureEvalFlatTable.vue +29 -19
- package/src/components/measureCalc/MeasureGroupBlocks.vue +181 -0
- package/src/components/measureCalc/MeasureQualAnalysis.vue +135 -174
- package/src/components/measureCalc/MeasureStatCell.vue +17 -0
- package/src/components/measureCalc/MeasureStatFlatTable.vue +20 -1
- package/src/components/measureCalc/MeasureStatModelTable.vue +2 -2
- package/src/components/measureCalc/MeasureSubModelPanel.vue +4 -3
- package/src/components/measureCalc/MeasureTreeTable.vue +36 -20
- package/src/components/measureCalc/helpers.js +81 -1
- package/src/components/measureCalc/index.vue +150 -83
- package/src/components/measureCalc/statModelHelper.js +3 -3
package/package.json
CHANGED
|
@@ -57,6 +57,25 @@
|
|
|
57
57
|
<template #default="{ row }">{{ fullScoreFn(row) }}</template>
|
|
58
58
|
</vxe-column>
|
|
59
59
|
|
|
60
|
+
<vxe-column
|
|
61
|
+
v-if="showFormulaCol"
|
|
62
|
+
field="displayFormula"
|
|
63
|
+
title="计算公式"
|
|
64
|
+
width="130"
|
|
65
|
+
align="center"
|
|
66
|
+
>
|
|
67
|
+
<template #default="{ row }">{{ row.displayFormula || '—' }}</template>
|
|
68
|
+
</vxe-column>
|
|
69
|
+
<vxe-column
|
|
70
|
+
v-if="showRemarkCol"
|
|
71
|
+
field="indicatorRemark"
|
|
72
|
+
title="评价标准"
|
|
73
|
+
width="130"
|
|
74
|
+
align="center"
|
|
75
|
+
>
|
|
76
|
+
<template #default="{ row }">{{ row.indicatorRemark || '—' }}</template>
|
|
77
|
+
</vxe-column>
|
|
78
|
+
|
|
60
79
|
<vxe-column title="指标值" min-width="260" align="center">
|
|
61
80
|
<template #default="{ row }">
|
|
62
81
|
<template v-if="isQualFn(row)">
|
|
@@ -119,6 +138,11 @@
|
|
|
119
138
|
</vxe-column>
|
|
120
139
|
|
|
121
140
|
<vxe-column title="指标得分" width="140" align="center">
|
|
141
|
+
<template #default="{ row }">
|
|
142
|
+
<div>{{ indicatorScoreFn(row) }}</div>
|
|
143
|
+
</template>
|
|
144
|
+
</vxe-column>
|
|
145
|
+
<vxe-column title="模型指标得分" width="140" align="center">
|
|
122
146
|
<template #default="{ row }">
|
|
123
147
|
<div>{{ resultFn(row) }}</div>
|
|
124
148
|
<InputNumber
|
|
@@ -133,28 +157,10 @@
|
|
|
133
157
|
:max="row.fullScore"
|
|
134
158
|
:disabled="ctx.readonly"
|
|
135
159
|
v-model="row.modifiedResult"
|
|
136
|
-
placeholder="
|
|
160
|
+
placeholder="修改模型指标得分"
|
|
137
161
|
/>
|
|
138
162
|
</template>
|
|
139
163
|
</vxe-column>
|
|
140
|
-
<vxe-column
|
|
141
|
-
v-if="showFormulaCol"
|
|
142
|
-
field="displayFormula"
|
|
143
|
-
title="计算公式"
|
|
144
|
-
width="130"
|
|
145
|
-
align="center"
|
|
146
|
-
>
|
|
147
|
-
<template #default="{ row }">{{ row.displayFormula || '—' }}</template>
|
|
148
|
-
</vxe-column>
|
|
149
|
-
<vxe-column
|
|
150
|
-
v-if="showRemarkCol"
|
|
151
|
-
field="indicatorRemark"
|
|
152
|
-
title="评价标准"
|
|
153
|
-
width="130"
|
|
154
|
-
align="center"
|
|
155
|
-
>
|
|
156
|
-
<template #default="{ row }">{{ row.indicatorRemark || '—' }}</template>
|
|
157
|
-
</vxe-column>
|
|
158
164
|
<vxe-column
|
|
159
165
|
v-if="showModifyReasonCol"
|
|
160
166
|
min-width="260"
|
|
@@ -218,6 +224,7 @@ import {
|
|
|
218
224
|
isQualIndicator,
|
|
219
225
|
digitsCalc,
|
|
220
226
|
resultByShowStyle,
|
|
227
|
+
indicatorScoreText,
|
|
221
228
|
indicatorResultText,
|
|
222
229
|
fullScoreText,
|
|
223
230
|
showLevelSerial
|
|
@@ -278,6 +285,9 @@ export default {
|
|
|
278
285
|
resultFn(row) {
|
|
279
286
|
return resultByShowStyle(row, this.ctx.modelWrap)
|
|
280
287
|
},
|
|
288
|
+
indicatorScoreFn(row) {
|
|
289
|
+
return indicatorScoreText(row, this.ctx.modelWrap)
|
|
290
|
+
},
|
|
281
291
|
indicatorTextFn(row) {
|
|
282
292
|
return indicatorResultText(row, this.ctx.modelWrap)
|
|
283
293
|
},
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="measure-group-blocks">
|
|
3
|
+
<measure-qual-analysis
|
|
4
|
+
v-if="qualLooseNodes.length"
|
|
5
|
+
:groups="qualLooseGroups"
|
|
6
|
+
/>
|
|
7
|
+
<measure-tree-table
|
|
8
|
+
v-if="tableLooseNodes.length"
|
|
9
|
+
:nodes="tableLooseNodes"
|
|
10
|
+
:level="level"
|
|
11
|
+
:number-prefix="numberPrefix"
|
|
12
|
+
:calc-mode="calcMode"
|
|
13
|
+
:section="section"
|
|
14
|
+
/>
|
|
15
|
+
|
|
16
|
+
<div
|
|
17
|
+
v-for="(group, i) in nestedGroups"
|
|
18
|
+
:key="group._rowKey || i"
|
|
19
|
+
class="measure-inner-group"
|
|
20
|
+
>
|
|
21
|
+
<div class="section-title">
|
|
22
|
+
{{ group.name }}
|
|
23
|
+
<span v-if="group.remark" class="section-remark">
|
|
24
|
+
备注:<span class="remark-html" v-html="group.remark"></span>
|
|
25
|
+
</span>
|
|
26
|
+
<span v-if="innerWeightText(group)" class="section-weight-pill">
|
|
27
|
+
{{ innerWeightText(group) }}
|
|
28
|
+
</span>
|
|
29
|
+
<span v-if="innerSubtotalText(group)" class="section-score-pill">
|
|
30
|
+
{{ innerSubtotalText(group) }}
|
|
31
|
+
</span>
|
|
32
|
+
</div>
|
|
33
|
+
<measure-group-blocks
|
|
34
|
+
:nodes="group.children || []"
|
|
35
|
+
:group-node="group"
|
|
36
|
+
:level="level + 1"
|
|
37
|
+
:number-prefix="childNumberPrefix(group)"
|
|
38
|
+
:calc-mode="calcMode"
|
|
39
|
+
:section="section"
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script>
|
|
46
|
+
import MeasureQualAnalysis from './MeasureQualAnalysis.vue'
|
|
47
|
+
import {
|
|
48
|
+
splitGroupNodes,
|
|
49
|
+
isQualIndicator,
|
|
50
|
+
hierarchySerial,
|
|
51
|
+
hierarchySerialPrefix
|
|
52
|
+
} from './helpers'
|
|
53
|
+
|
|
54
|
+
export default {
|
|
55
|
+
name: 'MeasureGroupBlocks',
|
|
56
|
+
components: {
|
|
57
|
+
MeasureQualAnalysis,
|
|
58
|
+
MeasureTreeTable: () => import('./MeasureTreeTable.vue')
|
|
59
|
+
},
|
|
60
|
+
inject: ['measureCtx'],
|
|
61
|
+
props: {
|
|
62
|
+
nodes: {
|
|
63
|
+
type: Array,
|
|
64
|
+
default: () => []
|
|
65
|
+
},
|
|
66
|
+
groupNode: {
|
|
67
|
+
type: Object,
|
|
68
|
+
default: null
|
|
69
|
+
},
|
|
70
|
+
level: {
|
|
71
|
+
type: Number,
|
|
72
|
+
default: 1
|
|
73
|
+
},
|
|
74
|
+
numberPrefix: {
|
|
75
|
+
type: String,
|
|
76
|
+
default: ''
|
|
77
|
+
},
|
|
78
|
+
calcMode: {
|
|
79
|
+
type: Boolean,
|
|
80
|
+
default: false
|
|
81
|
+
},
|
|
82
|
+
section: {
|
|
83
|
+
type: Object,
|
|
84
|
+
default: () => ({})
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
computed: {
|
|
88
|
+
ctx() {
|
|
89
|
+
return this.measureCtx()
|
|
90
|
+
},
|
|
91
|
+
split() {
|
|
92
|
+
return splitGroupNodes(this.nodes)
|
|
93
|
+
},
|
|
94
|
+
nestedGroups() {
|
|
95
|
+
return this.split.groups
|
|
96
|
+
},
|
|
97
|
+
looseNodes() {
|
|
98
|
+
return this.split.loose
|
|
99
|
+
},
|
|
100
|
+
qualLooseNodes() {
|
|
101
|
+
return this.looseNodes.filter(isQualIndicator)
|
|
102
|
+
},
|
|
103
|
+
tableLooseNodes() {
|
|
104
|
+
return this.looseNodes.filter(n => !isQualIndicator(n))
|
|
105
|
+
},
|
|
106
|
+
qualLooseGroups() {
|
|
107
|
+
const resolve = this.ctx.resolveLeafNode
|
|
108
|
+
return [
|
|
109
|
+
{
|
|
110
|
+
name: '',
|
|
111
|
+
children: this.qualLooseNodes.map(n =>
|
|
112
|
+
resolve ? resolve(n) || n : n
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
methods: {
|
|
119
|
+
innerWeightText(group) {
|
|
120
|
+
const fn = this.ctx.groupWeightText
|
|
121
|
+
return fn ? fn(group) : ''
|
|
122
|
+
},
|
|
123
|
+
innerSubtotalText(group) {
|
|
124
|
+
const fn = this.ctx.groupSubtotalText
|
|
125
|
+
return fn ? fn(group) : ''
|
|
126
|
+
},
|
|
127
|
+
childNumberPrefix(group) {
|
|
128
|
+
const idx = this.nodes.findIndex(n => n._rowKey === group._rowKey)
|
|
129
|
+
const serial = hierarchySerial(this.numberPrefix, idx < 0 ? 0 : idx)
|
|
130
|
+
return hierarchySerialPrefix(serial)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
</script>
|
|
135
|
+
|
|
136
|
+
<style lang="less" scoped>
|
|
137
|
+
.measure-group-blocks {
|
|
138
|
+
width: 100%;
|
|
139
|
+
}
|
|
140
|
+
.measure-inner-group {
|
|
141
|
+
margin-top: 12px;
|
|
142
|
+
}
|
|
143
|
+
.measure-inner-group + .measure-inner-group {
|
|
144
|
+
margin-top: 16px;
|
|
145
|
+
}
|
|
146
|
+
.section-title {
|
|
147
|
+
display: flex;
|
|
148
|
+
align-items: center;
|
|
149
|
+
flex-wrap: wrap;
|
|
150
|
+
gap: 8px;
|
|
151
|
+
font-size: 15px;
|
|
152
|
+
font-weight: 600;
|
|
153
|
+
padding-left: 8px;
|
|
154
|
+
margin-bottom: 8px;
|
|
155
|
+
border-left: 3px solid #409eff;
|
|
156
|
+
}
|
|
157
|
+
.section-weight-pill,
|
|
158
|
+
.section-score-pill {
|
|
159
|
+
display: inline-block;
|
|
160
|
+
margin-left: 4px;
|
|
161
|
+
padding: 2px 10px;
|
|
162
|
+
font-size: 14px;
|
|
163
|
+
font-weight: 400;
|
|
164
|
+
color: #606266;
|
|
165
|
+
line-height: 20px;
|
|
166
|
+
background: #f2f3f5;
|
|
167
|
+
border-radius: 4px;
|
|
168
|
+
}
|
|
169
|
+
.section-remark {
|
|
170
|
+
margin-left: 0;
|
|
171
|
+
font-weight: 400;
|
|
172
|
+
color: #909399;
|
|
173
|
+
}
|
|
174
|
+
.section-remark .remark-html {
|
|
175
|
+
display: inline;
|
|
176
|
+
::v-deep p {
|
|
177
|
+
display: inline;
|
|
178
|
+
margin: 0;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
</style>
|
|
@@ -22,92 +22,120 @@
|
|
|
22
22
|
</span>
|
|
23
23
|
</div>
|
|
24
24
|
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
<vxe-table
|
|
26
|
+
border
|
|
27
|
+
class="qual-table"
|
|
28
|
+
:data="group.children"
|
|
29
|
+
:row-config="{ keyField: '_rowKey' }"
|
|
30
|
+
:scroll-y="{ enabled: false }"
|
|
31
|
+
>
|
|
32
|
+
<vxe-column v-if="showSerial" title="序号" width="72" align="center">
|
|
33
|
+
<template #default="{ rowIndex }">{{ rowIndex + 1 }}</template>
|
|
34
|
+
</vxe-column>
|
|
35
|
+
|
|
36
|
+
<vxe-column field="name" title="指标名称" min-width="180" align="center">
|
|
37
|
+
<template #default="{ row }">
|
|
38
|
+
<span v-title="row.name">{{ row.name }}</span>
|
|
39
|
+
</template>
|
|
40
|
+
</vxe-column>
|
|
41
|
+
|
|
42
|
+
<vxe-column
|
|
43
|
+
v-if="showWeightCol"
|
|
44
|
+
title="指标权重"
|
|
45
|
+
width="100"
|
|
46
|
+
align="center"
|
|
47
|
+
>
|
|
48
|
+
<template #default="{ row }">{{ row.weight || '—' }}</template>
|
|
49
|
+
</vxe-column>
|
|
50
|
+
|
|
51
|
+
<vxe-column title="指标满分值" width="110" align="center">
|
|
52
|
+
<template #default="{ row }">{{ formatFullScore(row) }}</template>
|
|
53
|
+
</vxe-column>
|
|
54
|
+
|
|
55
|
+
<vxe-column title="评价标准" min-width="180" align="center">
|
|
56
|
+
<template #default="{ row }">{{ evalStandardText(row) }}</template>
|
|
57
|
+
</vxe-column>
|
|
58
|
+
|
|
59
|
+
<vxe-column title="指标值" min-width="220" align="center">
|
|
60
|
+
<template #default="{ row }">
|
|
61
|
+
<el-select
|
|
62
|
+
v-if="isQualSelectNode(row)"
|
|
63
|
+
class="qual-select"
|
|
64
|
+
:value="row.scoreMapID"
|
|
65
|
+
:disabled="readonly"
|
|
66
|
+
size="small"
|
|
67
|
+
placeholder="请选择"
|
|
68
|
+
@change="val => onSelectChange(row, val)"
|
|
69
|
+
>
|
|
70
|
+
<el-option
|
|
71
|
+
v-for="option in row.optionList"
|
|
72
|
+
:key="option.scoreMapID"
|
|
73
|
+
:label="option.scoreText"
|
|
74
|
+
:value="option.scoreMapID"
|
|
75
|
+
style="height: auto"
|
|
44
76
|
>
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
</span>
|
|
62
|
-
<span class="qual-score-value">
|
|
63
|
-
{{ formatScore(node.result) }}
|
|
64
|
-
</span>
|
|
65
|
-
</div>
|
|
66
|
-
<div class="qual-cell qual-cell-reason">
|
|
67
|
-
<span class="qual-inline-label">评价理由</span>
|
|
68
|
-
<el-input
|
|
69
|
-
class="qual-reason-input"
|
|
70
|
-
type="textarea"
|
|
71
|
-
v-title
|
|
72
|
-
:show-overflow-tooltip="true"
|
|
73
|
-
:maxlength="2000"
|
|
74
|
-
show-word-limit
|
|
75
|
-
v-model="node.reason"
|
|
76
|
-
:disabled="readonly"
|
|
77
|
-
placeholder="请输入具体评价依据,不超过2000字"
|
|
78
|
-
@input="onReasonInput(node)"
|
|
79
|
-
/>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
77
|
+
<div class="select-top">{{ option.scoreText }}</div>
|
|
78
|
+
<div class="select-bottom">{{ option.reason }}</div>
|
|
79
|
+
</el-option>
|
|
80
|
+
</el-select>
|
|
81
|
+
<el-input
|
|
82
|
+
v-else-if="row.sourceType === 3"
|
|
83
|
+
class="qual-manual-input"
|
|
84
|
+
type="number"
|
|
85
|
+
size="small"
|
|
86
|
+
v-model="row.scoreValue"
|
|
87
|
+
:disabled="readonly"
|
|
88
|
+
placeholder="请输入评分"
|
|
89
|
+
/>
|
|
90
|
+
<span v-else>—</span>
|
|
91
|
+
</template>
|
|
92
|
+
</vxe-column>
|
|
82
93
|
|
|
83
|
-
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
94
|
+
<vxe-column :title="scoreColTitle(group)" width="120" align="center">
|
|
95
|
+
<template #default="{ row }">
|
|
96
|
+
{{ formatIndicatorScore(group, row) }}
|
|
97
|
+
</template>
|
|
98
|
+
</vxe-column>
|
|
99
|
+
|
|
100
|
+
<vxe-column
|
|
101
|
+
v-if="showModelScoreCol"
|
|
102
|
+
title="模型指标得分"
|
|
103
|
+
width="130"
|
|
104
|
+
align="center"
|
|
105
|
+
>
|
|
106
|
+
<template #default="{ row }">{{ formatScore(row.result) }}</template>
|
|
107
|
+
</vxe-column>
|
|
108
|
+
|
|
109
|
+
<vxe-column title="评价理由" min-width="240" align="center">
|
|
110
|
+
<template #default="{ row }">
|
|
111
|
+
<el-input
|
|
112
|
+
v-if="isQualSelectNode(row)"
|
|
113
|
+
class="qual-reason-input"
|
|
114
|
+
type="textarea"
|
|
115
|
+
v-title
|
|
116
|
+
:show-overflow-tooltip="true"
|
|
117
|
+
:maxlength="2000"
|
|
118
|
+
show-word-limit
|
|
119
|
+
v-model="row.reason"
|
|
120
|
+
:disabled="readonly"
|
|
121
|
+
placeholder="请输入具体评价依据,不超过2000字"
|
|
122
|
+
@input="onReasonInput(row)"
|
|
123
|
+
/>
|
|
124
|
+
</template>
|
|
125
|
+
</vxe-column>
|
|
126
|
+
</vxe-table>
|
|
105
127
|
</div>
|
|
106
128
|
</div>
|
|
107
129
|
</template>
|
|
108
130
|
|
|
109
131
|
<script>
|
|
110
|
-
import {
|
|
132
|
+
import {
|
|
133
|
+
resultByShowStyle,
|
|
134
|
+
indicatorScoreText,
|
|
135
|
+
showLevelSerial,
|
|
136
|
+
isQualIndicator,
|
|
137
|
+
fullScoreText
|
|
138
|
+
} from './helpers'
|
|
111
139
|
|
|
112
140
|
export default {
|
|
113
141
|
name: 'MeasureQualAnalysis',
|
|
@@ -128,6 +156,12 @@ export default {
|
|
|
128
156
|
showSerial() {
|
|
129
157
|
return showLevelSerial(this.modelWrap)
|
|
130
158
|
},
|
|
159
|
+
showWeightCol() {
|
|
160
|
+
return this.modelWrap.showWeight === 1 && !this.measureCtx().calcMode
|
|
161
|
+
},
|
|
162
|
+
showModelScoreCol() {
|
|
163
|
+
return !this.measureCtx().calcMode
|
|
164
|
+
},
|
|
131
165
|
/** 始终绑定 leafList 原始节点,避免 vxe 展开区副本导致 v-model 丢失 */
|
|
132
166
|
displayGroups() {
|
|
133
167
|
const resolve = this.measureCtx().resolveLeafNode
|
|
@@ -156,16 +190,26 @@ export default {
|
|
|
156
190
|
(isQualIndicator(node) && node.optionList && node.optionList.length)
|
|
157
191
|
)
|
|
158
192
|
},
|
|
159
|
-
|
|
193
|
+
scoreColTitle(group) {
|
|
194
|
+
if (group.itemType === 11) return '系数值'
|
|
195
|
+
return '指标得分'
|
|
196
|
+
},
|
|
197
|
+
formatIndicatorScore(group, node) {
|
|
160
198
|
if (group.itemType === 11) {
|
|
161
|
-
return
|
|
199
|
+
return this.formatScore(node.result)
|
|
162
200
|
}
|
|
163
|
-
return
|
|
201
|
+
return indicatorScoreText(node, this.modelWrap)
|
|
164
202
|
},
|
|
165
203
|
formatScore(val) {
|
|
166
204
|
if (val === '' || val == null) return ''
|
|
167
205
|
return resultByShowStyle({ result: val }, this.modelWrap)
|
|
168
206
|
},
|
|
207
|
+
formatFullScore(node) {
|
|
208
|
+
return fullScoreText(node, this.modelWrap) || '—'
|
|
209
|
+
},
|
|
210
|
+
evalStandardText(node) {
|
|
211
|
+
return node.indicatorRemark || this.selectedOptionReason(node) || '—'
|
|
212
|
+
},
|
|
169
213
|
resolveNode(node) {
|
|
170
214
|
const resolve = this.measureCtx().resolveLeafNode
|
|
171
215
|
return resolve ? resolve(node) || node : node
|
|
@@ -293,105 +337,14 @@ export default {
|
|
|
293
337
|
|
|
294
338
|
.qual-table {
|
|
295
339
|
width: 100%;
|
|
296
|
-
border: 1px solid #ebeef5;
|
|
297
|
-
border-radius: 2px;
|
|
298
|
-
overflow: hidden;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
.qual-row {
|
|
302
|
-
display: flex;
|
|
303
|
-
width: 100%;
|
|
304
|
-
min-height: 52px;
|
|
305
|
-
border-bottom: 1px solid #ebeef5;
|
|
306
|
-
box-sizing: border-box;
|
|
307
|
-
|
|
308
|
-
&:last-child {
|
|
309
|
-
border-bottom: none;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
.qual-cell {
|
|
314
|
-
padding: 10px 12px;
|
|
315
|
-
border-right: 1px solid #ebeef5;
|
|
316
|
-
box-sizing: border-box;
|
|
317
|
-
min-width: 0;
|
|
318
|
-
font-size: 14px;
|
|
319
|
-
color: #303133;
|
|
320
|
-
line-height: 1.5;
|
|
321
|
-
|
|
322
|
-
&:last-child {
|
|
323
|
-
border-right: none;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/* 指标名称 | 选项 | 得分 | 评价理由 */
|
|
328
|
-
.qual-cell-name {
|
|
329
|
-
flex: 0 0 16%;
|
|
330
|
-
background: #fafafa;
|
|
331
|
-
color: #606266;
|
|
332
|
-
display: flex;
|
|
333
|
-
align-items: center;
|
|
334
|
-
word-break: break-all;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
.qual-cell-select {
|
|
338
|
-
flex: 0 0 28%;
|
|
339
|
-
display: flex;
|
|
340
|
-
flex-direction: column;
|
|
341
|
-
justify-content: center;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
.qual-cell-score {
|
|
345
|
-
flex: 0 0 12%;
|
|
346
|
-
display: flex;
|
|
347
|
-
flex-direction: column;
|
|
348
|
-
justify-content: center;
|
|
349
|
-
gap: 4px;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
.qual-cell-reason {
|
|
353
|
-
flex: 0 0 44%;
|
|
354
|
-
display: flex;
|
|
355
|
-
flex-direction: column;
|
|
356
|
-
gap: 6px;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
.qual-cell-manual {
|
|
360
|
-
flex: 1;
|
|
361
|
-
display: flex;
|
|
362
|
-
align-items: center;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
.qual-inline-label {
|
|
366
|
-
flex-shrink: 0;
|
|
367
|
-
font-size: 14px;
|
|
368
|
-
color: #606266;
|
|
369
|
-
line-height: 1.4;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
.qual-score-value {
|
|
373
|
-
min-height: 20px;
|
|
374
|
-
word-break: break-all;
|
|
375
340
|
}
|
|
376
341
|
|
|
342
|
+
.qual-select,
|
|
377
343
|
.qual-reason-input,
|
|
378
344
|
.qual-manual-input {
|
|
379
345
|
width: 100%;
|
|
380
346
|
}
|
|
381
347
|
|
|
382
|
-
.qual-select {
|
|
383
|
-
width: 100%;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
.option-reason {
|
|
387
|
-
margin-top: 4px;
|
|
388
|
-
color: #999;
|
|
389
|
-
font-size: 14px;
|
|
390
|
-
line-height: 1.4;
|
|
391
|
-
white-space: normal;
|
|
392
|
-
word-wrap: break-word;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
348
|
.select-top {
|
|
396
349
|
margin-top: 2px;
|
|
397
350
|
height: 14px;
|
|
@@ -409,7 +362,15 @@ export default {
|
|
|
409
362
|
white-space: normal;
|
|
410
363
|
word-wrap: break-word;
|
|
411
364
|
}
|
|
365
|
+
|
|
412
366
|
/deep/ .el-select .el-input__inner {
|
|
413
367
|
text-align: center;
|
|
414
368
|
}
|
|
369
|
+
|
|
370
|
+
/deep/ .vxe-body--column {
|
|
371
|
+
padding-top: 6px;
|
|
372
|
+
padding-bottom: 6px;
|
|
373
|
+
height: auto !important;
|
|
374
|
+
max-height: unset !important;
|
|
375
|
+
}
|
|
415
376
|
</style>
|
|
@@ -53,6 +53,18 @@
|
|
|
53
53
|
:d-num="digits"
|
|
54
54
|
v-model="cell.value"
|
|
55
55
|
/>
|
|
56
|
+
<el-tooltip
|
|
57
|
+
v-else-if="showFormulaTip"
|
|
58
|
+
placement="top"
|
|
59
|
+
effect="dark"
|
|
60
|
+
>
|
|
61
|
+
<div slot="content">
|
|
62
|
+
{{ cell.displayFormula }}:
|
|
63
|
+
<br />
|
|
64
|
+
{{ cell.relFormula }}
|
|
65
|
+
</div>
|
|
66
|
+
<span>{{ displayValue(cell) }}</span>
|
|
67
|
+
</el-tooltip>
|
|
56
68
|
<span v-else>{{ displayValue(cell) }}</span>
|
|
57
69
|
</template>
|
|
58
70
|
</div>
|
|
@@ -74,6 +86,11 @@ export default {
|
|
|
74
86
|
computed: {
|
|
75
87
|
readonly() {
|
|
76
88
|
return !!this.measureCtx().readonly
|
|
89
|
+
},
|
|
90
|
+
/** 指标值列才展示公式;得分列 column.disabled 不展示 */
|
|
91
|
+
showFormulaTip() {
|
|
92
|
+
if (!this.cell || this.column.disabled) return false
|
|
93
|
+
return !!(this.cell.displayFormula || this.cell.relFormula)
|
|
77
94
|
}
|
|
78
95
|
},
|
|
79
96
|
methods: {
|
|
@@ -53,8 +53,24 @@
|
|
|
53
53
|
</el-select>
|
|
54
54
|
</template>
|
|
55
55
|
<template v-else>
|
|
56
|
-
<
|
|
56
|
+
<el-tooltip
|
|
57
57
|
v-if="
|
|
58
|
+
row.sourceType !== 3 &&
|
|
59
|
+
(!row.optionList || !row.optionList.length) &&
|
|
60
|
+
hasFormulaFn(row)
|
|
61
|
+
"
|
|
62
|
+
placement="top"
|
|
63
|
+
effect="dark"
|
|
64
|
+
>
|
|
65
|
+
<div slot="content">
|
|
66
|
+
{{ row.displayFormula }}:
|
|
67
|
+
<br />
|
|
68
|
+
{{ row.relFormula }}
|
|
69
|
+
</div>
|
|
70
|
+
<span>{{ indicatorTextFn(row) }}</span>
|
|
71
|
+
</el-tooltip>
|
|
72
|
+
<span
|
|
73
|
+
v-else-if="
|
|
58
74
|
row.sourceType !== 3 &&
|
|
59
75
|
(!row.optionList || !row.optionList.length)
|
|
60
76
|
"
|
|
@@ -175,6 +191,9 @@ export default {
|
|
|
175
191
|
indicatorTextFn(row) {
|
|
176
192
|
return indicatorResultText(row, this.ctx.modelWrap)
|
|
177
193
|
},
|
|
194
|
+
hasFormulaFn(row) {
|
|
195
|
+
return !!(row && (row.displayFormula || row.relFormula))
|
|
196
|
+
},
|
|
178
197
|
onQualChange(row) {
|
|
179
198
|
const option = row.value
|
|
180
199
|
if (!option || !option.scoreMapID) return
|
|
@@ -32,14 +32,14 @@
|
|
|
32
32
|
<el-table-column
|
|
33
33
|
prop="name"
|
|
34
34
|
label="指标项名称"
|
|
35
|
-
width="
|
|
35
|
+
min-width="160"
|
|
36
36
|
align="center"
|
|
37
37
|
/>
|
|
38
38
|
<el-table-column
|
|
39
39
|
v-for="col in dynamicColumns(block)"
|
|
40
40
|
:key="col.prop"
|
|
41
41
|
:label="col.label"
|
|
42
|
-
:width="col.
|
|
42
|
+
:min-width="col.minWidth || 140"
|
|
43
43
|
align="center"
|
|
44
44
|
>
|
|
45
45
|
<template slot-scope="{ row }">
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="measure-sub-model-panel">
|
|
3
|
-
<!--
|
|
4
|
-
<measure-
|
|
3
|
+
<!-- 计算模型:分组外提为区块标题,指标用树表 -->
|
|
4
|
+
<measure-group-blocks
|
|
5
5
|
v-if="isCalc"
|
|
6
6
|
:nodes="subModel.children || []"
|
|
7
|
+
:group-node="subModel"
|
|
7
8
|
:level="level"
|
|
8
9
|
:number-prefix="numberPrefix"
|
|
9
10
|
calc-mode
|
|
@@ -38,7 +39,7 @@ export default {
|
|
|
38
39
|
components: {
|
|
39
40
|
MeasureEvalFlatTable,
|
|
40
41
|
MeasureStatPanel,
|
|
41
|
-
|
|
42
|
+
MeasureGroupBlocks: () => import('./MeasureGroupBlocks.vue')
|
|
42
43
|
},
|
|
43
44
|
props: {
|
|
44
45
|
subModel: {
|
|
@@ -229,7 +229,7 @@
|
|
|
229
229
|
</vxe-column>
|
|
230
230
|
</template>
|
|
231
231
|
|
|
232
|
-
<!--
|
|
232
|
+
<!-- 默认列:满分值 / 计算公式 / 评价标准 / 指标值 / 指标得分 / 模型指标得分 / 理由 -->
|
|
233
233
|
<template v-else>
|
|
234
234
|
<vxe-column title="指标满分值" width="110" align="center">
|
|
235
235
|
<template #default="{ row }">
|
|
@@ -238,6 +238,25 @@
|
|
|
238
238
|
</template>
|
|
239
239
|
</vxe-column>
|
|
240
240
|
|
|
241
|
+
<vxe-column
|
|
242
|
+
v-if="showFormulaCol"
|
|
243
|
+
field="displayFormula"
|
|
244
|
+
title="计算公式"
|
|
245
|
+
width="130"
|
|
246
|
+
align="center"
|
|
247
|
+
>
|
|
248
|
+
<template #default="{ row }">{{ row.displayFormula || '—' }}</template>
|
|
249
|
+
</vxe-column>
|
|
250
|
+
<vxe-column
|
|
251
|
+
v-if="showRemarkCol"
|
|
252
|
+
field="indicatorRemark"
|
|
253
|
+
title="评价标准"
|
|
254
|
+
width="130"
|
|
255
|
+
align="center"
|
|
256
|
+
>
|
|
257
|
+
<template #default="{ row }">{{ row.indicatorRemark || '—' }}</template>
|
|
258
|
+
</vxe-column>
|
|
259
|
+
|
|
241
260
|
<vxe-column title="指标值" min-width="260" align="center">
|
|
242
261
|
<template #default="{ row }">
|
|
243
262
|
<template v-if="isQuantIndicatorFn(row)">
|
|
@@ -298,6 +317,17 @@
|
|
|
298
317
|
</vxe-column>
|
|
299
318
|
|
|
300
319
|
<vxe-column title="指标得分" width="140" align="center">
|
|
320
|
+
<template #default="{ row }">
|
|
321
|
+
<template v-if="isQuantIndicatorFn(row)">
|
|
322
|
+
<div>{{ indicatorScoreFn(row) }}</div>
|
|
323
|
+
</template>
|
|
324
|
+
<template v-else-if="isSubModelFn(row) && ctx.parentCalced">
|
|
325
|
+
<div>{{ indicatorScoreFn(row) }}</div>
|
|
326
|
+
</template>
|
|
327
|
+
<span v-else class="color-placeholder">—</span>
|
|
328
|
+
</template>
|
|
329
|
+
</vxe-column>
|
|
330
|
+
<vxe-column title="模型指标得分" width="140" align="center">
|
|
301
331
|
<template #default="{ row }">
|
|
302
332
|
<template v-if="isQuantIndicatorFn(row)">
|
|
303
333
|
<div>{{ resultFn(row) }}</div>
|
|
@@ -310,7 +340,7 @@
|
|
|
310
340
|
:max="row.fullScore"
|
|
311
341
|
:disabled="ctx.readonly"
|
|
312
342
|
v-model="row.modifiedResult"
|
|
313
|
-
placeholder="
|
|
343
|
+
placeholder="修改模型指标得分"
|
|
314
344
|
/>
|
|
315
345
|
</template>
|
|
316
346
|
<template v-else-if="isSubModelFn(row) && ctx.parentCalced">
|
|
@@ -319,24 +349,6 @@
|
|
|
319
349
|
<span v-else class="color-placeholder">—</span>
|
|
320
350
|
</template>
|
|
321
351
|
</vxe-column>
|
|
322
|
-
<vxe-column
|
|
323
|
-
v-if="showFormulaCol"
|
|
324
|
-
field="displayFormula"
|
|
325
|
-
title="计算公式"
|
|
326
|
-
width="130"
|
|
327
|
-
align="center"
|
|
328
|
-
>
|
|
329
|
-
<template #default="{ row }">{{ row.displayFormula || '—' }}</template>
|
|
330
|
-
</vxe-column>
|
|
331
|
-
<vxe-column
|
|
332
|
-
v-if="showRemarkCol"
|
|
333
|
-
field="indicatorRemark"
|
|
334
|
-
title="评价标准"
|
|
335
|
-
width="130"
|
|
336
|
-
align="center"
|
|
337
|
-
>
|
|
338
|
-
<template #default="{ row }">{{ row.indicatorRemark || '—' }}</template>
|
|
339
|
-
</vxe-column>
|
|
340
352
|
|
|
341
353
|
<vxe-column
|
|
342
354
|
v-if="showModifyReasonCol"
|
|
@@ -404,6 +416,7 @@ import {
|
|
|
404
416
|
typeMeta,
|
|
405
417
|
digitsCalc,
|
|
406
418
|
resultByShowStyle,
|
|
419
|
+
indicatorScoreText,
|
|
407
420
|
indicatorResultText,
|
|
408
421
|
fullScoreText,
|
|
409
422
|
hierarchySerial,
|
|
@@ -567,6 +580,9 @@ export default {
|
|
|
567
580
|
resultFn(row) {
|
|
568
581
|
return resultByShowStyle(row, this.ctx.modelWrap)
|
|
569
582
|
},
|
|
583
|
+
indicatorScoreFn(row) {
|
|
584
|
+
return indicatorScoreText(row, this.ctx.modelWrap)
|
|
585
|
+
},
|
|
570
586
|
indicatorTextFn(row) {
|
|
571
587
|
return indicatorResultText(row, this.ctx.modelWrap)
|
|
572
588
|
},
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* sourceType:0 系统自定义 1 报表取数 2 指标取数 3 手工填报 4 标准值取数 5 系统取值 6 系统取数
|
|
9
9
|
* modifyRank:0 不调整 1 调整指标得分 2 调整指标值
|
|
10
10
|
*/
|
|
11
|
+
import { N } from 'n20-common-lib'
|
|
11
12
|
import { toFixedTrunc, addThousands } from '../common'
|
|
12
13
|
import { resolveManualFillValue, statItemChildren } from './statModelHelper'
|
|
13
14
|
|
|
@@ -83,6 +84,70 @@ export function isSubModel(row) {
|
|
|
83
84
|
return t === 'calcModel' || t === 'evalModel' || t === 'statModel'
|
|
84
85
|
}
|
|
85
86
|
|
|
87
|
+
/** 普通分组(非子模型容器) */
|
|
88
|
+
export function isGroup(row) {
|
|
89
|
+
return isContainer(row) && !isSubModel(row)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** 当前层拆成普通分组 vs 其余(指标/子模型),分组抬到表格外展示 */
|
|
93
|
+
export function splitGroupNodes(nodes) {
|
|
94
|
+
const groups = []
|
|
95
|
+
const loose = []
|
|
96
|
+
if (!Array.isArray(nodes)) return { groups, loose }
|
|
97
|
+
nodes.forEach(node => {
|
|
98
|
+
if (isGroup(node)) groups.push(node)
|
|
99
|
+
else loose.push(node)
|
|
100
|
+
})
|
|
101
|
+
return { groups, loose }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** 节点用于汇总的得分(优先调整后得分) */
|
|
105
|
+
export function nodeScoreValue(node) {
|
|
106
|
+
if (!node) return null
|
|
107
|
+
if (
|
|
108
|
+
node.modifyRank === 1 &&
|
|
109
|
+
node.modifiedResult !== '' &&
|
|
110
|
+
node.modifiedResult != null
|
|
111
|
+
) {
|
|
112
|
+
return node.modifiedResult
|
|
113
|
+
}
|
|
114
|
+
if (node.result === '' || node.result == null) return null
|
|
115
|
+
return node.result
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** 收集分组下叶子指标(子模型不计入得分小计) */
|
|
119
|
+
export function collectIndicatorScoreNodes(nodes, bucket = []) {
|
|
120
|
+
if (!Array.isArray(nodes)) return bucket
|
|
121
|
+
nodes.forEach(n => {
|
|
122
|
+
if (!n) return
|
|
123
|
+
if (isIndicator(n)) {
|
|
124
|
+
bucket.push(n)
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
if (isSubModel(n)) return
|
|
128
|
+
if (n.children && n.children.length) {
|
|
129
|
+
collectIndicatorScoreNodes(n.children, bucket)
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
return bucket
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** 分组得分小计:加总下属指标得分,无有效得分返回 null */
|
|
136
|
+
export function sumIndicatorScores(nodes) {
|
|
137
|
+
const items = collectIndicatorScoreNodes(nodes)
|
|
138
|
+
let has = false
|
|
139
|
+
let total = 0
|
|
140
|
+
items.forEach(n => {
|
|
141
|
+
const val = nodeScoreValue(n)
|
|
142
|
+
if (val === null) return
|
|
143
|
+
const num = Number(val)
|
|
144
|
+
if (Number.isNaN(num)) return
|
|
145
|
+
has = true
|
|
146
|
+
total += num
|
|
147
|
+
})
|
|
148
|
+
return has ? total : null
|
|
149
|
+
}
|
|
150
|
+
|
|
86
151
|
/** 测算场景下子模型的统一展示名称 */
|
|
87
152
|
export const SUB_MODEL_LABEL = '测算子模型'
|
|
88
153
|
|
|
@@ -152,7 +217,7 @@ export function digitsCalc(row, modelWrap) {
|
|
|
152
217
|
return modelWrap ? modelWrap.digits : 2
|
|
153
218
|
}
|
|
154
219
|
|
|
155
|
-
/**
|
|
220
|
+
/** 模型指标得分 / 模型指标系数数值(权重之后的 result) */
|
|
156
221
|
export function resultByShowStyle(row, modelWrap) {
|
|
157
222
|
let val = ''
|
|
158
223
|
const digits = digitsCalc(row, modelWrap)
|
|
@@ -168,6 +233,21 @@ export function resultByShowStyle(row, modelWrap) {
|
|
|
168
233
|
return val
|
|
169
234
|
}
|
|
170
235
|
|
|
236
|
+
/**
|
|
237
|
+
* 指标得分(权重之前):result * 100 / weight
|
|
238
|
+
* 与旧测算详情 valueScore 算法一致;无权重时不展示
|
|
239
|
+
*/
|
|
240
|
+
export function indicatorScoreText(row, modelWrap) {
|
|
241
|
+
if (!row || (row.result !== 0 && (row.result === '' || row.result == null))) {
|
|
242
|
+
return ''
|
|
243
|
+
}
|
|
244
|
+
if (!row.weight) {
|
|
245
|
+
return resultByShowStyle(row, modelWrap)
|
|
246
|
+
}
|
|
247
|
+
const digits = digitsCalc(row, modelWrap)
|
|
248
|
+
return N.div(N.mul(row.result, 100, digits + 2), row.weight, digits)
|
|
249
|
+
}
|
|
250
|
+
|
|
171
251
|
/** 指标满分值展示 */
|
|
172
252
|
export function fullScoreText(row, modelWrap) {
|
|
173
253
|
if (!row || (row.fullScore !== 0 && !row.fullScore)) return ''
|
|
@@ -29,6 +29,15 @@
|
|
|
29
29
|
>
|
|
30
30
|
{{ allExpanded ? '全部收起' : '全部展开' }}
|
|
31
31
|
</el-button>
|
|
32
|
+
<el-button
|
|
33
|
+
v-if="showPrint"
|
|
34
|
+
size="small"
|
|
35
|
+
plain
|
|
36
|
+
:loading="printLoading"
|
|
37
|
+
@click="printFn"
|
|
38
|
+
>
|
|
39
|
+
打印
|
|
40
|
+
</el-button>
|
|
32
41
|
</div>
|
|
33
42
|
</div>
|
|
34
43
|
|
|
@@ -210,13 +219,10 @@
|
|
|
210
219
|
:sub-model="section.container"
|
|
211
220
|
:level="1"
|
|
212
221
|
/>
|
|
213
|
-
<measure-
|
|
214
|
-
v-else-if="isQualOnlySection(section)"
|
|
215
|
-
:groups="qualSectionGroups(section)"
|
|
216
|
-
/>
|
|
217
|
-
<measure-tree-table
|
|
222
|
+
<measure-group-blocks
|
|
218
223
|
v-else-if="section.nodes && section.nodes.length"
|
|
219
224
|
:nodes="section.nodes"
|
|
225
|
+
:group-node="section.container"
|
|
220
226
|
:level="1"
|
|
221
227
|
:calc-mode="calcRootModel"
|
|
222
228
|
:section="section"
|
|
@@ -228,8 +234,7 @@
|
|
|
228
234
|
|
|
229
235
|
<script>
|
|
230
236
|
import { SecondaryTab } from './ui'
|
|
231
|
-
import
|
|
232
|
-
import MeasureQualAnalysis from './MeasureQualAnalysis.vue'
|
|
237
|
+
import MeasureGroupBlocks from './MeasureGroupBlocks.vue'
|
|
233
238
|
import MeasureSubModelPanel from './MeasureSubModelPanel.vue'
|
|
234
239
|
import MeasureStatPanel from './MeasureStatPanel.vue'
|
|
235
240
|
import {
|
|
@@ -238,9 +243,10 @@ import {
|
|
|
238
243
|
isIndicator,
|
|
239
244
|
isSubModel,
|
|
240
245
|
isStatModel,
|
|
241
|
-
isQualOnlyNodes,
|
|
242
246
|
isQualIndicator,
|
|
243
247
|
resolveQualSelection,
|
|
248
|
+
sumIndicatorScores,
|
|
249
|
+
nodeScoreValue as readNodeScore,
|
|
244
250
|
SUB_MODEL_LABEL,
|
|
245
251
|
SUB_MODEL_CALC_BTN,
|
|
246
252
|
isCalcRootModel as checkCalcRootModel,
|
|
@@ -255,13 +261,13 @@ import {
|
|
|
255
261
|
} from './statModelHelper'
|
|
256
262
|
import { withRequestTimestamp } from './api'
|
|
257
263
|
import { formatFloat2 } from '../common'
|
|
264
|
+
import { printJS } from 'n20-common-lib/src/plugins/Print'
|
|
258
265
|
|
|
259
266
|
export default {
|
|
260
267
|
name: 'MeasureCalc',
|
|
261
268
|
components: {
|
|
262
269
|
SecondaryTab,
|
|
263
|
-
|
|
264
|
-
MeasureQualAnalysis,
|
|
270
|
+
MeasureGroupBlocks,
|
|
265
271
|
MeasureSubModelPanel,
|
|
266
272
|
MeasureStatPanel
|
|
267
273
|
},
|
|
@@ -276,7 +282,11 @@ export default {
|
|
|
276
282
|
readonly: this.readonly,
|
|
277
283
|
resolveLeafNode: this.resolveLeafNode,
|
|
278
284
|
syncQualSelection: this.syncQualSelection,
|
|
279
|
-
getQualSelection: this.getQualSelection
|
|
285
|
+
getQualSelection: this.getQualSelection,
|
|
286
|
+
evalRootModel: this.evalRootModel,
|
|
287
|
+
groupWeightText: this.groupWeightText,
|
|
288
|
+
groupScoreText: this.groupScoreText,
|
|
289
|
+
groupSubtotalText: this.groupSubtotalText
|
|
280
290
|
})
|
|
281
291
|
}
|
|
282
292
|
},
|
|
@@ -315,12 +325,28 @@ export default {
|
|
|
315
325
|
condParam: {
|
|
316
326
|
type: Object,
|
|
317
327
|
default: () => ({})
|
|
328
|
+
},
|
|
329
|
+
/** 是否展示打印按钮,由业务系统做权限判断后传入,默认不展示 */
|
|
330
|
+
showPrint: {
|
|
331
|
+
type: Boolean,
|
|
332
|
+
default: false
|
|
333
|
+
},
|
|
334
|
+
/** 授信申报信息,打印时原样传给打印接口 */
|
|
335
|
+
creditInfo: {
|
|
336
|
+
type: Object,
|
|
337
|
+
default: () => ({})
|
|
338
|
+
},
|
|
339
|
+
/** 评级申报信息,打印时原样传给打印接口 */
|
|
340
|
+
gradeInfo: {
|
|
341
|
+
type: Object,
|
|
342
|
+
default: () => ({})
|
|
318
343
|
}
|
|
319
344
|
},
|
|
320
345
|
data() {
|
|
321
346
|
return {
|
|
322
347
|
loading: false,
|
|
323
348
|
calcLoading: false,
|
|
349
|
+
printLoading: false,
|
|
324
350
|
model: { type: 1, name: '', code: '', digits: 2, modelTreeVO: {} },
|
|
325
351
|
sections: [],
|
|
326
352
|
anchorTabs: [],
|
|
@@ -352,18 +378,18 @@ export default {
|
|
|
352
378
|
messageStr: '',
|
|
353
379
|
options: [
|
|
354
380
|
{ value: '13', label: '13月(已审计报表)' },
|
|
355
|
-
{ value: '
|
|
356
|
-
{ value: '2', label: '2月' },
|
|
357
|
-
{ value: '3', label: '3月' },
|
|
358
|
-
{ value: '4', label: '4月' },
|
|
359
|
-
{ value: '5', label: '5月' },
|
|
360
|
-
{ value: '6', label: '6月' },
|
|
361
|
-
{ value: '7', label: '7月' },
|
|
362
|
-
{ value: '8', label: '8月' },
|
|
363
|
-
{ value: '9', label: '9月' },
|
|
364
|
-
{ value: '10', label: '10月' },
|
|
381
|
+
{ value: '12', label: '12月' },
|
|
365
382
|
{ value: '11', label: '11月' },
|
|
366
|
-
{ value: '
|
|
383
|
+
{ value: '10', label: '10月' },
|
|
384
|
+
{ value: '9', label: '9月' },
|
|
385
|
+
{ value: '8', label: '8月' },
|
|
386
|
+
{ value: '7', label: '7月' },
|
|
387
|
+
{ value: '6', label: '6月' },
|
|
388
|
+
{ value: '5', label: '5月' },
|
|
389
|
+
{ value: '4', label: '4月' },
|
|
390
|
+
{ value: '3', label: '3月' },
|
|
391
|
+
{ value: '2', label: '2月' },
|
|
392
|
+
{ value: '1', label: '1月' }
|
|
367
393
|
]
|
|
368
394
|
}
|
|
369
395
|
},
|
|
@@ -423,9 +449,20 @@ export default {
|
|
|
423
449
|
}
|
|
424
450
|
return this.relFormula || this.displayFormula || '--'
|
|
425
451
|
},
|
|
426
|
-
/**
|
|
452
|
+
/** 表格内仍可展开的容器(分组已外提,只剩子模型) */
|
|
427
453
|
hasAnyContainer() {
|
|
428
|
-
|
|
454
|
+
const walk = nodes => {
|
|
455
|
+
if (!Array.isArray(nodes)) return false
|
|
456
|
+
return nodes.some(n => {
|
|
457
|
+
if (isSubModel(n)) return true
|
|
458
|
+
if (n && n.children && n.children.length) return walk(n.children)
|
|
459
|
+
return false
|
|
460
|
+
})
|
|
461
|
+
}
|
|
462
|
+
return this.sections.some(s => {
|
|
463
|
+
if (s.container && isSubModel(s.container)) return true
|
|
464
|
+
return walk(s.nodes)
|
|
465
|
+
})
|
|
429
466
|
},
|
|
430
467
|
/** 仍有必填项未完善时显示黄字提示 */
|
|
431
468
|
showIncompleteTip() {
|
|
@@ -476,17 +513,6 @@ export default {
|
|
|
476
513
|
subModelResultText(node) {
|
|
477
514
|
return formatSubModelResult(node, this.model)
|
|
478
515
|
},
|
|
479
|
-
isQualOnlySection(section) {
|
|
480
|
-
return isQualOnlyNodes(section.nodes)
|
|
481
|
-
},
|
|
482
|
-
qualSectionGroups(section) {
|
|
483
|
-
return [
|
|
484
|
-
{
|
|
485
|
-
name: '',
|
|
486
|
-
children: (section.nodes || []).map(n => this.resolveLeafNode(n) || n)
|
|
487
|
-
}
|
|
488
|
-
]
|
|
489
|
-
},
|
|
490
516
|
/** 表格展开区可能是副本节点,统一解析到 leafList / qualList 原始引用 */
|
|
491
517
|
resolveLeafNode(node) {
|
|
492
518
|
return this.findQualNode(node && node.tid, node && node.itemID, node)
|
|
@@ -842,25 +868,28 @@ export default {
|
|
|
842
868
|
return false
|
|
843
869
|
},
|
|
844
870
|
|
|
845
|
-
/**
|
|
871
|
+
/** 单个指标的入参校验与组装(同一指标只组装一条,避免后端 findFirst 丢调整得分) */
|
|
846
872
|
checkItem(item) {
|
|
847
873
|
const obj = { scoreMapList: [], indicatorCalcList: [], state: true }
|
|
874
|
+
const displayValue =
|
|
875
|
+
item.displayStyle === 1
|
|
876
|
+
? formatFloat2(item.value / 100, this.model.digits)
|
|
877
|
+
: item.value
|
|
878
|
+
const calcItem = {
|
|
879
|
+
hasInput: true,
|
|
880
|
+
indicatorID: item.itemID,
|
|
881
|
+
tid: item.tid,
|
|
882
|
+
modifiedReason: item.modifiedReason || ''
|
|
883
|
+
}
|
|
884
|
+
let hasCalc = false
|
|
848
885
|
// 手工填报(含统计模型行转列内的可量化指标)
|
|
849
886
|
if (item.sourceType === 3 && !isQualIndicator(item)) {
|
|
850
887
|
if (!item.value && item.value !== 0) {
|
|
851
888
|
obj.state = false
|
|
852
889
|
this.messageStr += `${item.name}的指标值不可为空;`
|
|
853
890
|
}
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
indicatorID: item.itemID,
|
|
857
|
-
tid: item.tid,
|
|
858
|
-
modifiedReason: item.modifiedReason || '',
|
|
859
|
-
scoreValue:
|
|
860
|
-
item.displayStyle === 1
|
|
861
|
-
? formatFloat2(item.value / 100, this.model.digits)
|
|
862
|
-
: item.value
|
|
863
|
-
})
|
|
891
|
+
calcItem.scoreValue = displayValue
|
|
892
|
+
hasCalc = true
|
|
864
893
|
}
|
|
865
894
|
// 不可量化 + 有选项:校验选项(optionList 以 qualList 为准)
|
|
866
895
|
if (isQualIndicator(item)) {
|
|
@@ -913,16 +942,8 @@ export default {
|
|
|
913
942
|
item.indicatorResult !== null &&
|
|
914
943
|
(item.value || item.value === 0)
|
|
915
944
|
) {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
indicatorID: item.itemID,
|
|
919
|
-
tid: item.tid,
|
|
920
|
-
modifiedReason: item.modifiedReason || '',
|
|
921
|
-
modifiedVal:
|
|
922
|
-
item.displayStyle === 1
|
|
923
|
-
? formatFloat2(item.value / 100, this.model.digits)
|
|
924
|
-
: item.value
|
|
925
|
-
})
|
|
945
|
+
calcItem.modifiedVal = displayValue
|
|
946
|
+
hasCalc = true
|
|
926
947
|
}
|
|
927
948
|
// 调整项=指标得分
|
|
928
949
|
if (
|
|
@@ -931,14 +952,10 @@ export default {
|
|
|
931
952
|
item.modifyRank === 1 &&
|
|
932
953
|
(item.modifiedResult || item.modifiedResult === 0)
|
|
933
954
|
) {
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
indicatorID: item.itemID,
|
|
937
|
-
tid: item.tid,
|
|
938
|
-
modifiedReason: item.modifiedReason || '',
|
|
939
|
-
modifiedResult: item.modifiedResult
|
|
940
|
-
})
|
|
955
|
+
calcItem.modifiedResult = item.modifiedResult
|
|
956
|
+
hasCalc = true
|
|
941
957
|
}
|
|
958
|
+
if (hasCalc) obj.indicatorCalcList.push(calcItem)
|
|
942
959
|
return obj
|
|
943
960
|
},
|
|
944
961
|
|
|
@@ -1032,6 +1049,42 @@ export default {
|
|
|
1032
1049
|
}
|
|
1033
1050
|
},
|
|
1034
1051
|
|
|
1052
|
+
async printFn() {
|
|
1053
|
+
const logId = this.model.logId || this.logId || ''
|
|
1054
|
+
const modelId = this.model.modelID || this.model.id || this.id || ''
|
|
1055
|
+
if (!logId || !modelId) {
|
|
1056
|
+
this.$message.warning('请先完成测算后再打印')
|
|
1057
|
+
return
|
|
1058
|
+
}
|
|
1059
|
+
this.printLoading = true
|
|
1060
|
+
try {
|
|
1061
|
+
const res = await this.$axios.post(
|
|
1062
|
+
withRequestTimestamp('/imes/v1/indicatorModel/print'),
|
|
1063
|
+
[
|
|
1064
|
+
{
|
|
1065
|
+
logId,
|
|
1066
|
+
modelId,
|
|
1067
|
+
creditInfo: this.creditInfo || {},
|
|
1068
|
+
gradeInfo: this.gradeInfo || {}
|
|
1069
|
+
}
|
|
1070
|
+
]
|
|
1071
|
+
)
|
|
1072
|
+
if (res.code !== 0) {
|
|
1073
|
+
this.$message.error(res.msg || '打印失败')
|
|
1074
|
+
return
|
|
1075
|
+
}
|
|
1076
|
+
printJS({
|
|
1077
|
+
printable: res.data,
|
|
1078
|
+
type: 'pdf',
|
|
1079
|
+
base64: true
|
|
1080
|
+
})
|
|
1081
|
+
} catch (e) {
|
|
1082
|
+
this.$message.error('打印异常')
|
|
1083
|
+
} finally {
|
|
1084
|
+
this.printLoading = false
|
|
1085
|
+
}
|
|
1086
|
+
},
|
|
1087
|
+
|
|
1035
1088
|
/** 外层模型整体测算 */
|
|
1036
1089
|
async calc() {
|
|
1037
1090
|
if (this.readonly) return
|
|
@@ -1297,16 +1350,7 @@ export default {
|
|
|
1297
1350
|
|
|
1298
1351
|
/** 节点用于汇总的得分(优先调整后得分) */
|
|
1299
1352
|
nodeScoreValue(node) {
|
|
1300
|
-
|
|
1301
|
-
if (
|
|
1302
|
-
node.modifyRank === 1 &&
|
|
1303
|
-
node.modifiedResult !== '' &&
|
|
1304
|
-
node.modifiedResult != null
|
|
1305
|
-
) {
|
|
1306
|
-
return node.modifiedResult
|
|
1307
|
-
}
|
|
1308
|
-
if (node.result === '' || node.result == null) return null
|
|
1309
|
-
return node.result
|
|
1353
|
+
return readNodeScore(node)
|
|
1310
1354
|
},
|
|
1311
1355
|
|
|
1312
1356
|
formatScoreNum(val) {
|
|
@@ -1385,23 +1429,46 @@ export default {
|
|
|
1385
1429
|
},
|
|
1386
1430
|
|
|
1387
1431
|
/** 分区标题旁总权重(评价模型且开启显示权重) */
|
|
1388
|
-
|
|
1389
|
-
if (!this.evalRootModel || !
|
|
1432
|
+
groupWeightText(groupNode, children) {
|
|
1433
|
+
if (!this.evalRootModel || !groupNode) return ''
|
|
1390
1434
|
if (this.model.showWeight !== 1) return ''
|
|
1391
|
-
if (
|
|
1392
|
-
return this.buildGroupWeightText(
|
|
1435
|
+
if (this.isSubModel(groupNode)) return ''
|
|
1436
|
+
return this.buildGroupWeightText(
|
|
1437
|
+
groupNode,
|
|
1438
|
+
children || groupNode.children
|
|
1439
|
+
)
|
|
1440
|
+
},
|
|
1441
|
+
sectionWeightText(section) {
|
|
1442
|
+
if (!section || !section.container) return ''
|
|
1443
|
+
return this.groupWeightText(section.container, section.nodes)
|
|
1393
1444
|
},
|
|
1394
1445
|
|
|
1395
|
-
/**
|
|
1396
|
-
|
|
1397
|
-
if (!this.evalRootModel || !
|
|
1398
|
-
if (
|
|
1446
|
+
/** 分组标题旁得分(评价模型:未测算显示 --) */
|
|
1447
|
+
groupScoreText(groupNode, children) {
|
|
1448
|
+
if (!this.evalRootModel || !groupNode) return ''
|
|
1449
|
+
if (this.isSubModel(groupNode)) return ''
|
|
1399
1450
|
if (!this.parentCalced) return '总得分: --'
|
|
1400
1451
|
return (
|
|
1401
|
-
this.buildGroupScoreText(
|
|
1402
|
-
|
|
1452
|
+
this.buildGroupScoreText(
|
|
1453
|
+
groupNode,
|
|
1454
|
+
children || groupNode.children
|
|
1455
|
+
) || '总得分: --'
|
|
1403
1456
|
)
|
|
1404
1457
|
},
|
|
1458
|
+
sectionScoreText(section) {
|
|
1459
|
+
if (!section || !section.container) return ''
|
|
1460
|
+
return this.groupScoreText(section.container, section.nodes)
|
|
1461
|
+
},
|
|
1462
|
+
|
|
1463
|
+
/** 内层分组标题旁得分小计:加总下属指标得分 */
|
|
1464
|
+
groupSubtotalText(groupNode, children) {
|
|
1465
|
+
if (!this.evalRootModel || !groupNode) return ''
|
|
1466
|
+
if (this.isSubModel(groupNode)) return ''
|
|
1467
|
+
if (!this.parentCalced) return '得分小计: --'
|
|
1468
|
+
const total = sumIndicatorScores(children || groupNode.children || [])
|
|
1469
|
+
if (total === null) return '得分小计: --'
|
|
1470
|
+
return `得分小计: ${this.formatScoreNum(total)}`
|
|
1471
|
+
},
|
|
1405
1472
|
|
|
1406
1473
|
/**
|
|
1407
1474
|
* 评价模型得分文案:总分(57) = 定量分析(7) + 定性分析(50)
|
|
@@ -289,7 +289,7 @@ export async function buildStatModelTables(treeData, fetchScoreMap, modelWrap) {
|
|
|
289
289
|
)
|
|
290
290
|
|
|
291
291
|
const columns = [
|
|
292
|
-
{ label: '指标项名称', prop: 'name',
|
|
292
|
+
{ label: '指标项名称', prop: 'name', minWidth: 160, align: 'center' }
|
|
293
293
|
]
|
|
294
294
|
const list = []
|
|
295
295
|
|
|
@@ -302,7 +302,7 @@ export async function buildStatModelTables(treeData, fetchScoreMap, modelWrap) {
|
|
|
302
302
|
columns.push({
|
|
303
303
|
label,
|
|
304
304
|
prop: label,
|
|
305
|
-
|
|
305
|
+
minWidth: 140,
|
|
306
306
|
align: 'center',
|
|
307
307
|
slotName: label
|
|
308
308
|
})
|
|
@@ -313,7 +313,7 @@ export async function buildStatModelTables(treeData, fetchScoreMap, modelWrap) {
|
|
|
313
313
|
prop: item.statsName + '指标得分',
|
|
314
314
|
slotName: item.statsName + '指标得分',
|
|
315
315
|
disabled: true,
|
|
316
|
-
|
|
316
|
+
minWidth: 140,
|
|
317
317
|
align: 'center'
|
|
318
318
|
})
|
|
319
319
|
}
|