deliverySlipPrintUtil.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <?php
  2. namespace common\components;
  3. use biz\shop\classes\ShopClass;
  4. use bizHd\order\classes\OrderGoodsClass;
  5. use bizHd\order\services\OrderService;
  6. use Yii;
  7. /**
  8. * A4 鲜花配送单云打印
  9. */
  10. class deliverySlipPrintUtil
  11. {
  12. /**
  13. * 根据零售订单 ID 打印 A4 配送单
  14. */
  15. public static function printByOrderId($orderId, $mainId = 0, array $printOptions = [])
  16. {
  17. $order = OrderService::getById($orderId);
  18. if (empty($order)) {
  19. throw new CloudPrinterApiException('订单不存在');
  20. }
  21. if ($mainId > 0) {
  22. OrderService::valid($order, $mainId);
  23. }
  24. $data = self::buildDataFromOrder($order);
  25. return self::printByData($data, $printOptions);
  26. }
  27. /**
  28. * 直接按模板数据打印
  29. */
  30. public static function printByData(array $data, array $printOptions = [])
  31. {
  32. if (!cloudPrintUtil::isEnabled()) {
  33. throw new CloudPrinterApiException('链科云打印未启用,请先在 .env 配置 LIANKENET_*');
  34. }
  35. $paper = cloudPrintPaperSpec::resolve(array_merge([
  36. 'scene' => cloudPrintPaperSpec::SCENE_DELIVERY_SLIP,
  37. ], $printOptions));
  38. $data['paper'] = $paper;
  39. $html = self::renderHtml($data);
  40. return (new cloudPrintUtil())->printHtml($html, $paper['dmPaperSize']);
  41. }
  42. /**
  43. * 组装配送单展示数据
  44. */
  45. public static function buildDataFromOrder(array $order)
  46. {
  47. $shopId = intval($order['shopId'] ?? 0);
  48. $shop = ShopClass::getById($shopId, true);
  49. $shopName = '';
  50. if (!empty($shop)) {
  51. $merchantName = $shop->merchantName ?? '';
  52. $branchName = $shop->shopName ?? '';
  53. $shopName = ($branchName === '首店' || $branchName === '') ? $merchantName : trim($merchantName . ' ' . $branchName);
  54. }
  55. if ($shopName === '') {
  56. $shopName = '花掌柜';
  57. }
  58. $reachPeriodMap = [0 => '上午', 1 => '下午', 2 => '晚上'];
  59. $reachPeriod = $reachPeriodMap[intval($order['reachPeriod'] ?? 0)] ?? '';
  60. $reachDate = trim((string)($order['reachDate'] ?? ''));
  61. if ($reachDate === '' || $reachDate === '0000-00-00') {
  62. $reachDateLabel = '立即发单';
  63. $reachDateTime = date('m月d日 H:i');
  64. } else {
  65. $reachDateLabel = '预约配送';
  66. $reachDateTime = date('m月d日', strtotime($reachDate)) . ' ' . $reachPeriod;
  67. }
  68. $bookName = $order['bookName'] ?? '';
  69. $bookMobile = $order['bookMobile'] ?? '';
  70. if (intval($order['anonymity'] ?? 0) === 1) {
  71. $bookName = '--';
  72. $bookMobile = '--';
  73. }
  74. $fullAddress = trim((string)($order['fullAddress'] ?? ''));
  75. $showAddress = trim((string)($order['showAddress'] ?? ''));
  76. if ($showAddress !== '' && strpos($fullAddress, $showAddress) === false) {
  77. $fullAddress .= '(' . $showAddress . ')';
  78. }
  79. $productName = trim((string)($order['orderName'] ?? ''));
  80. $goodsNum = max(1, intval($order['goodsNum'] ?? 1));
  81. if ($productName === '') {
  82. $productName = '鲜花';
  83. }
  84. $cover = self::resolveOrderCover($order);
  85. $distanceText = '';
  86. $distance = intval($order['sendDistance'] ?? ($order['deliveryDistance'] ?? 0));
  87. if ($distance > 0) {
  88. $distanceText = $distance >= 1000
  89. ? ('直线 ' . round($distance / 1000, 1) . '公里')
  90. : ('直线 ' . $distance . '米');
  91. }
  92. $servicePhone = trim((string)getenv('LIANKENET_SERVICE_PHONE'));
  93. if ($servicePhone === '' && !empty($shop)) {
  94. $servicePhone = trim((string)($shop->telephone ?? ''));
  95. }
  96. $sendNum = (string)($order['sendNum'] ?? '');
  97. $batchDay = str_pad((string)date('j'), 2, '0', STR_PAD_LEFT);
  98. return [
  99. 'title' => $shopName . ' 鲜花配送单',
  100. 'batchNo' => '#O' . $batchDay . ' [#' . $sendNum . ']',
  101. 'sendNum' => $sendNum,
  102. 'receiveUserName' => $order['receiveUserName'] ?? '',
  103. 'receiveMobile' => $order['receiveMobile'] ?? '',
  104. 'fullAddress' => $fullAddress,
  105. 'distanceText' => $distanceText,
  106. 'reachDateLabel' => $reachDateLabel,
  107. 'reachDateTime' => $reachDateTime,
  108. 'productName' => $productName,
  109. 'productCount' => (string)$goodsNum,
  110. 'productImage' => self::imageToDataUri($cover),
  111. 'cardInfo' => $order['cardInfo'] ?? '',
  112. 'bookName' => $bookName,
  113. 'bookMobile' => $bookMobile,
  114. 'orderSn' => $order['orderSn'] ?? '',
  115. 'servicePhone' => $servicePhone,
  116. ];
  117. }
  118. /**
  119. * 渲染 A4 HTML
  120. */
  121. public static function renderHtml(array $data)
  122. {
  123. if (empty($data['paper'])) {
  124. $data['paper'] = cloudPrintPaperSpec::resolve([
  125. 'scene' => cloudPrintPaperSpec::SCENE_DELIVERY_SLIP,
  126. ]);
  127. }
  128. $template = Yii::getAlias('@common/templates/delivery-slip-a4.php');
  129. if (!is_file($template)) {
  130. throw new CloudPrinterApiException('配送单模板不存在');
  131. }
  132. ob_start();
  133. include $template;
  134. return (string)ob_get_clean();
  135. }
  136. /**
  137. * 取订单商品封面图
  138. */
  139. protected static function resolveOrderCover(array $order)
  140. {
  141. $cover = trim((string)($order['cover'] ?? ''));
  142. if ($cover !== '') {
  143. return imgUtil::groupImg($cover) . '?x-oss-process=image/resize,m_fill,h_300,w_300';
  144. }
  145. $goodsList = OrderGoodsClass::getGoodsListById(intval($order['id'] ?? 0));
  146. if (!empty($goodsList)) {
  147. $first = $goodsList[0];
  148. $shortCover = $first['cover'] ?? '';
  149. if ($shortCover !== '') {
  150. return imgUtil::groupImg($shortCover) . '?x-oss-process=image/resize,m_fill,h_300,w_300';
  151. }
  152. }
  153. return '';
  154. }
  155. /**
  156. * 远程图片转 data URI,避免打印盒访问不了外网图
  157. */
  158. protected static function imageToDataUri($url)
  159. {
  160. $url = trim((string)$url);
  161. if ($url === '') {
  162. return '';
  163. }
  164. $binary = @file_get_contents($url);
  165. if ($binary === false || $binary === '') {
  166. return $url;
  167. }
  168. $mime = 'image/jpeg';
  169. if (function_exists('finfo_buffer')) {
  170. $finfo = finfo_open(FILEINFO_MIME_TYPE);
  171. if ($finfo) {
  172. $detected = finfo_buffer($finfo, $binary);
  173. if (!empty($detected)) {
  174. $mime = $detected;
  175. }
  176. finfo_close($finfo);
  177. }
  178. }
  179. return 'data:' . $mime . ';base64,' . base64_encode($binary);
  180. }
  181. }