@nstc-business/imes 1.0.20 → 1.0.22

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nstc-business/imes",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "private": false,
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -101,8 +101,20 @@
101
101
  label-width="10em"
102
102
  v-if="modelData.sataMode !== 1"
103
103
  >
104
- <el-form-item label="模型得分:" v-if="modelData.type === 1">
105
- <span>{{ modelData.result.toFixed(modelData.digits) }}</span>
104
+ <el-form-item
105
+ label="模型得分:"
106
+ v-if="
107
+ modelData.type === 1 ||
108
+ (modelData.type === 3 && modelData.sataMode === 2)
109
+ "
110
+ >
111
+ <span>
112
+ {{
113
+ modelData.result || modelData.result === 0
114
+ ? Number(modelData.result).toFixed(modelData.digits)
115
+ : '--'
116
+ }}
117
+ </span>
106
118
  </el-form-item>
107
119
  <el-form-item label="模型结果:" v-if="modelData.type !== 3">
108
120
  <span>{{ modelData.resultText }}</span>
@@ -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
- <div class="qual-table">
26
- <template v-for="(node, i) in group.children">
27
- <!-- 不可量化:下拉选项 -->
28
- <div
29
- v-if="isQualSelectNode(node)"
30
- :key="'qual-' + (node._rowKey || i)"
31
- class="qual-row"
32
- >
33
- <div class="qual-cell qual-cell-name" v-title="node.name">
34
- {{ node.name }}
35
- </div>
36
- <div class="qual-cell qual-cell-select">
37
- <el-select
38
- class="qual-select"
39
- :value="node.scoreMapID"
40
- :disabled="readonly"
41
- size="small"
42
- placeholder="请选择"
43
- @change="val => onSelectChange(node, val)"
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
- <el-option
46
- v-for="option in node.optionList"
47
- :key="option.scoreMapID"
48
- :label="option.scoreText"
49
- :value="option.scoreMapID"
50
- style="height: auto"
51
- >
52
- <div class="select-top">{{ option.scoreText }}</div>
53
- <div class="select-bottom">{{ option.reason }}</div>
54
- </el-option>
55
- </el-select>
56
- <div class="option-reason">{{ selectedOptionReason(node) }}</div>
57
- </div>
58
- <div class="qual-cell qual-cell-score">
59
- <span class="qual-inline-label">
60
- {{ scoreLabel(group, node) }}
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
- <div
85
- v-else-if="node.sourceType === 3"
86
- :key="'manual-' + (node._rowKey || i)"
87
- class="qual-row"
88
- >
89
- <div class="qual-cell qual-cell-name" v-title="node.name">
90
- {{ node.name }}
91
- </div>
92
- <div class="qual-cell qual-cell-manual">
93
- <el-input
94
- class="qual-manual-input"
95
- type="number"
96
- size="small"
97
- v-model="node.scoreValue"
98
- :disabled="readonly"
99
- placeholder="请输入评分"
100
- />
101
- </div>
102
- </div>
103
- </template>
104
- </div>
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 { resultByShowStyle, showLevelSerial, isQualIndicator } from './helpers'
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
- scoreLabel(group, node) {
193
+ scoreColTitle(group) {
194
+ if (group.itemType === 11) return '系数值'
195
+ return '指标得分'
196
+ },
197
+ formatIndicatorScore(group, node) {
160
198
  if (group.itemType === 11) {
161
- return node.ratioName ? `${node.ratioName}系数值` : '系数值'
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>
@@ -79,7 +79,8 @@ export default {
79
79
  methods: {
80
80
  displayValue(cell) {
81
81
  if (this.column.disabled) {
82
- const val = cell.result
82
+ const val =
83
+ cell.result !== '' && cell.result != null ? cell.result : cell.value
83
84
  if (val === '' || val == null) return ''
84
85
  let text = Number(val).toFixed(this.digits)
85
86
  if (cell.showStyle === 2) {