@nstc-business/imes 1.0.31 → 1.0.33
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 +1 -0
- package/src/components/measureCalc/MeasureQualAnalysis.vue +1 -1
- package/src/components/measureCalc/MeasureStatFlatTable.vue +1 -0
- package/src/components/measureCalc/MeasureTreeTable.vue +1 -1
- package/src/components/measureCalc/helpers.js +93 -17
- package/src/components/measureCalc/index.vue +115 -22
- package/src/index.js +1 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<vxe-table
|
|
3
3
|
border
|
|
4
4
|
ref="xTable"
|
|
5
|
-
:class="['measure-tree-table', 'level-' + level]"
|
|
5
|
+
:class="['measure-tree-table', 'v3-n20-table-pro', 'level-' + level]"
|
|
6
6
|
:row-config="{ keyField: '_rowKey' }"
|
|
7
7
|
:data="nodes"
|
|
8
8
|
:expand-config="{ lazy: false, visibleMethod: canExpand }"
|
|
@@ -154,16 +154,14 @@ export const SUB_MODEL_LABEL = '测算子模型'
|
|
|
154
154
|
/** 子模型独立测算按钮文案 */
|
|
155
155
|
export const SUB_MODEL_CALC_BTN = '子模型测算'
|
|
156
156
|
|
|
157
|
-
/**
|
|
157
|
+
/** 子模型测算结果展示(计算/统计读 digits,评价分数+等级固定2位) */
|
|
158
158
|
export function subModelResultText(row, modelWrap) {
|
|
159
159
|
if (!row) return ''
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
return ''
|
|
160
|
+
return formatDisplayModelResult(
|
|
161
|
+
{ result: row.result, resultText: row.resultText },
|
|
162
|
+
modelWrap,
|
|
163
|
+
{ modelType: row.itemType, thousands: row.showStyle === 2 }
|
|
164
|
+
)
|
|
167
165
|
}
|
|
168
166
|
|
|
169
167
|
export function isCalcModel(row) {
|
|
@@ -223,6 +221,31 @@ export function digitsCalc(row, modelWrap) {
|
|
|
223
221
|
*/
|
|
224
222
|
export const SCORE_DIGITS = 2
|
|
225
223
|
|
|
224
|
+
/**
|
|
225
|
+
* 模型结果小数位:读模型返回的 digits,缺省回退 2
|
|
226
|
+
* (计算模型用;对应后台全局计算位数配置)
|
|
227
|
+
*/
|
|
228
|
+
export function modelResultDigits(modelWrap) {
|
|
229
|
+
return modelWrap && modelWrap.digits != null ? modelWrap.digits : 2
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* 模型结果数值格式化:按模型 digits 四舍五入保留小数位(仅计算模型)
|
|
234
|
+
* @param {*} val
|
|
235
|
+
* @param {*} modelWrap
|
|
236
|
+
* @param {{ thousands?: boolean }} [options]
|
|
237
|
+
*/
|
|
238
|
+
export function formatModelResultText(val, modelWrap, options = {}) {
|
|
239
|
+
if (val === '' || val == null) return ''
|
|
240
|
+
const num = Number(val)
|
|
241
|
+
if (Number.isNaN(num)) return String(val)
|
|
242
|
+
let text = num.toFixed(modelResultDigits(modelWrap))
|
|
243
|
+
if (options.thousands) {
|
|
244
|
+
text = addThousands(text)
|
|
245
|
+
}
|
|
246
|
+
return text
|
|
247
|
+
}
|
|
248
|
+
|
|
226
249
|
/**
|
|
227
250
|
* 得分数值格式化:四舍五入,固定保留 SCORE_DIGITS 位
|
|
228
251
|
* @param {*} val
|
|
@@ -239,6 +262,61 @@ export function formatScoreText(val, options = {}) {
|
|
|
239
262
|
return text
|
|
240
263
|
}
|
|
241
264
|
|
|
265
|
+
/**
|
|
266
|
+
* 解析模型种类:顶层 type(1/2/3) 或节点 itemType(12/11/13)
|
|
267
|
+
* @returns {'eval'|'calc'|'stat'|'other'}
|
|
268
|
+
*/
|
|
269
|
+
export function resolveModelKind(type) {
|
|
270
|
+
const t = Number(type)
|
|
271
|
+
if (t === 1 || t === ITEM_TYPE.EVAL_MODEL) return 'eval'
|
|
272
|
+
if (t === 2 || t === ITEM_TYPE.CALC_MODEL) return 'calc'
|
|
273
|
+
if (t === 3 || t === ITEM_TYPE.STAT_MODEL) return 'stat'
|
|
274
|
+
return 'other'
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* 测算结果展示:
|
|
279
|
+
* - 计算/统计模型:按模型 digits(后台全局计算位数)
|
|
280
|
+
* - 评价模型:分数固定 2 位;有等级则「分数(等级)」,等级为空只显示分数
|
|
281
|
+
* @param {{ result?: *, resultText?: * }} payload
|
|
282
|
+
* @param {*} modelWrap
|
|
283
|
+
* @param {{ modelType?: number|string, thousands?: boolean }} [options]
|
|
284
|
+
*/
|
|
285
|
+
export function formatDisplayModelResult(payload, modelWrap, options = {}) {
|
|
286
|
+
const result = payload && payload.result
|
|
287
|
+
const resultText = payload && payload.resultText
|
|
288
|
+
const modelType = options.modelType != null ? options.modelType : modelWrap && modelWrap.type
|
|
289
|
+
const kind = resolveModelKind(modelType)
|
|
290
|
+
const hasScore = result !== '' && result != null
|
|
291
|
+
const grade =
|
|
292
|
+
resultText !== '' && resultText != null ? String(resultText).trim() : ''
|
|
293
|
+
|
|
294
|
+
if (kind === 'eval') {
|
|
295
|
+
if (!hasScore && !grade) return ''
|
|
296
|
+
const parts = []
|
|
297
|
+
if (hasScore) {
|
|
298
|
+
parts.push(formatScoreText(result, { thousands: options.thousands }))
|
|
299
|
+
}
|
|
300
|
+
// 等级为空不展示;「未知」等非空等级文案仍展示
|
|
301
|
+
if (grade) {
|
|
302
|
+
parts.push(`(${grade})`)
|
|
303
|
+
}
|
|
304
|
+
return parts.join('')
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const raw = hasScore ? result : grade
|
|
308
|
+
if (raw === '' || raw == null) return ''
|
|
309
|
+
const text = String(raw).trim()
|
|
310
|
+
if (!/^-?\d+(\.\d+)?$/.test(text)) {
|
|
311
|
+
return String(raw)
|
|
312
|
+
}
|
|
313
|
+
// 计算/统计模型读 digits;其他固定 2 位
|
|
314
|
+
if (kind === 'calc' || kind === 'stat') {
|
|
315
|
+
return formatModelResultText(text, modelWrap, { thousands: options.thousands })
|
|
316
|
+
}
|
|
317
|
+
return formatScoreText(text, { thousands: options.thousands })
|
|
318
|
+
}
|
|
319
|
+
|
|
242
320
|
/** 模型指标得分 / 模型指标系数数值(权重之后的 result);得分不读模型 digits */
|
|
243
321
|
export function resultByShowStyle(row, modelWrap) {
|
|
244
322
|
if (!row || (row.result !== 0 && (row.result === '' || row.result == null))) {
|
|
@@ -319,15 +397,13 @@ export function indicatorResultText(row, modelWrap) {
|
|
|
319
397
|
/** 从子模型节点解析指标值展示文案 */
|
|
320
398
|
export function resolveSubModelValueText(row, modelWrap) {
|
|
321
399
|
if (!row) return ''
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
if (
|
|
328
|
-
|
|
329
|
-
}
|
|
330
|
-
return ''
|
|
400
|
+
const modelResult = formatDisplayModelResult(
|
|
401
|
+
{ result: row.result, resultText: row.resultText },
|
|
402
|
+
modelWrap,
|
|
403
|
+
{ modelType: row.itemType, thousands: row.showStyle === 2 }
|
|
404
|
+
)
|
|
405
|
+
if (modelResult) return modelResult
|
|
406
|
+
return indicatorResultText(row, modelWrap)
|
|
331
407
|
}
|
|
332
408
|
|
|
333
409
|
/** 子模型指标值:子模型测算后展示计算结果(固化,避免父模型测算覆盖 result 后丢失) */
|
|
@@ -191,6 +191,42 @@
|
|
|
191
191
|
</div>
|
|
192
192
|
</div>
|
|
193
193
|
<calculate-detail-dialog ref="calculateDetailDialog" />
|
|
194
|
+
<el-dialog
|
|
195
|
+
title="选择打印"
|
|
196
|
+
:visible.sync="printDialogVisible"
|
|
197
|
+
width="480px"
|
|
198
|
+
append-to-body
|
|
199
|
+
@closed="onPrintDialogClosed"
|
|
200
|
+
>
|
|
201
|
+
<el-form label-width="90px">
|
|
202
|
+
<el-form-item label="打印选项" required>
|
|
203
|
+
<el-select
|
|
204
|
+
v-model="selectedTemplateName"
|
|
205
|
+
placeholder="请选择"
|
|
206
|
+
clearable
|
|
207
|
+
filterable
|
|
208
|
+
:loading="printTemplateLoading"
|
|
209
|
+
style="width: 100%"
|
|
210
|
+
>
|
|
211
|
+
<el-option
|
|
212
|
+
v-for="item in printTemplateList"
|
|
213
|
+
:key="item.ptId || item.ptNo || item.ptName"
|
|
214
|
+
:label="item.ptName"
|
|
215
|
+
:value="item.ptName"
|
|
216
|
+
/>
|
|
217
|
+
</el-select>
|
|
218
|
+
</el-form-item>
|
|
219
|
+
</el-form>
|
|
220
|
+
<div slot="footer" class="dialog-footer">
|
|
221
|
+
<el-button type="primary" size="small" :loading="printLoading" @click="confirmPrintDownload('download')">
|
|
222
|
+
下载
|
|
223
|
+
</el-button>
|
|
224
|
+
<el-button type="primary" size="small" :loading="printLoading" @click="confirmPrintDownload('print')">
|
|
225
|
+
打印
|
|
226
|
+
</el-button>
|
|
227
|
+
<el-button size="small" @click="printDialogVisible = false">取消</el-button>
|
|
228
|
+
</div>
|
|
229
|
+
</el-dialog>
|
|
194
230
|
</div>
|
|
195
231
|
</template>
|
|
196
232
|
|
|
@@ -216,6 +252,7 @@ import {
|
|
|
216
252
|
subModelResultText as formatSubModelResult,
|
|
217
253
|
saveSubModelValueText,
|
|
218
254
|
formatScoreText,
|
|
255
|
+
formatDisplayModelResult,
|
|
219
256
|
resolveCalcEchoValue,
|
|
220
257
|
shouldApplyModifiedVal
|
|
221
258
|
} from './helpers'
|
|
@@ -341,6 +378,10 @@ export default {
|
|
|
341
378
|
loading: false,
|
|
342
379
|
calcLoading: false,
|
|
343
380
|
printLoading: false,
|
|
381
|
+
printDialogVisible: false,
|
|
382
|
+
printTemplateList: [],
|
|
383
|
+
selectedTemplateName: '',
|
|
384
|
+
printTemplateLoading: false,
|
|
344
385
|
model: { type: 1, name: '', code: '', digits: 2, modelTreeVO: {} },
|
|
345
386
|
sections: [],
|
|
346
387
|
anchorTabs: [],
|
|
@@ -419,21 +460,14 @@ export default {
|
|
|
419
460
|
if (this.model.version === '' || this.model.version == null) return '--'
|
|
420
461
|
return `版本${this.model.version}`
|
|
421
462
|
},
|
|
422
|
-
/**
|
|
463
|
+
/** 测算结果:计算/统计读 digits;评价固定2位且有等级则「分数(等级)」 */
|
|
423
464
|
displayResultText() {
|
|
424
|
-
const
|
|
425
|
-
this.resultText
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
if (raw === null || raw === '') return '--'
|
|
431
|
-
const text = String(raw).trim()
|
|
432
|
-
// 纯数字得分:固定 2 位;非数字文案原样展示
|
|
433
|
-
if (/^-?\d+(\.\d+)?$/.test(text)) {
|
|
434
|
-
return formatScoreText(text)
|
|
435
|
-
}
|
|
436
|
-
return String(raw)
|
|
465
|
+
const text = formatDisplayModelResult(
|
|
466
|
+
{ result: this.calcResult, resultText: this.resultText },
|
|
467
|
+
this.model,
|
|
468
|
+
{ modelType: this.model && this.model.type }
|
|
469
|
+
)
|
|
470
|
+
return text || '--'
|
|
437
471
|
},
|
|
438
472
|
/** 评价模型展示「模型得分」,计算模型展示「模型公式」 */
|
|
439
473
|
formulaRowLabel() {
|
|
@@ -1082,6 +1116,42 @@ export default {
|
|
|
1082
1116
|
}
|
|
1083
1117
|
},
|
|
1084
1118
|
async printFn() {
|
|
1119
|
+
const logId = this.currentLogId()
|
|
1120
|
+
const modelId = this.currentModelId()
|
|
1121
|
+
if (!logId || !modelId) {
|
|
1122
|
+
this.$message.warning('请先完成测算后再打印')
|
|
1123
|
+
return
|
|
1124
|
+
}
|
|
1125
|
+
this.selectedTemplateName = ''
|
|
1126
|
+
this.printDialogVisible = true
|
|
1127
|
+
await this.loadPrintTemplates()
|
|
1128
|
+
},
|
|
1129
|
+
onPrintDialogClosed() {
|
|
1130
|
+
this.selectedTemplateName = ''
|
|
1131
|
+
},
|
|
1132
|
+
async loadPrintTemplates() {
|
|
1133
|
+
this.printTemplateLoading = true
|
|
1134
|
+
try {
|
|
1135
|
+
const ptType =
|
|
1136
|
+
this.model && this.model.type != null && this.model.type !== '' ? String(this.model.type) : undefined
|
|
1137
|
+
const res = await this.$axios.get(
|
|
1138
|
+
'/imes/print-template/list',
|
|
1139
|
+
ptType ? { ptType } : {},
|
|
1140
|
+
{ loading: false }
|
|
1141
|
+
)
|
|
1142
|
+
const list = Array.isArray(res) ? res : (res && res.data) || []
|
|
1143
|
+
this.printTemplateList = Array.isArray(list) ? list : []
|
|
1144
|
+
} catch (e) {
|
|
1145
|
+
this.printTemplateList = []
|
|
1146
|
+
} finally {
|
|
1147
|
+
this.printTemplateLoading = false
|
|
1148
|
+
}
|
|
1149
|
+
},
|
|
1150
|
+
async confirmPrintDownload(action) {
|
|
1151
|
+
if (!this.selectedTemplateName) {
|
|
1152
|
+
this.$message.warning('请选择打印选项')
|
|
1153
|
+
return
|
|
1154
|
+
}
|
|
1085
1155
|
const logId = this.currentLogId()
|
|
1086
1156
|
const modelId = this.currentModelId()
|
|
1087
1157
|
if (!logId || !modelId) {
|
|
@@ -1095,24 +1165,47 @@ export default {
|
|
|
1095
1165
|
{
|
|
1096
1166
|
...extra,
|
|
1097
1167
|
logId,
|
|
1098
|
-
modelId
|
|
1168
|
+
modelId,
|
|
1169
|
+
templateName: this.selectedTemplateName
|
|
1099
1170
|
}
|
|
1100
1171
|
])
|
|
1101
1172
|
if (res.code !== 0) {
|
|
1102
|
-
// this.$message.error(res.msg || '打印失败')
|
|
1103
1173
|
return
|
|
1104
1174
|
}
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1175
|
+
if (action === 'print') {
|
|
1176
|
+
printJS({
|
|
1177
|
+
printable: res.data,
|
|
1178
|
+
type: 'pdf',
|
|
1179
|
+
base64: true
|
|
1180
|
+
})
|
|
1181
|
+
} else {
|
|
1182
|
+
this.downloadPdfBase64(res.data)
|
|
1183
|
+
}
|
|
1184
|
+
this.printDialogVisible = false
|
|
1110
1185
|
} catch (e) {
|
|
1111
|
-
//
|
|
1186
|
+
// keep quiet consistent with previous print catch
|
|
1112
1187
|
} finally {
|
|
1113
1188
|
this.printLoading = false
|
|
1114
1189
|
}
|
|
1115
1190
|
},
|
|
1191
|
+
downloadPdfBase64(base64) {
|
|
1192
|
+
const pure = String(base64 || '').replace(/^data:application\/pdf;base64,/, '')
|
|
1193
|
+
const binary = atob(pure)
|
|
1194
|
+
const len = binary.length
|
|
1195
|
+
const bytes = new Uint8Array(len)
|
|
1196
|
+
for (let i = 0; i < len; i++) {
|
|
1197
|
+
bytes[i] = binary.charCodeAt(i)
|
|
1198
|
+
}
|
|
1199
|
+
const blob = new Blob([bytes], { type: 'application/pdf' })
|
|
1200
|
+
const url = URL.createObjectURL(blob)
|
|
1201
|
+
const a = document.createElement('a')
|
|
1202
|
+
a.href = url
|
|
1203
|
+
a.download = `${(this.model && this.model.code) || '测算结果'}.pdf`
|
|
1204
|
+
document.body.appendChild(a)
|
|
1205
|
+
a.click()
|
|
1206
|
+
document.body.removeChild(a)
|
|
1207
|
+
URL.revokeObjectURL(url)
|
|
1208
|
+
},
|
|
1116
1209
|
hasPrintObj(val) {
|
|
1117
1210
|
return val && typeof val === 'object' && Object.keys(val).length > 0
|
|
1118
1211
|
},
|