|
|
@@ -59,7 +59,9 @@ export default {
|
|
|
isPrinting: false, // 正在打印
|
|
|
printers: [],
|
|
|
currentTicket: null,
|
|
|
- currentOrder: null
|
|
|
+ currentOrder: null,
|
|
|
+ printAdvanced: false, // 当前这张票是否已推进过队列(回调与超时兜底互斥,保证只推进一次)
|
|
|
+ printAdvanceTimer: null // 打印回调未触发时的兜底推进定时器
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
@@ -111,16 +113,24 @@ export default {
|
|
|
this.smallTicketWebview.addEventListener('ipc-message', this.handlePrintSmallTicket)
|
|
|
},
|
|
|
// 推进打印队列:移除当前门票,有剩余则渲染并打印下一张
|
|
|
- nextPrintTicket () {
|
|
|
+ nextPrintTicket (reason) {
|
|
|
+ // 同一张票只允许推进一次:打印回调与超时兜底二选一,防止双推进丢票
|
|
|
+ if (this.printAdvanced) return
|
|
|
+ this.printAdvanced = true
|
|
|
+ if (this.printAdvanceTimer) {
|
|
|
+ clearTimeout(this.printAdvanceTimer)
|
|
|
+ this.printAdvanceTimer = null
|
|
|
+ }
|
|
|
this.$store.commit('PRINT_NEW')
|
|
|
const rest = this.$store.state.app.printList
|
|
|
- this.$log.warn(`[print-queue] 剩余待打印 ${rest.length} 张`)
|
|
|
+ this.$log.warn(`[print-queue] 剩余待打印 ${rest.length} 张(推进原因:${reason})`)
|
|
|
if (rest.length > 0) {
|
|
|
this.isPrinting = true
|
|
|
- // 延迟到当前渲染帧之后再切换 currentTicket,确保本次打印已发出
|
|
|
+ // 等上一张的作业离开 Chromium 打印栈后再发下一张,
|
|
|
+ // 间隔过短连发时后续作业会被打印栈丢弃(1.0.17.8 起 N 张只打 N/2 的根因)
|
|
|
setTimeout(() => {
|
|
|
this.currentTicket = rest[0]
|
|
|
- }, 50)
|
|
|
+ }, 500)
|
|
|
} else {
|
|
|
this.isPrinting = false
|
|
|
}
|
|
|
@@ -142,23 +152,30 @@ export default {
|
|
|
this.$log.error(`[print-queue] 渲染错位!期望票号:${currentTicketNo},webview 实际渲染:${renderedTicketNo}`)
|
|
|
}
|
|
|
this.$log.warn(`[print-queue] 开始打印!票号:${currentTicketNo},webview 实际渲染:${renderedTicketNo || '(未知)'},打印机:${printer}`)
|
|
|
- // 打印当前门票;打印成功回调在未连打印机时不触发,不能用来推进队列
|
|
|
+ // 打印当前门票;以打印回调推进队列,保证上一张作业完成后再发下一张(恢复 1.0.17.6 的串行节奏)
|
|
|
try {
|
|
|
+ this.printAdvanced = false
|
|
|
this.webview.print({
|
|
|
silent: true,
|
|
|
printBackground: true,
|
|
|
deviceName: printer
|
|
|
}, (data) => {
|
|
|
this.$log.warn('[print-queue] 打印成功回调')
|
|
|
+ this.nextPrintTicket('打印回调')
|
|
|
})
|
|
|
+ // 兜底:未连打印机等场景回调不触发,超时后强制推进,避免队列卡死
|
|
|
+ this.printAdvanceTimer = setTimeout(() => {
|
|
|
+ this.$log.warn('[print-queue] 打印回调超时(2.5s),兜底推进')
|
|
|
+ this.nextPrintTicket('超时兜底')
|
|
|
+ }, 2500)
|
|
|
} catch (e) {
|
|
|
this.$log.error('[print-queue] 调用打印失败', e)
|
|
|
+ // 调用失败时也要推进,否则队列永久卡死
|
|
|
+ this.nextPrintTicket('调用失败')
|
|
|
}
|
|
|
} catch (e) {
|
|
|
console.log(e)
|
|
|
}
|
|
|
- // 无论打印是否成功,都推进打印队列到下一张(webview 渲染完当前门票即到达此处)
|
|
|
- this.nextPrintTicket()
|
|
|
}
|
|
|
},
|
|
|
handlePrintSmallTicket (event) {
|