XpYunService.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <?php
  2. namespace services\extend\printer;
  3. use common\components\Service;
  4. use common\helpers\StringHelper;
  5. use common\models\extend\printer\XpYun;
  6. use linslin\yii2\curl\Curl;
  7. use Yii;
  8. use yii\helpers\Json;
  9. use yii\web\UnprocessableEntityHttpException;
  10. use function services\extend\iconv;
  11. use function services\extend\mb_strlen;
  12. use function services\extend\mb_strwidth;
  13. use function services\extend\mb_substr;
  14. /**
  15. * 芯烨云打印机
  16. *
  17. * Class XpYunService
  18. * @package services\extend
  19. * @author jianyan74 <751393839@qq.com>
  20. */
  21. class XpYunService extends Service
  22. {
  23. const URL = 'https://open.xpyun.net/api/openapi/'; //接口IP或域名
  24. public $terminal_number;
  25. public $app_id;
  26. public $app_secret_key;
  27. public $print_num = 1;
  28. /**
  29. * @var string[]
  30. */
  31. protected $errorInfo = [
  32. 0 => '成功',
  33. -1 => '请求头错误',
  34. -2 => '参数不合法',
  35. -3 => '参数签名失败',
  36. -4 => '用户未注册',
  37. 1001 => '打印机编号和用户不匹配',
  38. 1002 => '打印机未注册',
  39. 1003 => '打印机不在线',
  40. 1004 => '添加订单失败',
  41. 1005 => '未找到订单信息',
  42. 1006 => '订单日期格式或大小不正确',
  43. 1007 => '打印内容不能超过12K',
  44. 1008 => '用户修改打印机记录失败',
  45. 1009 => '用户添加打印机时,打印机编号或名称不能为空',
  46. 1010 => '打印机设备编号无效',
  47. 1011 => '打印机已存在,若当前开放平台无法查询到打印机信息,请联系售后技术支持人员核实',
  48. 1012 => '添加打印设备失败,请稍后再试或联系售后技术支持人员',
  49. ];
  50. /**
  51. * @param XpYun $config
  52. */
  53. public function initConfig(XpYun $config)
  54. {
  55. $this->app_id = $config->app_id;
  56. $this->app_secret_key = $config->app_secret_key;
  57. $this->terminal_number = $config->terminal_number;
  58. $this->print_num = $config->print_num;
  59. parent::init();
  60. }
  61. /**
  62. * @param $content
  63. * @param int $times
  64. * @param XpYun|array $config
  65. */
  66. public function print($content, $config = [])
  67. {
  68. if (!empty($config)) {
  69. $this->initConfig($config);
  70. }
  71. // 格式化内容
  72. $content = $this->formattedContent($content);
  73. $time = time(); // 请求时间
  74. $jsonStr = [
  75. 'user' => $this->app_id,
  76. 'timestamp' => $time,
  77. 'sign' => $this->signature($time),
  78. 'debug' => '1',
  79. 'sn' => $this->terminal_number,
  80. 'content' => $content,
  81. 'mode' => '1', // 值为 1 不检查打印机是否在线,直接生成打印订单,并返回打印订单号。如果打印机不在线,订单将缓存在打印队列中,打印机正常在线时会自动打印
  82. 'copies' => $this->print_num, // 打印次数
  83. 'money' => $content['payMoney'] ?? 0
  84. ];
  85. $jsonStr = Json::encode($jsonStr);
  86. $curl = new Curl();
  87. $result = $curl->setHeaders([
  88. 'Content-Type' => 'application/json;charset=UTF-8',
  89. 'Content-Length: ' . strlen($jsonStr)
  90. ])->setRawPostData($jsonStr)->post(self::URL . 'xprinter/print');
  91. $result = Json::decode($result);
  92. if ($result['code'] != 0) {
  93. if (isset($this->errorInfo[$result['code']])) {
  94. throw new UnprocessableEntityHttpException($this->errorInfo[$result['code']]);
  95. }
  96. throw new UnprocessableEntityHttpException($result['msg']);
  97. }
  98. return $result['data'];
  99. }
  100. /**
  101. * @param $data
  102. * @return string
  103. * @throws \yii\base\InvalidConfigException
  104. */
  105. protected function formattedContent($data)
  106. {
  107. if (!is_array($data)) {
  108. return $data;
  109. }
  110. $content = "<BOLD><C>****** {$data['title']} ******<BR></C></BOLD>" . "<BR>";
  111. $content .= str_repeat('.', 32) . "<BR>";
  112. $content .= "<BOLD><C>---{$data['payType']}---<BR></C></BOLD>" . "<BR>";
  113. // $content .= "<C>{$data['merchantTitle']}</C>";
  114. $content .= "打印时间:" . Yii::$app->formatter->asDatetime(time()) . "<BR>";
  115. $content .= "下单时间:" . $data['orderTime'] . "<BR>";
  116. $content .= str_repeat('*', 13) . " 商品 " . str_repeat("*", 13) . "<BR>";
  117. $content .= $this->composing($data['products']);
  118. $content .= "商品总价:¥{$data['productOriginalMoney']}<BR>";
  119. foreach ($data['marketingDetails'] as $marketingDetail) {
  120. $content .= "{$marketingDetail['marketing_name']}:-¥{$marketingDetail['discount_money']}<BR>";
  121. }
  122. $data['pointMoney'] > 0 && $content .= "积分抵扣:-¥{$data['pointMoney']}<BR>";
  123. $data['taxMoney'] > 0 && $content .= "发票税额:-¥{$data['taxMoney']}<BR>";
  124. $content .= "配送费:¥{$data['shippingMoney']}<BR>";
  125. $content .= "应付金额:¥{$data['payMoney']}<BR>";
  126. $content .= str_repeat('.', 32) . "<BR>";
  127. $content .= "昵称: " . $data['nickname'] . "<BR>";
  128. isset($data['receiverName']) && $content .= "客户: " . $data['receiverName'] . "<BR>";
  129. isset($data['receiverMobile']) && $content .= "电话: " . StringHelper::hideStr($data['receiverMobile'], 3) . "<BR>";
  130. isset($data['receiverAddress']) && $content .= "地址: " . $data['receiverRegionName'] . $data['receiverAddress'] . "<BR>";
  131. isset($data['buyerMessage']) && $content .= "备注: " . !empty($data['buyerMessage']) ? $data['buyerMessage'] : '无' . "<BR>";
  132. if (!empty($data['qr'])) {
  133. $content .= str_repeat('.', 32) . "<BR>";
  134. $content .= "<C>二维码<BR></C>";
  135. $content .= "<C><QR>{$data['qr']}</QR></C>";
  136. } else {
  137. $content .= str_repeat('.', 32) . "<BR>";
  138. $content .= "<C>二维码<BR></C>";
  139. $content .= "<C><QR>{$data['orderSn']}</QR></C>";
  140. }
  141. $content .= str_repeat('.', 32) . "<BR>";
  142. $content .= "<C>订单号</C>";
  143. $content .= "<C><BARCODE>{$data['orderSn']}</BARCODE></C>" . "<BR>";
  144. $content .= "<BOLD><C>****** 完 ******<BR></C></BOLD>" . "<BR>";
  145. return $content;
  146. }
  147. /**
  148. *
  149. * @param $products
  150. * @param int $A 名称
  151. * @param int $B 单价
  152. * @param int $C 数量
  153. * @param int $D 金额
  154. * @return string
  155. */
  156. protected function composing($products, $A = 14, $B = 6, $C = 3, $D = 6)
  157. {
  158. $orderInfo = '商品名称      数量 金额<BR>';
  159. $orderInfo .= '--------------------------------<BR>';
  160. foreach ($products as $k5 => $v5) {
  161. $name = $v5['title'];
  162. // $price = $v5['price'];
  163. $price = '';
  164. $num = $v5['num'];
  165. $prices = $v5['price'];
  166. $kw3 = '';
  167. $kw1 = '';
  168. $kw2 = '';
  169. $kw4 = '';
  170. $str = $name;
  171. $blankNum = $A;//名称控制为14个字节
  172. $lan = mb_strlen($str, 'utf-8');
  173. $m = 0;
  174. $j = 1;
  175. $blankNum++;
  176. $result = array();
  177. if (strlen($price) < $B) {
  178. $k1 = $B - strlen($price);
  179. for ($q = 0; $q < $k1; $q++) {
  180. $kw1 .= ' ';
  181. }
  182. $price = $price . $kw1;
  183. }
  184. if (strlen($num) < $C) {
  185. $k2 = $C - strlen($num);
  186. for ($q = 0; $q < $k2; $q++) {
  187. $kw2 .= ' ';
  188. }
  189. $num = $num . $kw2;
  190. }
  191. if (strlen($prices) < $D) {
  192. $k3 = $D - strlen($prices);
  193. for ($q = 0; $q < $k3; $q++) {
  194. $kw4 .= ' ';
  195. }
  196. $prices = $prices . $kw4;
  197. }
  198. for ($i = 0; $i < $lan; $i++) {
  199. $new = mb_substr($str, $m, $j, 'utf-8');
  200. $j++;
  201. if (mb_strwidth($new, 'utf-8') < $blankNum) {
  202. if ($m + $j > $lan) {
  203. $m = $m + $j;
  204. $tail = $new;
  205. $lenght = iconv("UTF-8", "GBK//IGNORE", $new);
  206. $k = $A - strlen($lenght);
  207. for ($q = 0; $q < $k; $q++) {
  208. $kw3 .= ' ';
  209. }
  210. if ($m == $j) {
  211. $tail .= $kw3 . ' ' . $price . ' ' . $num . ' ' . $prices;
  212. } else {
  213. $tail .= $kw3 . '<BR>';
  214. }
  215. break;
  216. } else {
  217. $next_new = mb_substr($str, $m, $j, 'utf-8');
  218. if (mb_strwidth($next_new, 'utf-8') < $blankNum) {
  219. continue;
  220. } else {
  221. $m = $i + 1;
  222. $result[] = $new;
  223. $j = 1;
  224. }
  225. }
  226. }
  227. }
  228. $head = '';
  229. foreach ($result as $key => $value) {
  230. if ($key < 1) {
  231. $v_lenght = iconv("UTF-8", "GBK//IGNORE", $value);
  232. $v_lenght = strlen($v_lenght);
  233. if ($v_lenght == 13) {
  234. $value = $value . " ";
  235. }
  236. $head .= $value . ' ' . $price . ' ' . $num . ' ' . $prices;
  237. } else {
  238. $head .= $value . '<BR>';
  239. }
  240. }
  241. $orderInfo .= $head . $tail;
  242. }
  243. $orderInfo .= '--------------------------------<BR>';
  244. return $orderInfo;
  245. }
  246. /**
  247. * @param $time
  248. * @return string
  249. */
  250. protected function signature($time)
  251. {
  252. // 公共参数,请求公钥
  253. return sha1($this->app_id . $this->app_secret_key . $time);
  254. }
  255. }
粤ICP备19079148号