You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express中调用QZ-Tray实现LQ-310打印无响应问题求助

问题排查与解决方案

1. 异步执行顺序错误

你的代码中fs.writeFile和shell.exec都是异步操作,但未保证执行顺序——shell脚本可能在invoice.json写入完成前就执行,导致QZ-Tray读取无效数据;同时shell.exec默认异步,未等待其完成就返回响应,无法捕获执行状态。

修复方式:将shell执行逻辑放到writeFile的回调中,确保文件写入完成后再触发打印,同时捕获shell执行的输出与错误:

const printInvoice = (req, res) => {
    fs.writeFile(`src/invoice/invoice.json`, JSON.stringify(req.body), (err) => {
        if (err) {
            console.error('文件写入失败:', err);
            return res.status(500).json({ error: '文件写入失败' });
        }

        const shell = require('shelljs');
        const path = require('path');
        // 使用绝对路径避免工作目录问题
        const scriptPath = path.resolve(__dirname, 'src/invoice/qz-tray.sh');
        
        shell.echo('Running qz-tray');
        // 捕获shell执行的所有输出
        const { code, stdout, stderr } = shell.exec(`bash ${scriptPath}`, { silent: false });
        
        console.log('Shell执行输出:', stdout);
        console.error('Shell执行错误:', stderr);
        console.log('Shell退出码:', code);

        fs.readFile(`src/invoice/invoice.json`, (err, data) => {
            if (err) {
                console.error('文件读取失败:', err);
                return res.status(500).json({ error: '文件读取失败' });
            }
            res.json(JSON.parse(data));
        });
    });
}

2. 相对路径失效

bash src/invoice/qz-tray.sh使用相对路径,当Express应用的工作目录不是项目根目录时,会找不到脚本。必须使用绝对路径定位脚本文件,如上例中的path.resolve方式。

同时确保脚本有执行权限:

chmod +x src/invoice/qz-tray.sh

3. QZ-Tray的运行逻辑误区

QZ-Tray是客户端工具,依赖浏览器环境与本地QZ-Tray服务的连接。后端直接通过shell脚本调用QZ-Tray相关代码,可能缺少必要的上下文(比如未建立与QZ-Tray服务的连接、无浏览器端的授权)。

正确流程应为:

  • 后端接收请求,生成并存储打印数据(如invoice.json)
  • 前端页面请求后端获取打印数据,然后通过QZ-Tray的前端JS API触发打印

若必须在后端触发,需确保脚本中正确实现了与QZ-Tray本地服务的连接逻辑,且当前运行Express的用户有权限访问QZ-Tray的默认端口(2112)。

4. 脚本执行日志缺失

在qz-tray.sh中添加日志输出,可直接排查脚本是否执行、执行到哪一步:

#!/bin/bash
# 添加日志到临时文件
echo "[$(date)] 脚本开始执行" >> /tmp/qz-tray-debug.log
# 你的原有打印逻辑
# ...
echo "[$(date)] 脚本执行结束,退出码: $?" >> /tmp/qz-tray-debug.log

之后查看日志文件:

cat /tmp/qz-tray-debug.log

5. 错误处理不规范

异步回调中直接throw err会导致Express无法捕获错误,进而导致请求挂起无响应。必须通过res.status(500)返回错误响应,如上述代码中的处理方式。


内容的提问来源于stack exchange,提问作者Rusydy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:40:28