feieContentToText($content);
if ($plainText === '') {
return false;
}
$chunks = $this->splitContent($plainText, 4500);
foreach ($chunks as $chunk) {
$this->printTextChunk($chunk, $shop, $orderSn);
}
return true;
}
/**
* 打印标签内容(链科走文本任务,飞鹅标签指令无法直接复用)
*/
public function printLabelMsg($content)
{
$plainText = $this->feieContentToText($content);
if ($plainText === '') {
return false;
}
return $this->printTextChunk($plainText);
}
/**
* 直接打印本地文件
*/
public function printFile($filePath, $optionalArray = [], $paperSize = null)
{
$client = self::createClient();
$printer = $this->resolvePrinterConfig($client);
$paperSize = $paperSize ?? intval(getenv('LIANKENET_PAPER_SIZE') ?: 9);
return $client->addJobByPath(
$printer['port'],
$printer['model'],
$paperSize,
$filePath,
$optionalArray
);
}
/**
* 打印 HTML 页面(A4 配送单等排版页面)
*/
public function printHtml($html, $paperSize = null, $optionalArray = [])
{
$html = trim((string)$html);
if ($html === '') {
return false;
}
$tempFile = $this->createTempHtmlFile($html);
try {
return $this->printFile($tempFile, $optionalArray, $paperSize);
} finally {
if (is_file($tempFile)) {
@unlink($tempFile);
}
}
}
/**
* 生成可打印 HTML 临时文件
*/
protected function createTempHtmlFile($html)
{
$tempFile = tempnam(sys_get_temp_dir(), 'lk_print_');
if ($tempFile === false) {
throw new CloudPrinterApiException('无法创建临时打印文件');
}
$target = $tempFile . '.html';
@unlink($tempFile);
file_put_contents($target, $html);
return $target;
}
/**
* 飞鹅排版标签转纯文本
*/
protected function feieContentToText($content)
{
$text = str_ireplace(['
', '
', '
', '
'], "\n", (string)$content);
$text = preg_replace('/<\/?CB>/i', '', $text);
$text = preg_replace('/<\/?B>/i', '', $text);
$text = preg_replace('/<\/?C>/i', '', $text);
$text = preg_replace('/.*?<\/QR>/is', '', $text);
$text = preg_replace('/<[^>]+>/', '', $text);
$text = str_replace(["\r\n", "\r"], "\n", $text);
return trim($text);
}
/**
* 长内容分段,避免单文件过大
*/
protected function splitContent($text, $maxLength = 4500)
{
if (strlen($text) <= $maxLength) {
return [$text];
}
$lines = explode("\n", $text);
$chunks = [];
$current = '';
foreach ($lines as $line) {
$candidate = $current === '' ? $line : $current . "\n" . $line;
if (strlen($candidate) > $maxLength) {
if ($current !== '') {
$chunks[] = $current;
}
$current = $line;
} else {
$current = $candidate;
}
}
if ($current !== '') {
$chunks[] = $current;
}
return $chunks;
}
/**
* 提交一段文本为打印任务
*/
protected function printTextChunk($text, $shop = null, $orderSn = '')
{
$tempFile = $this->createTempTextFile($text);
try {
$client = self::createClient();
$printer = $this->resolvePrinterConfig($client);
$paperSize = intval(getenv('LIANKENET_PAPER_SIZE') ?: 9);
$client->addJobByPath(
$printer['port'],
$printer['model'],
$paperSize,
$tempFile,
$this->buildOptionalParams()
);
} catch (\Throwable $e) {
Yii::error('链科云打印失败: ' . $e->getMessage(), __METHOD__);
$shopName = '';
if (is_object($shop)) {
$shopName = ($shop->merchantName ?? '') . ($shop->shopName ?? '');
}
noticeUtil::push(
trim($shopName . ' 链科云打印未成功,订单号:' . $orderSn . ',原因:' . $e->getMessage()),
'15280215347'
);
return false;
} finally {
if (is_file($tempFile)) {
@unlink($tempFile);
}
}
return true;
}
/**
* 生成 UTF-8 BOM 文本临时文件,便于 Windows 打印盒识别中文
*/
protected function createTempTextFile($text)
{
$tempFile = tempnam(sys_get_temp_dir(), 'lk_print_');
if ($tempFile === false) {
throw new CloudPrinterApiException('无法创建临时打印文件');
}
$target = $tempFile . '.txt';
@unlink($tempFile);
file_put_contents($target, "\xEF\xBB\xBF" . $text);
return $target;
}
/**
* 解析打印机 USB 口与驱动名:优先 .env,否则取列表首台
*/
protected function resolvePrinterConfig(CloudPrinter $client)
{
if (is_array(self::$printerConfig)) {
return self::$printerConfig;
}
$port = trim((string)getenv('LIANKENET_DEVICE_PORT'));
$model = trim((string)getenv('LIANKENET_PRINTER_MODEL'));
if ($port !== '' && $model !== '') {
self::$printerConfig = ['port' => $port, 'model' => $model];
return self::$printerConfig;
}
$list = $client->getPrinterList();
if (empty($list)) {
throw new CloudPrinterApiException('链科设备下没有可用打印机');
}
$printer = $list[0];
self::$printerConfig = [
'port' => $printer->port ?? '',
'model' => $printer->driver_name ?? '',
];
if (self::$printerConfig['port'] === '' || self::$printerConfig['model'] === '') {
throw new CloudPrinterApiException('链科打印机信息不完整');
}
return self::$printerConfig;
}
/**
* 可选打印参数(份数、颜色、方向等,按 v3 文档扩展)
*/
protected function buildOptionalParams()
{
$params = [];
$copies = intval(getenv('LIANKENET_COPIES') ?: 1);
if ($copies > 1) {
$params['dmCopies'] = $copies;
}
return $params;
}
}