@nstc-business/imes 1.0.26 → 1.0.28

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.
@@ -1,637 +1,624 @@
1
- <template>
2
- <!-- 定量分析 包含统计模型 行转列 重写 -->
3
- <div class="com-page-con">
4
- <div class="wrap" v-if="!isPrms && nodeListData">
5
- <Descriptions border>
6
- <el-descriptions-item label="总得分">
7
- {{ allresult }}
8
- </el-descriptions-item>
9
- </Descriptions>
10
- </div>
11
- <div class="table" v-for="(item, index) in tableData" :key="index">
12
- <div class="title">
13
- <div class="title-item">
14
- <span>{{ index + 1 }}.</span>
15
- {{ item.statIndicatorName }}
16
- </div>
17
- <div class="flex-box flex-lr flex-v title-item">
18
- <div class="m-l-s" v-for="(statResult, index2) in item.statsResultList" :key="index2">
19
- <span v-if="statResult.statCalMethod == 1 && statResult.statShow == 1">
20
- {{ statResult.name }}合计:
21
- {{
22
- statResult.statResult || statResult.statResult === 0
23
- ? statResult.statResult.toFixed(paramsObj.digits)
24
- : ''
25
- }}
26
- </span>
27
- </div>
28
- </div>
29
- </div>
30
-
31
- <Table :showSetsize="true" :data="item.list" :columns="item.columns" border style="width: 100%">
32
- <el-table-column prop="name" label="指标名称" slot="name" align="center">
33
- <template slot-scope="{ row }">
34
- <!-- 授信定量分析中的计算模型名称展示蓝色字体 -->
35
- <span style="color: #007aff" v-if="isPrms && row.itemType === 11">{{ row.name }}</span>
36
- <span v-else>{{ row.name }}</span>
37
- </template>
38
- </el-table-column>
39
- <template v-for="(column, index) in item.columns">
40
- <el-table-column
41
- :key="index"
42
- :slot="column.prop"
43
- v-if="column.prop != 'name'"
44
- v-bind="{ width: '150', align: 'center', 'show-overflow-tooltip': false, ...column }"
45
- >
46
- <template slot-scope="{ row }">
47
- <!-- 满分值列:按录入原样展示,不做位数格式化 -->
48
- <span v-if="column.isFullScore">
49
- {{
50
- row[column.prop]?.value || row[column.prop]?.value === 0
51
- ? String(row[column.prop].value)
52
- : ''
53
- }}
54
- </span>
55
- <!-- 手工录入的时候不显示调整框,显示手工录入的框,就是 sourceType为3-->
56
- <div v-else-if="row[column.prop]?.sourceType === 3">
57
- <span v-if="column.disabled">
58
- {{
59
- row[column.prop]?.value || row[column.prop]?.value === 0
60
- ? N.subFixed(row[column.prop]?.value, paramsObj.digits)
61
- : ''
62
- }}
63
-
64
- {{
65
- row[column.prop]?.displayStyle === 1 && (row[column.prop]?.value || row[column.prop]?.value === 0)
66
- ? '%'
67
- : ''
68
- }}
69
- </span>
70
- <div v-else>
71
- <InputNumber
72
- :d-num="paramsObj.digits"
73
- style="width: 100%"
74
- :disabled="opinionPage || isDetail"
75
- v-model="row[column.prop].value"
76
- placeholder="请输入数字"
77
- v-if="row[column.prop]?.displayStyle !== 1"
78
- ></InputNumber>
79
- <InputNumber
80
- :d-num="paramsObj.digits"
81
- type="rate"
82
- style="width: 100%"
83
- :disabled="opinionPage || isDetail"
84
- v-model="row[column.prop].value"
85
- placeholder="请输入数字"
86
- v-else-if="row[column.prop]?.displayStyle === 1"
87
- ></InputNumber>
88
- </div>
89
- </div>
90
-
91
- <!-- @change="getReason(node)" -->
92
- <div v-else-if="row[column.prop]?.sourceType === 0">
93
- <span v-if="column.disabled">
94
- {{
95
- row[column.prop]?.value || row[column.prop]?.value === 0
96
- ? N.subFixed(row[column.prop]?.value, paramsObj.digits)
97
- : ''
98
- }}
99
-
100
- {{
101
- row[column.prop]?.displayStyle === 1 && (row[column.prop]?.value || row[column.prop]?.value === 0)
102
- ? '%'
103
- : ''
104
- }}
105
- </span>
106
- <el-select
107
- v-else
108
- v-model="row[column.prop].value"
109
- :disabled="opinionPage || isDetail"
110
- placeholder="请选择"
111
- value-key="scoreMapID"
112
- >
113
- <el-option
114
- v-for="option in row[column.prop]?.optionList"
115
- :key="option.scoreText"
116
- :label="option.scoreText"
117
- :value="option"
118
- style="height: auto"
119
- >
120
- <div class="select-top">{{ option.scoreText }}</div>
121
- <div class="select-bottom">{{ option.reason }}</div>
122
- </el-option>
123
- </el-select>
124
- </div>
125
- <div v-else>
126
- <InputNumber
127
- :d-num="paramsObj.digits"
128
- style="width: 100%"
129
- :disabled="opinionPage || isDetail"
130
- v-model="row[column.prop].value"
131
- placeholder="请输入数字"
132
- v-if="
133
- row[column.prop]?.displayStyle !== 1 &&
134
- row[column.prop]?.modifyRank === 2 &&
135
- row[column.prop]?.value !== '' &&
136
- row[column.prop]?.value !== null
137
- "
138
- ></InputNumber>
139
- <InputNumber
140
- :d-num="paramsObj.digits"
141
- type="rate"
142
- style="width: 100%"
143
- :disabled="opinionPage || isDetail"
144
- v-model="row[column.prop].value"
145
- placeholder="请输入数字"
146
- v-else-if="
147
- row[column.prop]?.displayStyle === 1 &&
148
- row[column.prop]?.modifyRank === 2 &&
149
- row[column.prop]?.value !== '' &&
150
- row[column.prop]?.value !== null
151
- "
152
- ></InputNumber>
153
-
154
- <span v-else>
155
- {{
156
- row[column.prop]?.value || row[column.prop]?.value === 0
157
- ? N.subFixed(row[column.prop]?.value, paramsObj.digits)
158
- : ''
159
- }}
160
-
161
- {{
162
- row[column.prop]?.displayStyle === 1 && (row[column.prop]?.value || row[column.prop]?.value === 0)
163
- ? '%'
164
- : ''
165
- }}
166
- </span>
167
- </div>
168
- </template>
169
- </el-table-column>
170
- </template>
171
-
172
- <el-table-column
173
- prop="modifiedReason"
174
- label="调整理由"
175
- align="center"
176
- slot="modifiedReason"
177
- v-if="paramsObj.showModifyReason === 1"
178
- >
179
- <template slot-scope="scope">
180
- <el-input
181
- v-if="
182
- (scope.row.modifyRank == 2 && scope.row.modifiedVal !== '' && scope.row.modifiedVal !== null) ||
183
- (scope.row.result !== '' && scope.row.modifyRank === 1)
184
- "
185
- type="textarea"
186
- v-title
187
- :disabled="opinionPage || isDetail"
188
- :show-overflow-tooltip="true"
189
- :maxlength="200"
190
- show-word-limit
191
- v-model="scope.row.modifiedReason"
192
- placeholder="请输入具体评价依据,不超过200字"
193
- />
194
- </template>
195
- </el-table-column>
196
- </Table>
197
- </div>
198
- </div>
199
- </template>
200
-
201
- <script>
202
- import { N } from 'n20-common-lib'
203
- import { Descriptions, Table, InputNumber } from './ui'
204
- import { getScoreMap } from './api'
205
- import { formatFloat2 } from '../common'
206
- export default {
207
- name: 'EvaOfCreditConditions',
208
- components: { Descriptions, Table, InputNumber },
209
- // isPrms 授信标识 isDetail 是否是详情页 acrossShow是否横向展示
210
- props: ['data', 'ruleForms', 'canEdit', 'nodeList', 'modelId', 'isPrms', 'isDetail', 'paramsObj'],
211
- data() {
212
- return {
213
- N,
214
- tableMsg: [],
215
- tableData: [],
216
- columns: [],
217
- textarea: '',
218
- checked1: true,
219
- checked2: true,
220
- value: '',
221
- nodeListData: this.nodeList,
222
- acrossKeysList: {}
223
- }
224
- },
225
- computed: {
226
- allresult() {
227
- let result = 0
228
- // this.tableData.map(item => {
229
- // if (item.statsResultList) {
230
- // item.statsResultList.map(statsResult => {
231
- // if (statsResult.statCalMethod == 1 && statsResult.statShow == 1) {
232
- // result = result + statsResult.statResult
233
- // }
234
- // })
235
- // }
236
- // })
237
- result = this.nodeListData.result
238
- return formatFloat2(result, this.paramsObj.digits)
239
- },
240
- opinionPage() {
241
- return (
242
- (location.pathname.indexOf('opinionIndex') > -1 && location.pathname.indexOf('pending') === -1) ||
243
- location.pathname.indexOf('loanReview') > -1
244
- )
245
- }
246
- },
247
- methods: {
248
- // 指标值是否可录入
249
- showInput(row) {
250
- // 授信定量分析指标值,系统取数可编辑 手工填报:3
251
- if (
252
- row.sourceType == 3 &&
253
- (location.pathname.indexOf('CreditApplication') > -1 || location.pathname.indexOf('ratingapplication') > -1)
254
- ) {
255
- return true
256
- } else {
257
- return false
258
- }
259
- },
260
- save() {
261
- // this.$emit("saveCredit")
262
- this.$message({
263
- message: '移至授信信息页签保存',
264
- type: 'warning'
265
- })
266
- },
267
- submit() {
268
- // this.$emit("saveCredit")
269
- this.$message({
270
- message: '移至授信信息页签上报',
271
- type: 'warning'
272
- })
273
- },
274
- initColumns(list, acrossKeys) {
275
- this.columns = [
276
- { slotName: 'name' },
277
- { slotName: 'weight' },
278
- { slotName: 'fullScore' },
279
- { slotName: 'indicatorResult' },
280
- { slotName: 'ratioName' },
281
- { slotName: 'result1' },
282
- { slotName: 'result2' },
283
- { slotName: 'modifiedReason' }
284
- // { slotName: 'modifiedResult' }
285
- ]
286
- this.nodeListData = list
287
- if (list && this.nodeListData.children) {
288
- this.tableData = this.nodeListData.children
289
- if (acrossKeys) {
290
- let columsAdd = []
291
- this.acrossKeysList = {}
292
- acrossKeys.forEach(item => {
293
- columsAdd.push({ slotName: item })
294
- this.acrossKeysList[item] = { indicatorID: '', key: item, sourceType: '', value: '' }
295
- })
296
- this.columns.splice(3, 0, ...columsAdd)
297
- }
298
- this.tableData.forEach(
299
- item =>
300
- // indicatorResult 系统指标数
301
- // modifiedVal 修改的指标值
302
- // Result 旧的得分
303
- // modifiedResult 修改得分
304
- item?.children &&
305
- item?.children.forEach((child, i) => {
306
- // 如果indicatorValText有值,把indicatorValText赋值给indicatorResult
307
- child.indicatorResult = child.indicatorValText ? child.indicatorValText : child.indicatorResult
308
- // modifyRank===1 为可调整指标得分,如果modifiedResult为空,把result赋值给modifiedResult
309
- // modifyRank===2 为可调整指标值,如果modifiedVal为空,把indicatorResult赋值给modifiedVal
310
- // child.modifiedResult == '' ?
311
- if (child.modifyRank === 1) {
312
- child.modifiedResult = child.result || child.modifiedResult
313
- }
314
- child.modifiedVal = child.modifiedVal !== '' ? child.modifiedVal : child.indicatorResult
315
- // 手工录入的时候,如果indicatorResult没值,给默认值defaultVal
316
- if (child.sourceType === 3) {
317
- child.indicatorResult =
318
- !child.indicatorResult && child.indicatorResult !== 0 ? child.defaultVal : child.indicatorResult
319
- }
320
- if (acrossKeys) {
321
- child = { ...child, ...this.acrossKeysList }
322
- for (let el in this.acrossKeysList) {
323
- let filterIt = child.acrossLabelVos.filter(it => it.key === el)
324
- if (filterIt && filterIt.length > 0) {
325
- item.children[i][el] = filterIt[0]
326
- }
327
- }
328
- }
329
- })
330
- )
331
- }
332
- },
333
-
334
- /**
335
- * rankType
336
- * 0 取指标值
337
- * 1 分段模糊化打分
338
- * 2 公式模糊化打分
339
- * 3 分段模糊化公式打分
340
- * 4 企业绩效评估标准打分
341
- * 5 评价等级化取值
342
- * 6 分段模糊化取值
343
- * 7 特殊化打分
344
- * 8 标准值打分
345
- * 9 统计项运算
346
- * 10 手工录入
347
- * 11 分段取值
348
- */
349
- /**
350
- * 数据行转列
351
- */
352
- async initColumnsRewrite(treeData) {
353
- const statCalResult = treeData.statCalResult
354
- this.nodeListData = treeData
355
- const promiseAll2 = statCalResult.map(async item1 => {
356
- let arr = []
357
- const digui = children => {
358
- children.forEach(item => {
359
- if (item.isLeaf == 2) {
360
- const obj = {}
361
- for (let key in item) {
362
- obj[key] = item[key]
363
- }
364
- if (item1.pid == item.pid) {
365
- arr.push(obj)
366
- }
367
- } else {
368
- digui(item.children)
369
- }
370
- })
371
- }
372
- digui(treeData?.children)
373
- item1.children = arr
374
- const columns = [{ label: '指标项名称', prop: 'name', width: '250px', align: 'center' }]
375
- const list = []
376
- // 所有的指标项 都是共用一个表头的
377
- // 不管有几个指标项 表头都是一致的所以取第一个数据就可以了
378
- item1.children &&
379
- item1.children[0] &&
380
- item1.children[0].children &&
381
- item1.children[0].children.map(item => {
382
- const obj = item1.statsResultList.find(stats => stats.name == item.statsName)
383
- // 指标取数:任一行开启「是否展示满分值」则插入满分值列
384
- const showFullScoreCol =
385
- obj &&
386
- obj.calType == 0 &&
387
- item1.children.some(row => {
388
- const child = (row.children || []).find(c => c.statsName === item.statsName)
389
- return child && child.showFullScore !== 0
390
- })
391
- if (showFullScoreCol) {
392
- columns.push({
393
- label: item.statsName + '满分值',
394
- prop: item.statsName + '满分值',
395
- slotName: item.statsName + '满分值',
396
- disabled: true,
397
- isFullScore: true,
398
- width: '200px',
399
- align: 'center'
400
- })
401
- }
402
- const label = obj.calType == 0 ? item.statsName + '指标值' : item.statsName
403
- const columnsItem = {
404
- label: label,
405
- prop: label,
406
- width: '250px',
407
- align: 'center',
408
- slotName: label
409
- }
410
- columns.push(columnsItem)
411
- if (obj && obj.statShow == 1) {
412
- // 得分列不能输入
413
- if ([0].includes(obj.calType)) {
414
- const columnsItemAdd = {
415
- label: item.statsName + '指标得分',
416
- prop: item.statsName + '指标得分',
417
- slotName: item.statsName + '指标得分',
418
- disabled: true, // 得分列不能输入 只做显示
419
- width: '250px',
420
- align: 'center'
421
- }
422
- columns.push(columnsItemAdd)
423
- }
424
- }
425
- })
426
- // 有几个指标项就有几条数据
427
- const promiseAll1 = item1.children.map(async item2 => {
428
- const listItem = {}
429
- listItem.name = item2.folderName || item2.name
430
- listItem.pid = item2.pid
431
- const promiseAll = item2.children.map(async item => {
432
- const obj = item1.statsResultList.find(stats => stats.name == item.statsName)
433
- const label = obj.calType == 0 ? item.statsName + '指标值' : item.statsName
434
- // 如果indicatorValText有值,把indicatorValText赋值给indicatorResult
435
- item.indicatorResult = item.indicatorValText ? item.indicatorValText : item.indicatorResult
436
- let value = ''
437
- // 指标取数来源
438
- switch (item.sourceType) {
439
- // 手工填报
440
- case 3:
441
- value = item.indicatorResult
442
- break
443
- // 系统自定义
444
- case 0:
445
- value = {}
446
- break
447
- default:
448
- // 指标项取值方式
449
- switch (item.rankType) {
450
- // 手工录入
451
- case 10:
452
- value = item.formula
453
- break
454
- // 统计项运算
455
- case 9:
456
- value = item.result
457
- break
458
- default:
459
- value = item.indicatorResult
460
- break
461
- }
462
- break
463
- }
464
- // 系统自定义 不可量化指标用
465
- if (item.sourceType != 3 && item.itemType == 22) {
466
- const { data } = await getScoreMap({ id: item.itemID })
467
- item.optionList = data
468
- const obj = item.optionList.find(item2 => item2.scoreValue == item.indicatorResult)
469
- if (obj) {
470
- value = obj
471
- }
472
- }
473
- if ([0].includes(obj.calType) && item.showFullScore !== 0) {
474
- const fullScore =
475
- item.fullScore === 0 || item.fullScore ? item.fullScore : ''
476
- listItem[item.statsName + '满分值'] = {
477
- ...item,
478
- value: fullScore,
479
- result: fullScore,
480
- sourceType: '',
481
- displayStyle: 0,
482
- calcState: false
483
- }
484
- }
485
- if ([0].includes(obj.calType)) {
486
- // 得分列清空 sourceType 得分列用result
487
- listItem[item.statsName + '指标得分'] = {
488
- ...item,
489
- value: item.result,
490
- sourceType: '',
491
- displayStyle: 0,
492
- calcState: false // 不参与计算传值
493
- }
494
- }
495
- listItem[label] = { ...item, value }
496
- return
497
- })
498
- await Promise.all(promiseAll)
499
- list.push(listItem)
500
- return
501
- })
502
- await Promise.all(promiseAll1)
503
- item1.columns = columns
504
- item1.list = list
505
- return item1
506
- })
507
-
508
- const tableData = await Promise.all(promiseAll2)
509
- this.tableData = tableData
510
- },
511
-
512
- /** 计算效验 */
513
- validateFn() {
514
- const obj = {
515
- scoreMapList: [],
516
- indicatorCalcList: [],
517
- state: true
518
- }
519
- this.tableData.map(item => {
520
- const { list } = item
521
- list.map(listItem => {
522
- Object.keys(listItem).map(key => {
523
- switch (listItem[key]['sourceType']) {
524
- case 3:
525
- if (!listItem[key].value && listItem[key].value !== 0) {
526
- obj.state = false
527
- return
528
- }
529
- obj.indicatorCalcList.push({
530
- hasInput: true,
531
- indicatorID: listItem[key].itemID,
532
- modifiedReason: listItem[key].modifiedReason,
533
- scoreValue:
534
- listItem[key].displayStyle == 1
535
- ? formatFloat2(listItem[key].value / 100, parseInt(this.paramsObj.digits || 0) + 2)
536
- : listItem[key].value
537
- })
538
- break
539
- default:
540
- if (
541
- listItem[key].itemType == 22 &&
542
- listItem[key]?.optionList?.length > 0 &&
543
- listItem[key].calcState != false
544
- ) {
545
- if (!listItem[key].value?.scoreMapID) {
546
- obj.state = false
547
- return
548
- }
549
- obj.scoreMapList.push({
550
- indicatorID: listItem[key].value?.indicatorID,
551
- modifiedReason: listItem[key]?.modifiedReason,
552
- scoreMapID: listItem[key].value?.scoreMapID,
553
- scoreText: listItem[key].value?.scoreText,
554
- scoreValue: listItem[key].value?.scoreValue
555
- })
556
- }
557
-
558
- break
559
- }
560
- })
561
- })
562
- })
563
-
564
- return obj
565
- }
566
- }
567
- }
568
- </script>
569
-
570
- <style lang="less" scoped>
571
- .com-page-con {
572
- overflow: hidden;
573
- padding: 0 8px;
574
-
575
- .wrap {
576
- width: 100%;
577
- display: flex;
578
-
579
- .wrap-item {
580
- display: flex;
581
- width: 25%;
582
- height: 34px;
583
- border: 1px solid #dfe6ee;
584
- justify-content: flex-start;
585
- align-items: center;
586
- padding: 0 15px;
587
-
588
- &:nth-child(2n + 1) {
589
- background-color: #e5efff;
590
- justify-content: flex-end;
591
- }
592
- }
593
- }
594
-
595
- .title {
596
- // margin-top:20px;
597
- height: 30px;
598
- align-items: center;
599
- display: flex;
600
-
601
- .title-item {
602
- display: flex;
603
- justify-content: flex-start;
604
- width: 50%;
605
- }
606
- }
607
-
608
- .btn-grop {
609
- display: flex;
610
- background: #ffffff;
611
- box-shadow: 0px -2px 6px 0px rgba(92, 100, 113, 0.11);
612
- justify-content: center;
613
- padding: 20px 0;
614
- }
615
- }
616
-
617
- .select-top {
618
- margin-top: 2px;
619
- height: 14px;
620
- line-height: 16px;
621
- font-size: 14px;
622
- }
623
-
624
- .select-bottom {
625
- margin-top: 1px;
626
- min-height: 14px;
627
- line-height: 16px;
628
- color: #999999;
629
- font-size: 13px;
630
- max-width: 500px;
631
- white-space: normal; /* 允许换行 */
632
- word-wrap: break-word; /* 在长单词或 URL 地址内部进行换行 */
633
- }
634
- /deep/ .el-select .el-input__inner {
635
- text-align: center;
636
- }
637
- </style>
1
+ <template>
2
+ <!-- 定量分析 包含统计模型 行转列 重写 -->
3
+ <div class="com-page-con">
4
+ <div class="wrap" v-if="!isPrms && nodeListData">
5
+ <Descriptions border>
6
+ <el-descriptions-item label="总得分">
7
+ {{ allresult }}
8
+ </el-descriptions-item>
9
+ </Descriptions>
10
+ </div>
11
+ <div class="table" v-for="(item, index) in tableData" :key="index">
12
+ <div class="title">
13
+ <div class="title-item">
14
+ <span>{{ index + 1 }}.</span>
15
+ {{ item.statIndicatorName }}
16
+ </div>
17
+ <div class="flex-box flex-lr flex-v title-item">
18
+ <div class="m-l-s" v-for="(statResult, index2) in item.statsResultList" :key="index2">
19
+ <span v-if="statResult.statCalMethod == 1 && statResult.statShow == 1">
20
+ {{ statResult.name }}合计:
21
+ {{
22
+ formatScoreCell(statResult.statResult)
23
+ }}
24
+ </span>
25
+ </div>
26
+ </div>
27
+ </div>
28
+
29
+ <Table :showSetsize="true" :data="item.list" :columns="item.columns" border style="width: 100%">
30
+ <el-table-column prop="name" label="指标名称" slot="name" align="center">
31
+ <template slot-scope="{ row }">
32
+ <!-- 授信定量分析中的计算模型名称展示蓝色字体 -->
33
+ <span style="color: #007aff" v-if="isPrms && row.itemType === 11">{{ row.name }}</span>
34
+ <span v-else>{{ row.name }}</span>
35
+ </template>
36
+ </el-table-column>
37
+ <template v-for="(column, index) in item.columns">
38
+ <el-table-column
39
+ :key="index"
40
+ :slot="column.prop"
41
+ v-if="column.prop != 'name'"
42
+ v-bind="{ width: '150', align: 'center', 'show-overflow-tooltip': false, ...column }"
43
+ >
44
+ <template slot-scope="{ row }">
45
+ <!-- 满分值列:按录入原样展示,不做位数格式化 -->
46
+ <span v-if="column.isFullScore">
47
+ {{
48
+ row[column.prop]?.value || row[column.prop]?.value === 0
49
+ ? String(row[column.prop].value)
50
+ : ''
51
+ }}
52
+ </span>
53
+ <!-- 手工录入的时候不显示调整框,显示手工录入的框,就是 sourceType为3-->
54
+ <div v-else-if="row[column.prop]?.sourceType === 3">
55
+ <span v-if="column.disabled">
56
+ {{ formatScoreCell(row[column.prop]?.value) }}
57
+ </span>
58
+ <div v-else>
59
+ <InputNumber
60
+ :d-num="paramsObj.digits"
61
+ style="width: 100%"
62
+ :disabled="opinionPage || isDetail"
63
+ v-model="row[column.prop].value"
64
+ placeholder="请输入数字"
65
+ v-if="row[column.prop]?.displayStyle !== 1"
66
+ ></InputNumber>
67
+ <InputNumber
68
+ :d-num="paramsObj.digits"
69
+ type="rate"
70
+ style="width: 100%"
71
+ :disabled="opinionPage || isDetail"
72
+ v-model="row[column.prop].value"
73
+ placeholder="请输入数字"
74
+ v-else-if="row[column.prop]?.displayStyle === 1"
75
+ ></InputNumber>
76
+ </div>
77
+ </div>
78
+
79
+ <!-- @change="getReason(node)" -->
80
+ <div v-else-if="row[column.prop]?.sourceType === 0">
81
+ <span v-if="column.disabled">
82
+ {{ formatScoreCell(row[column.prop]?.value) }}
83
+ </span>
84
+ <el-select
85
+ v-else
86
+ v-model="row[column.prop].value"
87
+ :disabled="opinionPage || isDetail"
88
+ placeholder="请选择"
89
+ value-key="scoreMapID"
90
+ >
91
+ <el-option
92
+ v-for="option in row[column.prop]?.optionList"
93
+ :key="option.scoreText"
94
+ :label="option.scoreText"
95
+ :value="option"
96
+ style="height: auto"
97
+ >
98
+ <div class="select-top">{{ option.scoreText }}</div>
99
+ <div class="select-bottom">{{ option.reason }}</div>
100
+ </el-option>
101
+ </el-select>
102
+ </div>
103
+ <div v-else>
104
+ <InputNumber
105
+ :d-num="paramsObj.digits"
106
+ style="width: 100%"
107
+ :disabled="opinionPage || isDetail"
108
+ v-model="row[column.prop].value"
109
+ placeholder="请输入数字"
110
+ v-if="
111
+ row[column.prop]?.displayStyle !== 1 &&
112
+ row[column.prop]?.modifyRank === 2 &&
113
+ row[column.prop]?.value !== '' &&
114
+ row[column.prop]?.value !== null
115
+ "
116
+ ></InputNumber>
117
+ <InputNumber
118
+ :d-num="paramsObj.digits"
119
+ type="rate"
120
+ style="width: 100%"
121
+ :disabled="opinionPage || isDetail"
122
+ v-model="row[column.prop].value"
123
+ placeholder="请输入数字"
124
+ v-else-if="
125
+ row[column.prop]?.displayStyle === 1 &&
126
+ row[column.prop]?.modifyRank === 2 &&
127
+ row[column.prop]?.value !== '' &&
128
+ row[column.prop]?.value !== null
129
+ "
130
+ ></InputNumber>
131
+
132
+ <span v-else-if="column.disabled">
133
+ {{ formatScoreCell(row[column.prop]?.value) }}
134
+ </span>
135
+ <span v-else>
136
+ {{
137
+ row[column.prop]?.value || row[column.prop]?.value === 0
138
+ ? N.subFixed(row[column.prop]?.value, paramsObj.digits)
139
+ : ''
140
+ }}
141
+
142
+ {{
143
+ row[column.prop]?.displayStyle === 1 && (row[column.prop]?.value || row[column.prop]?.value === 0)
144
+ ? '%'
145
+ : ''
146
+ }}
147
+ </span>
148
+ </div>
149
+ </template>
150
+ </el-table-column>
151
+ </template>
152
+
153
+ <el-table-column
154
+ prop="modifiedReason"
155
+ label="调整理由"
156
+ align="center"
157
+ slot="modifiedReason"
158
+ v-if="paramsObj.showModifyReason === 1"
159
+ >
160
+ <template slot-scope="scope">
161
+ <el-input
162
+ v-if="
163
+ (scope.row.modifyRank == 2 && scope.row.modifiedVal !== '' && scope.row.modifiedVal !== null) ||
164
+ (scope.row.result !== '' && scope.row.modifyRank === 1)
165
+ "
166
+ type="textarea"
167
+ v-title
168
+ :disabled="opinionPage || isDetail"
169
+ :show-overflow-tooltip="true"
170
+ :maxlength="200"
171
+ show-word-limit
172
+ v-model="scope.row.modifiedReason"
173
+ placeholder="请输入具体评价依据,不超过200字"
174
+ />
175
+ </template>
176
+ </el-table-column>
177
+ </Table>
178
+ </div>
179
+ </div>
180
+ </template>
181
+
182
+ <script>
183
+ import { N } from 'n20-common-lib'
184
+ import { Descriptions, Table, InputNumber } from './ui'
185
+ import { getScoreMap } from './api'
186
+ import { formatFloat2 } from '../common'
187
+ import { formatScoreText } from './helpers'
188
+ export default {
189
+ name: 'EvaOfCreditConditions',
190
+ components: { Descriptions, Table, InputNumber },
191
+ // isPrms 授信标识 isDetail 是否是详情页 acrossShow是否横向展示
192
+ props: ['data', 'ruleForms', 'canEdit', 'nodeList', 'modelId', 'isPrms', 'isDetail', 'paramsObj'],
193
+ data() {
194
+ return {
195
+ N,
196
+ tableMsg: [],
197
+ tableData: [],
198
+ columns: [],
199
+ textarea: '',
200
+ checked1: true,
201
+ checked2: true,
202
+ value: '',
203
+ nodeListData: this.nodeList,
204
+ acrossKeysList: {}
205
+ }
206
+ },
207
+ computed: {
208
+ allresult() {
209
+ let result = 0
210
+ // this.tableData.map(item => {
211
+ // if (item.statsResultList) {
212
+ // item.statsResultList.map(statsResult => {
213
+ // if (statsResult.statCalMethod == 1 && statsResult.statShow == 1) {
214
+ // result = result + statsResult.statResult
215
+ // }
216
+ // })
217
+ // }
218
+ // })
219
+ result = this.nodeListData.result
220
+ // 总得分固定 2 位四舍五入,不读模型 digits
221
+ return formatScoreText(result)
222
+ },
223
+ opinionPage() {
224
+ return (
225
+ (location.pathname.indexOf('opinionIndex') > -1 && location.pathname.indexOf('pending') === -1) ||
226
+ location.pathname.indexOf('loanReview') > -1
227
+ )
228
+ }
229
+ },
230
+ methods: {
231
+ /** 得分列/合计:固定 2 位四舍五入 */
232
+ formatScoreCell(val) {
233
+ return formatScoreText(val)
234
+ },
235
+ // 指标值是否可录入
236
+ showInput(row) {
237
+ // 授信定量分析指标值,系统取数可编辑 手工填报:3
238
+ if (
239
+ row.sourceType == 3 &&
240
+ (location.pathname.indexOf('CreditApplication') > -1 || location.pathname.indexOf('ratingapplication') > -1)
241
+ ) {
242
+ return true
243
+ } else {
244
+ return false
245
+ }
246
+ },
247
+ save() {
248
+ // this.$emit("saveCredit")
249
+ this.$message({
250
+ message: '移至授信信息页签保存',
251
+ type: 'warning'
252
+ })
253
+ },
254
+ submit() {
255
+ // this.$emit("saveCredit")
256
+ this.$message({
257
+ message: '移至授信信息页签上报',
258
+ type: 'warning'
259
+ })
260
+ },
261
+ initColumns(list, acrossKeys) {
262
+ this.columns = [
263
+ { slotName: 'name' },
264
+ { slotName: 'weight' },
265
+ { slotName: 'fullScore' },
266
+ { slotName: 'indicatorResult' },
267
+ { slotName: 'ratioName' },
268
+ { slotName: 'result1' },
269
+ { slotName: 'result2' },
270
+ { slotName: 'modifiedReason' }
271
+ // { slotName: 'modifiedResult' }
272
+ ]
273
+ this.nodeListData = list
274
+ if (list && this.nodeListData.children) {
275
+ this.tableData = this.nodeListData.children
276
+ if (acrossKeys) {
277
+ let columsAdd = []
278
+ this.acrossKeysList = {}
279
+ acrossKeys.forEach(item => {
280
+ columsAdd.push({ slotName: item })
281
+ this.acrossKeysList[item] = { indicatorID: '', key: item, sourceType: '', value: '' }
282
+ })
283
+ this.columns.splice(3, 0, ...columsAdd)
284
+ }
285
+ this.tableData.forEach(
286
+ item =>
287
+ // indicatorResult 系统指标数
288
+ // modifiedVal 修改的指标值
289
+ // Result 旧的得分
290
+ // modifiedResult 修改得分
291
+ item?.children &&
292
+ item?.children.forEach((child, i) => {
293
+ // 如果indicatorValText有值,把indicatorValText赋值给indicatorResult
294
+ child.indicatorResult = child.indicatorValText ? child.indicatorValText : child.indicatorResult
295
+ // modifyRank===1 为可调整指标得分,如果modifiedResult为空,把result赋值给modifiedResult
296
+ // modifyRank===2 为可调整指标值,如果modifiedVal为空,把indicatorResult赋值给modifiedVal
297
+ // child.modifiedResult == '' ?
298
+ if (child.modifyRank === 1) {
299
+ child.modifiedResult = child.result || child.modifiedResult
300
+ }
301
+ child.modifiedVal = child.modifiedVal !== '' ? child.modifiedVal : child.indicatorResult
302
+ // 手工录入的时候,如果indicatorResult没值,给默认值defaultVal
303
+ if (child.sourceType === 3) {
304
+ child.indicatorResult =
305
+ !child.indicatorResult && child.indicatorResult !== 0 ? child.defaultVal : child.indicatorResult
306
+ }
307
+ if (acrossKeys) {
308
+ child = { ...child, ...this.acrossKeysList }
309
+ for (let el in this.acrossKeysList) {
310
+ let filterIt = child.acrossLabelVos.filter(it => it.key === el)
311
+ if (filterIt && filterIt.length > 0) {
312
+ item.children[i][el] = filterIt[0]
313
+ }
314
+ }
315
+ }
316
+ })
317
+ )
318
+ }
319
+ },
320
+
321
+ /**
322
+ * rankType
323
+ * 0 取指标值
324
+ * 1 分段模糊化打分
325
+ * 2 公式模糊化打分
326
+ * 3 分段模糊化公式打分
327
+ * 4 企业绩效评估标准打分
328
+ * 5 评价等级化取值
329
+ * 6 分段模糊化取值
330
+ * 7 特殊化打分
331
+ * 8 标准值打分
332
+ * 9 统计项运算
333
+ * 10 手工录入
334
+ * 11 分段取值
335
+ */
336
+ /**
337
+ * 数据行转列
338
+ */
339
+ async initColumnsRewrite(treeData) {
340
+ const statCalResult = treeData.statCalResult
341
+ this.nodeListData = treeData
342
+ const promiseAll2 = statCalResult.map(async item1 => {
343
+ let arr = []
344
+ const digui = children => {
345
+ children.forEach(item => {
346
+ if (item.isLeaf == 2) {
347
+ const obj = {}
348
+ for (let key in item) {
349
+ obj[key] = item[key]
350
+ }
351
+ if (item1.pid == item.pid) {
352
+ arr.push(obj)
353
+ }
354
+ } else {
355
+ digui(item.children)
356
+ }
357
+ })
358
+ }
359
+ digui(treeData?.children)
360
+ item1.children = arr
361
+ const columns = [{ label: '指标项名称', prop: 'name', width: '250px', align: 'center' }]
362
+ const list = []
363
+ // 所有的指标项 都是共用一个表头的
364
+ // 不管有几个指标项 表头都是一致的所以取第一个数据就可以了
365
+ item1.children &&
366
+ item1.children[0] &&
367
+ item1.children[0].children &&
368
+ item1.children[0].children.map(item => {
369
+ const obj = item1.statsResultList.find(stats => stats.name == item.statsName)
370
+ // 指标取数:任一行开启「是否展示满分值」则插入满分值列
371
+ const showFullScoreCol =
372
+ obj &&
373
+ obj.calType == 0 &&
374
+ item1.children.some(row => {
375
+ const child = (row.children || []).find(c => c.statsName === item.statsName)
376
+ return child && child.showFullScore !== 0
377
+ })
378
+ if (showFullScoreCol) {
379
+ columns.push({
380
+ label: item.statsName + '满分值',
381
+ prop: item.statsName + '满分值',
382
+ slotName: item.statsName + '满分值',
383
+ disabled: true,
384
+ isFullScore: true,
385
+ width: '200px',
386
+ align: 'center'
387
+ })
388
+ }
389
+ const label = obj.calType == 0 ? item.statsName + '指标值' : item.statsName
390
+ const columnsItem = {
391
+ label: label,
392
+ prop: label,
393
+ width: '250px',
394
+ align: 'center',
395
+ slotName: label
396
+ }
397
+ columns.push(columnsItem)
398
+ if (obj && obj.statShow == 1) {
399
+ // 得分列不能输入
400
+ if ([0].includes(obj.calType)) {
401
+ const columnsItemAdd = {
402
+ label: item.statsName + '指标得分',
403
+ prop: item.statsName + '指标得分',
404
+ slotName: item.statsName + '指标得分',
405
+ disabled: true, // 得分列不能输入 只做显示
406
+ width: '250px',
407
+ align: 'center'
408
+ }
409
+ columns.push(columnsItemAdd)
410
+ }
411
+ }
412
+ })
413
+ // 有几个指标项就有几条数据
414
+ const promiseAll1 = item1.children.map(async item2 => {
415
+ const listItem = {}
416
+ listItem.name = item2.folderName || item2.name
417
+ listItem.pid = item2.pid
418
+ const promiseAll = item2.children.map(async item => {
419
+ const obj = item1.statsResultList.find(stats => stats.name == item.statsName)
420
+ const label = obj.calType == 0 ? item.statsName + '指标值' : item.statsName
421
+ // 如果indicatorValText有值,把indicatorValText赋值给indicatorResult
422
+ item.indicatorResult = item.indicatorValText ? item.indicatorValText : item.indicatorResult
423
+ let value = ''
424
+ // 指标取数来源
425
+ switch (item.sourceType) {
426
+ // 手工填报
427
+ case 3:
428
+ value = item.indicatorResult
429
+ break
430
+ // 系统自定义
431
+ case 0:
432
+ value = {}
433
+ break
434
+ default:
435
+ // 指标项取值方式
436
+ switch (item.rankType) {
437
+ // 手工录入
438
+ case 10:
439
+ value = item.formula
440
+ break
441
+ // 统计项运算
442
+ case 9:
443
+ value = item.result
444
+ break
445
+ default:
446
+ value = item.indicatorResult
447
+ break
448
+ }
449
+ break
450
+ }
451
+ // 系统自定义 不可量化指标用
452
+ if (item.sourceType != 3 && item.itemType == 22) {
453
+ const { data } = await getScoreMap({ id: item.itemID })
454
+ item.optionList = data
455
+ const obj = item.optionList.find(item2 => item2.scoreValue == item.indicatorResult)
456
+ if (obj) {
457
+ value = obj
458
+ }
459
+ }
460
+ if ([0].includes(obj.calType) && item.showFullScore !== 0) {
461
+ const fullScore =
462
+ item.fullScore === 0 || item.fullScore ? item.fullScore : ''
463
+ listItem[item.statsName + '满分值'] = {
464
+ ...item,
465
+ value: fullScore,
466
+ result: fullScore,
467
+ sourceType: '',
468
+ displayStyle: 0,
469
+ calcState: false
470
+ }
471
+ }
472
+ if ([0].includes(obj.calType)) {
473
+ // 得分列清空 sourceType 得分列用result
474
+ listItem[item.statsName + '指标得分'] = {
475
+ ...item,
476
+ value: item.result,
477
+ sourceType: '',
478
+ displayStyle: 0,
479
+ calcState: false // 不参与计算传值
480
+ }
481
+ }
482
+ listItem[label] = { ...item, value }
483
+ return
484
+ })
485
+ await Promise.all(promiseAll)
486
+ list.push(listItem)
487
+ return
488
+ })
489
+ await Promise.all(promiseAll1)
490
+ item1.columns = columns
491
+ item1.list = list
492
+ return item1
493
+ })
494
+
495
+ const tableData = await Promise.all(promiseAll2)
496
+ this.tableData = tableData
497
+ },
498
+
499
+ /** 计算效验 */
500
+ validateFn() {
501
+ const obj = {
502
+ scoreMapList: [],
503
+ indicatorCalcList: [],
504
+ state: true
505
+ }
506
+ this.tableData.map(item => {
507
+ const { list } = item
508
+ list.map(listItem => {
509
+ Object.keys(listItem).map(key => {
510
+ switch (listItem[key]['sourceType']) {
511
+ case 3:
512
+ if (!listItem[key].value && listItem[key].value !== 0) {
513
+ obj.state = false
514
+ return
515
+ }
516
+ obj.indicatorCalcList.push({
517
+ hasInput: true,
518
+ indicatorID: listItem[key].itemID,
519
+ modifiedReason: listItem[key].modifiedReason,
520
+ scoreValue:
521
+ listItem[key].displayStyle == 1
522
+ ? formatFloat2(listItem[key].value / 100, parseInt(this.paramsObj.digits || 0) + 2)
523
+ : listItem[key].value
524
+ })
525
+ break
526
+ default:
527
+ if (
528
+ listItem[key].itemType == 22 &&
529
+ listItem[key]?.optionList?.length > 0 &&
530
+ listItem[key].calcState != false
531
+ ) {
532
+ if (!listItem[key].value?.scoreMapID) {
533
+ obj.state = false
534
+ return
535
+ }
536
+ obj.scoreMapList.push({
537
+ indicatorID: listItem[key].value?.indicatorID,
538
+ modifiedReason: listItem[key]?.modifiedReason,
539
+ scoreMapID: listItem[key].value?.scoreMapID,
540
+ scoreText: listItem[key].value?.scoreText,
541
+ scoreValue: listItem[key].value?.scoreValue
542
+ })
543
+ }
544
+
545
+ break
546
+ }
547
+ })
548
+ })
549
+ })
550
+
551
+ return obj
552
+ }
553
+ }
554
+ }
555
+ </script>
556
+
557
+ <style lang="less" scoped>
558
+ .com-page-con {
559
+ overflow: hidden;
560
+ padding: 0 8px;
561
+
562
+ .wrap {
563
+ width: 100%;
564
+ display: flex;
565
+
566
+ .wrap-item {
567
+ display: flex;
568
+ width: 25%;
569
+ height: 34px;
570
+ border: 1px solid #dfe6ee;
571
+ justify-content: flex-start;
572
+ align-items: center;
573
+ padding: 0 15px;
574
+
575
+ &:nth-child(2n + 1) {
576
+ background-color: #e5efff;
577
+ justify-content: flex-end;
578
+ }
579
+ }
580
+ }
581
+
582
+ .title {
583
+ // margin-top:20px;
584
+ height: 30px;
585
+ align-items: center;
586
+ display: flex;
587
+
588
+ .title-item {
589
+ display: flex;
590
+ justify-content: flex-start;
591
+ width: 50%;
592
+ }
593
+ }
594
+
595
+ .btn-grop {
596
+ display: flex;
597
+ background: #ffffff;
598
+ box-shadow: 0px -2px 6px 0px rgba(92, 100, 113, 0.11);
599
+ justify-content: center;
600
+ padding: 20px 0;
601
+ }
602
+ }
603
+
604
+ .select-top {
605
+ margin-top: 2px;
606
+ height: 14px;
607
+ line-height: 16px;
608
+ font-size: 14px;
609
+ }
610
+
611
+ .select-bottom {
612
+ margin-top: 1px;
613
+ min-height: 14px;
614
+ line-height: 16px;
615
+ color: #999999;
616
+ font-size: 13px;
617
+ max-width: 500px;
618
+ white-space: normal; /* 允许换行 */
619
+ word-wrap: break-word; /* 在长单词或 URL 地址内部进行换行 */
620
+ }
621
+ /deep/ .el-select .el-input__inner {
622
+ text-align: center;
623
+ }
624
+ </style>