桌面端原材料入场记录完善

This commit is contained in:
2026-07-31 14:27:46 +08:00
parent 67f3acfd43
commit ef28b93909
13 changed files with 531 additions and 75 deletions

View File

@@ -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:

View File

@@ -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

View File

@@ -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 分钟)。
---