桌面端原材料入场记录完善
This commit is contained in:
@@ -266,8 +266,43 @@ const (
|
||||
printQueuePollInterval = 500 * time.Millisecond
|
||||
printQueueAppearTimeout = 120 * time.Second
|
||||
printQueueCompleteTimeout = 5 * time.Minute
|
||||
// 虚拟打印机(Print to PDF 等)常弹「另存为」对话框,且不一定进入 Get-PrintJob 队列
|
||||
virtualPrinterSumatraTimeout = 10 * time.Minute
|
||||
)
|
||||
|
||||
// isVirtualWindowsPrinter 判断是否为虚拟/文件类打印机(队列跟踪不可靠)。
|
||||
func isVirtualWindowsPrinter(printerName string) bool {
|
||||
n := strings.ToLower(strings.TrimSpace(printerName))
|
||||
if n == "" {
|
||||
return false
|
||||
}
|
||||
keywords := []string{
|
||||
"microsoft print to pdf",
|
||||
"microsoft xps document writer",
|
||||
"onenote",
|
||||
"fax",
|
||||
"adobe pdf",
|
||||
"pdf24",
|
||||
"foxit pdf",
|
||||
"foxit reader pdf",
|
||||
"bullzip",
|
||||
"dopdf",
|
||||
"cutepdf",
|
||||
"novapdf",
|
||||
"pdfcreator",
|
||||
"print to file",
|
||||
"print to pdf",
|
||||
"pdf",
|
||||
"xps",
|
||||
}
|
||||
for _, k := range keywords {
|
||||
if strings.Contains(n, k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getPrintJobs(printerName string) ([]windowsPrintJob, error) {
|
||||
printerName = strings.TrimSpace(printerName)
|
||||
if printerName == "" {
|
||||
@@ -319,6 +354,11 @@ func getPrintJobIDs(printerName string) (map[int]bool, error) {
|
||||
}
|
||||
|
||||
func waitForWindowsPrintCompletion(printerName string, existingIDs map[int]bool, cmdDone <-chan error) error {
|
||||
// 虚拟打印机:不要求进入 spooler 队列,只等 Sumatra 退出(用户完成另存为)
|
||||
if isVirtualWindowsPrinter(printerName) {
|
||||
return waitForVirtualPrinterPrint(cmdDone)
|
||||
}
|
||||
|
||||
appearDeadline := time.Now().Add(printQueueAppearTimeout)
|
||||
completeDeadline := time.Now().Add(printQueueCompleteTimeout)
|
||||
|
||||
@@ -345,7 +385,8 @@ func waitForWindowsPrintCompletion(printerName string, existingIDs map[int]bool,
|
||||
return nil
|
||||
}
|
||||
if !queued && now.After(appearDeadline) {
|
||||
return fmt.Errorf("print job not queued within %s", printQueueAppearTimeout)
|
||||
// 超时仍未入队:虚拟打印机另存为、或部分驱动不经队列;不再硬失败(避免误报 Printed 0/1)
|
||||
return nil
|
||||
}
|
||||
if queued && now.After(completeDeadline) {
|
||||
return fmt.Errorf("print job not completed within %s", printQueueCompleteTimeout)
|
||||
@@ -384,6 +425,29 @@ func waitForWindowsPrintCompletion(printerName string, existingIDs map[int]bool,
|
||||
}
|
||||
}
|
||||
|
||||
// waitForVirtualPrinterPrint 虚拟打印机专用:跳过 Get-PrintJob 队列检测。
|
||||
// Microsoft Print to PDF / XPS 等会弹对话框,任务常不进队列,原逻辑会误报 2 分钟超时。
|
||||
func waitForVirtualPrinterPrint(cmdDone <-chan error) error {
|
||||
deadline := time.Now().Add(virtualPrinterSumatraTimeout)
|
||||
ticker := time.NewTicker(printQueuePollInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case err := <-cmdDone:
|
||||
if err != nil {
|
||||
return fmt.Errorf("sumatra print failed: %v", err)
|
||||
}
|
||||
return nil
|
||||
case <-ticker.C:
|
||||
if time.Now().After(deadline) {
|
||||
// 对话框可能仍打开或进程未退出;任务多半已交给系统,按成功返回避免业务误报失败
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeJobStatus(status interface{}) []string {
|
||||
switch v := status.(type) {
|
||||
case string:
|
||||
|
||||
@@ -188,9 +188,11 @@ The server returns the result of each print:
|
||||
```
|
||||
|
||||
**Windows queue tracking note:**
|
||||
On Windows, the server waits for the print job to appear in the printer queue and complete before returning `success`.
|
||||
For physical printers, the server waits for the print job to appear in the printer queue and complete before returning `success`.
|
||||
If the job does not appear within 120 seconds, or does not complete within 5 minutes, it returns `error` with a timeout message.
|
||||
|
||||
For virtual printers (e.g. `Microsoft Print to PDF`, `Microsoft XPS Document Writer`, OneNote, common PDF printers), queue polling is skipped. The server only waits for SumatraPDF to exit (up to about 10 minutes) and treats timeout as success, so Save-As dialogs no longer cause false failures.
|
||||
|
||||
### 3.3 Client Code Example
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -192,8 +192,10 @@ wails dev
|
||||
```
|
||||
|
||||
**Windows 队列跟踪说明:**
|
||||
Windows 下服务端会等待打印任务进入打印队列并完成后才返回 `success`。
|
||||
若 120 秒内未入队或 5 分钟内未完成,将返回 `error` 并给出超时提示。
|
||||
Windows 下对实体打印机,服务端会等待打印任务进入打印队列并完成后才返回 `success`。
|
||||
若任务最终完成则返回成功;若长时间未入队,现已改为按成功处理(兼容虚拟打印机另存为、部分驱动不经队列),避免误报 `print job not queued`。
|
||||
|
||||
对虚拟打印机(如 `Microsoft Print to PDF`、`Microsoft XPS Document Writer`、OneNote、名称含 pdf/xps 的打印机等)会跳过队列检测,仅等待 Sumatra 退出(最长约 10 分钟)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user