*/ class XpYunService extends Service { const URL = 'https://open.xpyun.net/api/openapi/'; //接口IP或域名 public $terminal_number; public $app_id; public $app_secret_key; public $print_num = 1; /** * @var string[] */ protected $errorInfo = [ 0 => '成功', -1 => '请求头错误', -2 => '参数不合法', -3 => '参数签名失败', -4 => '用户未注册', 1001 => '打印机编号和用户不匹配', 1002 => '打印机未注册', 1003 => '打印机不在线', 1004 => '添加订单失败', 1005 => '未找到订单信息', 1006 => '订单日期格式或大小不正确', 1007 => '打印内容不能超过12K', 1008 => '用户修改打印机记录失败', 1009 => '用户添加打印机时,打印机编号或名称不能为空', 1010 => '打印机设备编号无效', 1011 => '打印机已存在,若当前开放平台无法查询到打印机信息,请联系售后技术支持人员核实', 1012 => '添加打印设备失败,请稍后再试或联系售后技术支持人员', ]; /** * @param XpYun $config */ public function initConfig(XpYun $config) { $this->app_id = $config->app_id; $this->app_secret_key = $config->app_secret_key; $this->terminal_number = $config->terminal_number; $this->print_num = $config->print_num; parent::init(); } /** * @param $content * @param int $times * @param XpYun|array $config */ public function print($content, $config = []) { if (!empty($config)) { $this->initConfig($config); } // 格式化内容 $content = $this->formattedContent($content); $time = time(); // 请求时间 $jsonStr = [ 'user' => $this->app_id, 'timestamp' => $time, 'sign' => $this->signature($time), 'debug' => '1', 'sn' => $this->terminal_number, 'content' => $content, 'mode' => '1', // 值为 1 不检查打印机是否在线,直接生成打印订单,并返回打印订单号。如果打印机不在线,订单将缓存在打印队列中,打印机正常在线时会自动打印 'copies' => $this->print_num, // 打印次数 'money' => $content['payMoney'] ?? 0 ]; $jsonStr = Json::encode($jsonStr); $curl = new Curl(); $result = $curl->setHeaders([ 'Content-Type' => 'application/json;charset=UTF-8', 'Content-Length: ' . strlen($jsonStr) ])->setRawPostData($jsonStr)->post(self::URL . 'xprinter/print'); $result = Json::decode($result); if ($result['code'] != 0) { if (isset($this->errorInfo[$result['code']])) { throw new UnprocessableEntityHttpException($this->errorInfo[$result['code']]); } throw new UnprocessableEntityHttpException($result['msg']); } return $result['data']; } /** * @param $data * @return string * @throws \yii\base\InvalidConfigException */ protected function formattedContent($data) { if (!is_array($data)) { return $data; } $content = "****** {$data['title']} ******
" . "
"; $content .= str_repeat('.', 32) . "
"; $content .= "---{$data['payType']}---
" . "
"; // $content .= "{$data['merchantTitle']}"; $content .= "打印时间:" . Yii::$app->formatter->asDatetime(time()) . "
"; $content .= "下单时间:" . $data['orderTime'] . "
"; $content .= str_repeat('*', 13) . " 商品 " . str_repeat("*", 13) . "
"; $content .= $this->composing($data['products']); $content .= "商品总价:¥{$data['productOriginalMoney']}
"; foreach ($data['marketingDetails'] as $marketingDetail) { $content .= "{$marketingDetail['marketing_name']}:-¥{$marketingDetail['discount_money']}
"; } $data['pointMoney'] > 0 && $content .= "积分抵扣:-¥{$data['pointMoney']}
"; $data['taxMoney'] > 0 && $content .= "发票税额:-¥{$data['taxMoney']}
"; $content .= "配送费:¥{$data['shippingMoney']}
"; $content .= "应付金额:¥{$data['payMoney']}
"; $content .= str_repeat('.', 32) . "
"; $content .= "昵称: " . $data['nickname'] . "
"; isset($data['receiverName']) && $content .= "客户: " . $data['receiverName'] . "
"; isset($data['receiverMobile']) && $content .= "电话: " . StringHelper::hideStr($data['receiverMobile'], 3) . "
"; isset($data['receiverAddress']) && $content .= "地址: " . $data['receiverRegionName'] . $data['receiverAddress'] . "
"; isset($data['buyerMessage']) && $content .= "备注: " . !empty($data['buyerMessage']) ? $data['buyerMessage'] : '无' . "
"; if (!empty($data['qr'])) { $content .= str_repeat('.', 32) . "
"; $content .= "二维码
"; $content .= "{$data['qr']}"; } else { $content .= str_repeat('.', 32) . "
"; $content .= "二维码
"; $content .= "{$data['orderSn']}"; } $content .= str_repeat('.', 32) . "
"; $content .= "订单号"; $content .= "{$data['orderSn']}" . "
"; $content .= "****** 完 ******
" . "
"; return $content; } /** * * @param $products * @param int $A 名称 * @param int $B 单价 * @param int $C 数量 * @param int $D 金额 * @return string */ protected function composing($products, $A = 14, $B = 6, $C = 3, $D = 6) { $orderInfo = '商品名称      数量 金额
'; $orderInfo .= '--------------------------------
'; foreach ($products as $k5 => $v5) { $name = $v5['title']; // $price = $v5['price']; $price = ''; $num = $v5['num']; $prices = $v5['price']; $kw3 = ''; $kw1 = ''; $kw2 = ''; $kw4 = ''; $str = $name; $blankNum = $A;//名称控制为14个字节 $lan = mb_strlen($str, 'utf-8'); $m = 0; $j = 1; $blankNum++; $result = array(); if (strlen($price) < $B) { $k1 = $B - strlen($price); for ($q = 0; $q < $k1; $q++) { $kw1 .= ' '; } $price = $price . $kw1; } if (strlen($num) < $C) { $k2 = $C - strlen($num); for ($q = 0; $q < $k2; $q++) { $kw2 .= ' '; } $num = $num . $kw2; } if (strlen($prices) < $D) { $k3 = $D - strlen($prices); for ($q = 0; $q < $k3; $q++) { $kw4 .= ' '; } $prices = $prices . $kw4; } for ($i = 0; $i < $lan; $i++) { $new = mb_substr($str, $m, $j, 'utf-8'); $j++; if (mb_strwidth($new, 'utf-8') < $blankNum) { if ($m + $j > $lan) { $m = $m + $j; $tail = $new; $lenght = iconv("UTF-8", "GBK//IGNORE", $new); $k = $A - strlen($lenght); for ($q = 0; $q < $k; $q++) { $kw3 .= ' '; } if ($m == $j) { $tail .= $kw3 . ' ' . $price . ' ' . $num . ' ' . $prices; } else { $tail .= $kw3 . '
'; } break; } else { $next_new = mb_substr($str, $m, $j, 'utf-8'); if (mb_strwidth($next_new, 'utf-8') < $blankNum) { continue; } else { $m = $i + 1; $result[] = $new; $j = 1; } } } } $head = ''; foreach ($result as $key => $value) { if ($key < 1) { $v_lenght = iconv("UTF-8", "GBK//IGNORE", $value); $v_lenght = strlen($v_lenght); if ($v_lenght == 13) { $value = $value . " "; } $head .= $value . ' ' . $price . ' ' . $num . ' ' . $prices; } else { $head .= $value . '
'; } } $orderInfo .= $head . $tail; } $orderInfo .= '--------------------------------
'; return $orderInfo; } /** * @param $time * @return string */ protected function signature($time) { // 公共参数,请求公钥 return sha1($this->app_id . $this->app_secret_key . $time); } }