(imageBuffer: Buffer)
| 109 | try { |
| 110 | // 保存图片到临时文件 |
| 111 | writeFileSync(tempFile, imageBuffer); |
| 112 | |
| 113 | // 使用zbarimg解码二维码,设置环境变量确保UTF-8编码 |
| 114 | const env = { ...process.env, LC_ALL: 'C.UTF-8', LANG: 'C.UTF-8' }; |
| 115 | const { stdout } = await execFileAsync('zbarimg', [tempFile], { |
| 116 | encoding: 'utf8', |
| 117 | env: env |
| 118 | }); |
| 119 | |
| 120 | unlinkSync(tempFile); // 清理临时文件 |
| 121 | |
| 122 | if (!stdout.trim()) { |
| 123 | return []; |
| 124 | } |
| 125 | |
| 126 | // 解析输出,格式通常是 "QR-Code:内容" |
| 127 | // 确保正确处理UTF-8编码的字符 |
| 128 | const results = stdout.trim().split('\n') |
| 129 | .map(line => { |
| 130 | const content = line.replace(/^QR-Code:/, '').trim(); |
| 131 | |
| 132 | // 检测并修复编码问题 |
| 133 | if (hasEncodingIssues(content)) { |
| 134 | // 尝试多种解码方式修复编码问题 |
| 135 | const attempts = [ |
| 136 | // 尝试从ISO-8859-1转UTF-8 (常见于Linux系统) |
| 137 | () => Buffer.from(content, 'latin1').toString('utf8'), |
| 138 | // 尝试从Windows-1252转UTF-8 |
| 139 | () => Buffer.from(content, 'binary').toString('utf8'), |
| 140 | // 尝试处理双重编码问题 |
| 141 | () => Buffer.from(Buffer.from(content, 'latin1').toString('utf8'), 'latin1').toString('utf8'), |
| 142 | // 原始内容 |
| 143 | () => content |
| 144 | ]; |
| 145 | |
| 146 | for (const attempt of attempts) { |
| 147 | try { |
| 148 | const decoded = attempt(); |
| 149 | // 检查解码结果是否合理 |
| 150 | if (!hasEncodingIssues(decoded) && decoded.length > 0) { |
| 151 | return decoded; |
| 152 | } |
| 153 | } catch { |
| 154 | continue; |
| 155 | } |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | return content; |
| 160 | }) |
| 161 | .filter(line => line.length > 0); |
| 162 | |
| 163 | return results; |
| 164 | } catch (error) { |
| 165 | // 清理临时文件 |
| 166 | if (existsSync(tempFile)) { |
| 167 | unlinkSync(tempFile); |
| 168 | } |
no test coverage detected