@nstc-business/imes 1.1.11 → 1.1.12
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
|
@@ -1209,42 +1209,70 @@ export default {
|
|
|
1209
1209
|
},
|
|
1210
1210
|
/**
|
|
1211
1211
|
* 解析打印/下载文件名(不含 .pdf)
|
|
1212
|
-
* 时间:2026-10-29
|
|
1212
|
+
* 时间:2026-10-29 18:30:29
|
|
1213
1213
|
* 人员:AI && 徐红飞
|
|
1214
1214
|
* 入参:无
|
|
1215
|
-
*
|
|
1216
|
-
* 方法内容:优先 downloadFileName,否则 model.code
|
|
1215
|
+
* 出参:文件名基名(已清洗非法字符)
|
|
1216
|
+
* 方法内容:优先 downloadFileName,否则 model.code;统一清洗 \/:*?"<>| 供下载与打印共用
|
|
1217
1217
|
*/
|
|
1218
1218
|
resolvePrintFileBaseName() {
|
|
1219
1219
|
const raw = this.downloadFileName || (this.model && this.model.code) || '测算结果'
|
|
1220
|
-
return String(raw)
|
|
1220
|
+
return String(raw)
|
|
1221
|
+
.replace(/\.pdf$/i, '')
|
|
1222
|
+
.replace(/[\\/:*?"<>|]/g, '_')
|
|
1223
|
+
.trim() || '测算结果'
|
|
1221
1224
|
},
|
|
1222
1225
|
/**
|
|
1223
1226
|
* 带文件名打印 PDF(base64)
|
|
1224
|
-
* 时间:2026-10-29 18:
|
|
1227
|
+
* 时间:2026-10-29 18:30:29
|
|
1225
1228
|
* 人员:AI && 徐红飞
|
|
1226
1229
|
* 入参:base64 - PDF 内容;fileBaseName - 另存为预填名(不含 .pdf)
|
|
1227
1230
|
* 出参:无
|
|
1228
|
-
*
|
|
1231
|
+
* 方法内容:HTML iframe+title+embed 打印;等 embed load 后再 print;afterprint/长兜底再 cleanup,避免另存为未完成就 revoke
|
|
1229
1232
|
*/
|
|
1230
1233
|
printPdfWithFileName(base64, fileBaseName) {
|
|
1231
|
-
const title = String(fileBaseName || '测算结果').replace(/[\\/:*?"<>|]/g, '_')
|
|
1234
|
+
const title = String(fileBaseName || '测算结果').replace(/[\\/:*?"<>|]/g, '_').trim() || '测算结果'
|
|
1232
1235
|
const pure = String(base64 || '').replace(/^data:application\/pdf;base64,/, '')
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
bytes
|
|
1236
|
+
let bytes
|
|
1237
|
+
try {
|
|
1238
|
+
const binary = atob(pure)
|
|
1239
|
+
const len = binary.length
|
|
1240
|
+
bytes = new Uint8Array(len)
|
|
1241
|
+
for (let i = 0; i < len; i++) {
|
|
1242
|
+
bytes[i] = binary.charCodeAt(i)
|
|
1243
|
+
}
|
|
1244
|
+
} catch (e) {
|
|
1245
|
+
printJS({
|
|
1246
|
+
printable: pure,
|
|
1247
|
+
type: 'pdf',
|
|
1248
|
+
base64: true,
|
|
1249
|
+
documentTitle: title
|
|
1250
|
+
})
|
|
1251
|
+
return
|
|
1238
1252
|
}
|
|
1239
1253
|
const blob = new Blob([bytes], { type: 'application/pdf' })
|
|
1240
1254
|
const pdfUrl = URL.createObjectURL(blob)
|
|
1241
1255
|
const iframe = document.createElement('iframe')
|
|
1256
|
+
// 非零屏外尺寸:部分 Edge 对 0x0 iframe 打印/另存为不稳定
|
|
1242
1257
|
iframe.setAttribute(
|
|
1243
1258
|
'style',
|
|
1244
|
-
'position:fixed;
|
|
1259
|
+
'position:fixed;left:-9999px;top:0;width:800px;height:600px;border:0;opacity:0;pointer-events:none'
|
|
1245
1260
|
)
|
|
1246
1261
|
document.body.appendChild(iframe)
|
|
1247
1262
|
const frameWin = iframe.contentWindow
|
|
1263
|
+
if (!frameWin) {
|
|
1264
|
+
URL.revokeObjectURL(pdfUrl)
|
|
1265
|
+
if (iframe.parentNode) {
|
|
1266
|
+
iframe.parentNode.removeChild(iframe)
|
|
1267
|
+
}
|
|
1268
|
+
printJS({
|
|
1269
|
+
printable: pure,
|
|
1270
|
+
type: 'pdf',
|
|
1271
|
+
base64: true,
|
|
1272
|
+
documentTitle: title
|
|
1273
|
+
})
|
|
1274
|
+
return
|
|
1275
|
+
}
|
|
1248
1276
|
const frameDoc = frameWin.document
|
|
1249
1277
|
const safeTitle = title
|
|
1250
1278
|
.replace(/&/g, '&')
|
|
@@ -1254,10 +1282,21 @@ export default {
|
|
|
1254
1282
|
frameDoc.open()
|
|
1255
1283
|
frameDoc.write(
|
|
1256
1284
|
`<!DOCTYPE html><html><head><meta charset="utf-8"><title>${safeTitle}</title></head>` +
|
|
1257
|
-
`<body style="margin:0"><embed src="${pdfUrl}" type="application/pdf" width="100%" height="100%" /></body></html>`
|
|
1285
|
+
`<body style="margin:0"><embed id="pdfEmbed" src="${pdfUrl}" type="application/pdf" width="100%" height="100%" /></body></html>`
|
|
1258
1286
|
)
|
|
1259
1287
|
frameDoc.close()
|
|
1288
|
+
|
|
1289
|
+
let cleaned = false
|
|
1260
1290
|
const cleanup = () => {
|
|
1291
|
+
if (cleaned) {
|
|
1292
|
+
return
|
|
1293
|
+
}
|
|
1294
|
+
cleaned = true
|
|
1295
|
+
try {
|
|
1296
|
+
frameWin.removeEventListener('afterprint', onAfterPrint)
|
|
1297
|
+
} catch (e) {
|
|
1298
|
+
/* ignore */
|
|
1299
|
+
}
|
|
1261
1300
|
try {
|
|
1262
1301
|
if (iframe.parentNode) {
|
|
1263
1302
|
iframe.parentNode.removeChild(iframe)
|
|
@@ -1267,23 +1306,42 @@ export default {
|
|
|
1267
1306
|
}
|
|
1268
1307
|
URL.revokeObjectURL(pdfUrl)
|
|
1269
1308
|
}
|
|
1309
|
+
const onAfterPrint = () => {
|
|
1310
|
+
cleanup()
|
|
1311
|
+
}
|
|
1270
1312
|
const doPrint = () => {
|
|
1271
1313
|
try {
|
|
1314
|
+
frameWin.addEventListener('afterprint', onAfterPrint)
|
|
1272
1315
|
frameWin.focus()
|
|
1273
1316
|
frameWin.print()
|
|
1274
1317
|
} catch (e) {
|
|
1275
|
-
// 回退 printJS(可能仍无文件名,但保证能打)
|
|
1276
1318
|
printJS({
|
|
1277
1319
|
printable: pure,
|
|
1278
1320
|
type: 'pdf',
|
|
1279
1321
|
base64: true,
|
|
1280
1322
|
documentTitle: title
|
|
1281
1323
|
})
|
|
1324
|
+
cleanup()
|
|
1325
|
+
return
|
|
1282
1326
|
}
|
|
1283
|
-
|
|
1327
|
+
// 另存为对话框可能远超数秒;afterprint 优先,60s 兜底防泄漏
|
|
1328
|
+
setTimeout(cleanup, 60000)
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
const embed = frameDoc.getElementById('pdfEmbed')
|
|
1332
|
+
let printed = false
|
|
1333
|
+
const tryPrint = () => {
|
|
1334
|
+
if (printed) {
|
|
1335
|
+
return
|
|
1336
|
+
}
|
|
1337
|
+
printed = true
|
|
1338
|
+
doPrint()
|
|
1339
|
+
}
|
|
1340
|
+
if (embed) {
|
|
1341
|
+
embed.addEventListener('load', tryPrint)
|
|
1284
1342
|
}
|
|
1285
|
-
// embed
|
|
1286
|
-
setTimeout(
|
|
1343
|
+
// embed load 在部分浏览器不可靠,最长等 3s 再打
|
|
1344
|
+
setTimeout(tryPrint, 3000)
|
|
1287
1345
|
},
|
|
1288
1346
|
downloadPdfBase64(base64) {
|
|
1289
1347
|
const pure = String(base64 || '').replace(/^data:application\/pdf;base64,/, '')
|