event = $param['event']; if (!isset($param['order_type'])) { $this->order = Order::find()->where(['id' => $param['order_id']])->one(); $this->mall_id = $this->order['mall_id']; $this->order_detail = $this->order->detail; } else { $order_type = $param['order_type']; switch ($order_type){ case "C": $storeCashierOrder = StoreCashierOrder::find()->where(['id' => $param['order_id']])->one(); $extra = json_decode($storeCashierOrder['extra'],true); $this->mall_id = $storeCashierOrder['mall_id']; $order = new Order(); $order->user_id = $storeCashierOrder['user_id']; $order->mall_id = $storeCashierOrder['mall_id']; $order->store_id = $storeCashierOrder['store_id']; $order->order_no = $storeCashierOrder['order_no']; $order->payment_type = $storeCashierOrder['payment_type']; $order->pay_money = $storeCashierOrder['pay_money']; $order->created_at = $storeCashierOrder['created_at']; $order->remark = $storeCashierOrder['remark']; $order->original_goods_price = $storeCashierOrder['money']; $order->seller_remark = ''; $order->score_money = 0.00; $order->coupon_money = 0.00; if(!empty($extra)&&is_array($extra)){ if(!empty($extra['deduct_num_score'])){ $order->score_money = $extra['discount_money']; } if(!empty($extra['discount'])){ $order->coupon_money = $extra['discount']; } } $order_detail = StoreCashierOrderDetail::lists(['where'=>[['cashier_order_id'=>$storeCashierOrder['id']]]],false); if(empty($order_detail)) $order_detail = new OrderDetail(); $this->order = $order; $this->order_detail = $order_detail; break; } } $params = [ 'where' => [['=', 'mall_id', $this->mall_id], ['in', 'name', ['contact_tel', 'web_url', 'quick_map_address']]], 'select' => ['value', 'name'] ]; $this->mall_info = array_column(MallSetting::lists($params), 'value', 'name'); return $this; } /** * 设置打印机配置 * @return array */ public function getOpenPrinterConfig() { $params = [ 'select' => [$this->event, 'terminal', 'secret_key', 'api_key', 'mall_id', 'user_id', 'printer_type', 'store_id','mch_id', 'client_id','print_width'], 'where' => [['=', 'mall_id', $this->mall_id], ['status'=>StatusEnum::ENABLED]] ]; $list = Printer::lists($params); if (empty($list)) return []; foreach ($list as $k => $val) { $v = json_decode($val[$this->event], true); if ($v['is_printer'] == 0) { unset($list[$k]); continue; } if(!empty($this->order['mch_id'])){ if($this->order['mch_id']!=$val['mch_id']){ continue; } } if(!empty($this->order['store_id'])){ if($this->order['store_id']!=$val['store_id']){ continue; } } $this->config[] = [ 'user_id' => $val['user_id'], 'mall_id' => $val['mall_id'], 'client_id' => $val['client_id'], 'machine_code' => $val['terminal'], 'key' => $val['secret_key'], 'client_key' => $val['api_key'], 'time' => $v['num'], 'printer_type' => $val['printer_type'], 'store_id' => $val['store_id'], 'mch_id' => $val['mch_id'], 'template_id' => $v['template_id'], 'print_width' => $val['print_width'], ]; } } public function getPrinterTemplate() { if(!empty($this->config)){ $template_id = array_column($this->config, 'template_id'); $params = [ 'where' => [['=', 'mall_id', $this->mall_id], ['status'=>StatusEnum::ENABLED], ['in', 'id', $template_id]] ]; $this->template_list = array_column(PrinterTemplate::lists($params), null, 'id'); } } /** * 打印 */ public function print() { try { //判断是商场打印机还是门店打印机 $this->getOpenPrinterConfig(); $this->getPrinterTemplate(); if (empty($this->template_list) || empty($this->config)) { return; } $template = new DefaultTemplate(); $redis = \Yii::$app->redis; foreach ($this->config as $config) { if (($config['printer_type'] == 1 && $this->order['store_id'] == 0 && $this->order['mch_id'] == 0) || ($config['printer_type'] == 2 && $this->order['store_id'] == $config['store_id'])|| ($config['printer_type'] == 3 && $this->order['mch_id'] == $config['mch_id'])) { \Yii::error('===================='.json_encode($config)); $clientId = $config['client_id']; $machine_code = $config['machine_code']; $clientSecret = $config['client_key']; $yilian_config = new YlyConfig($clientId, $clientSecret); $client = new YlyOauthClient($yilian_config); $mall_id = $config['mall_id']; $cacheKey = RedisKeyEnum::suffix('printer_keys', $clientId); $access_token = $redis->get($cacheKey); if (empty($access_token)) { $token = $client->getToken(); $access_token = $token->access_token; //调用API凭证AccessToken 永久有效,请妥善保存. $redis->set($cacheKey,$access_token,'EX',30*24*3600-1); } $machine_code = $config['machine_code']; //机器码 $origin_id = StringHelper::generateOrderNo('p'); //内部订单号(32位以内) $template_info = $this->template_list[$config['template_id']]; $printData = $this->setOrderPrintData($template_info); /**文本接口开始**/ $print = new PrintService($access_token, $yilian_config); $content = $this->getContent($printData,$config['print_width']); $res = $print->index($machine_code, $content, $origin_id); if(isset($res->error)&&$res->error!=0){ throw new Exception($res->error_description); }else{ $result['err'] = 0; $result['msg'] = '打印成功'; } } } if(!isset($result['err'])){ $result['err'] = 1; $result['msg'] = '打印错误,请检查打印机配置是否正确'; } } catch (Exception $e) { \Yii::error('打印错误,msg=' . $e->getMessage() . ',行数:' . $e->getLine() . $e->getFile()); $result['err'] = 1; $result['msg'] = '打印错误,msg=' . $e->getMessage() . ',行数:' . $e->getLine() . $e->getFile(); } return $result; } public function getContentOld($data) { $content = ''; foreach ($data as $item) { if (isset($item['show']) && $item['show'] == 0) { continue; } $getter = 'get' . $item['handle']; if (isset($item['children'])) { $children = $item['content']; foreach ($item['children'] as $value) { if (isset($value['content'])) { $childGetter = 'get' . $value['handle']; $children .= $this->$childGetter($value['content']); } } $content .= $this->$getter($children); } else { $content .= $this->$getter($item['content']); } } return $content; } public function getContent($printData,$print_width) { $order_type = '商城订单'; $mall_name = ''; if(!empty($printData->mall_name)){ $mall_name = $printData->mall_name; } if(!empty($this->order['mch_id'])){ $order_type = '商户订单'; if(MallAddons::isInstall($this->order['mall_id'],'Mch')){ $mch = Mch::findOne(['id'=>$this->order['mch_id']]); if(!empty($mch['store_name'])){ $mall_name = $mch['store_name']; } } } $is_store = false; if(!empty($this->order['store_id'])){ $order_no = $this->order['order_no']; if($order_no[0]=='C'){ $order_type = '门店收银台订单'; }else{ $order_type = '门店订单'; } $store = Store::findOne(['id'=>$this->order['store_id']]); if(!empty($store['store_name'])){ $is_store = true; $mall_name = $store['store_name']; } } $content = "
".$printData->ticket_nam."
"; if(!empty($mall_name)){ $content .= "
".$mall_name."
"; } $content .= $this->getDivide($print_width); if ($printData->is_show_pickup && $printData->pickup_code) { $content .= "自提码:{$printData->pickup_code}" . "\n"; } $content .= "订单类型:{$order_type}" . "\n"; $content .= "订单编号:".$printData->order_no."\n"; $content .= "下单时间:".$printData->created_at."\n"; $content .= $this->getDivide($print_width); if(isset($this->order_detail)&&isset($this->order_detail[0]['id'])){ $content .= ""; $content .= ""; if(isset($printData->is_show_price)&&$printData->is_show_price) $content .= ""; $content .= ""; foreach ($printData->goods_list as $item) { $content .= ""; if(isset($printData->is_show_price)&&$printData->is_show_price){ $content .= ""; } $content .= ""; // 规格 if ($printData->is_show_attr && !empty($item->attr)) { $content .= ""; } } $content .= "
名称数量单价
$item->name$item->num$item->unit_price
[" . $item->attr . "]
"; $content .= $this->getDivide($print_width); } $content .= "商品总计:".$printData->price."\n"; $content .= "运费:".$printData->shipping_money."\n"; $content .= "积分抵扣:".$printData->score_money."\n"; $content .= "优惠券优惠:".$printData->coupon_money."\n"; $content .= "实际支付:".$printData->pay_money."\n"; if(!empty($printData->is_show_name)||!empty($printData->is_show_addr)||!empty($printData->is_show_phone)) { $content .= $this->getDivide($print_width); if(isset($printData->is_show_name)&&$printData->is_show_name) $content .= "收货人:".$printData->receiver_name."\n"; if(isset($printData->is_show_addr)&&$printData->is_show_addr) $content .= "收货地址:".$printData->address."\n"; if(isset($printData->is_show_phone)&&$printData->is_show_phone) $content .= "收货电话:".$printData->mobile."\n"; } if(!empty($printData->is_show_mall_phone)||!empty($printData->is_show_mall_addr)) { $content .= $this->getDivide($print_width); if ($is_store) { // 门店 if (isset($printData->is_show_mall_phone) && $printData->is_show_mall_phone && $is_store) $content .= "商家联系方式:" . $store['shop_mobile'] ."\n"; if (isset($printData->is_show_mall_addr) && $printData->is_show_mall_addr && $is_store) $content .= "商家地址:" . $store['address'] ."\n"; } else { if(isset($printData->is_show_mall_phone)&&$printData->is_show_mall_phone) $content .= "商家联系方式:".$printData->contact_tel."\n"; if(isset($printData->is_show_mall_addr)&&$printData->is_show_mall_addr) $content .= "商家地址:".$printData->quick_map_address."\n"; } } if(!empty($printData->is_show_mall_code)||!empty($printData->is_show_remark)||!empty($printData->is_show_seller_remark)){ $content .= $this->getDivide($print_width); if(isset($printData->is_show_mall_code)&&$printData->is_show_mall_code) $content .= "
".$printData->mall_qrcode_url."
"; if(isset($printData->is_show_remark)&&$printData->is_show_remark) $content .= "备注:".$printData->remark."\n"; if(isset($printData->is_show_seller_remark)&&$printData->is_show_seller_remark) $content .= "商家留言:".$printData->seller_remark."\n"; } if(!empty($printData->is_show_qrcode_url)||!empty($printData->bottom_info)){ $content .= $this->getDivide($print_width); if(!empty($printData->is_show_qrcode_url)) $content .= "
".$printData->qrcode_url."
"; if(!empty($printData->bottom_info)) $content .= "
".$printData->bottom_info."
"; } return $content; } /** * 设置打印数据 */ public function setOrderPrintData($template) { $mall = Mall::findOne($this->mall_id); if (empty($mall)) { return false; } $data = new OrderContent(); $data->mall_name = empty($template['head_info']) ? '' : $mall->name; $data->ticket_nam = $template['ticket_nam']; $order_type = '商城订单'; if(!empty($this->order['mch_id'])){ $order_type = '商户订单'; } if(!empty($this->order['store_id'])){ $order_no = $this->order['order_no']; if($order_no[0]=='C'){ $order_type = '门店收银台订单'; $template['price_info'] = 1; }else{ $order_type = '门店订单'; } } $data->order_type = $order_type; $data->attribute = $this->order; $data->created_at = date("Y-m-d H:i:s", $this->order->created_at); $data->contact_tel = $this->mall_info['contact_tel']; $data->quick_map_address = $this->mall_info['quick_map_address']; $data->remark = $this->order['remark']; $data->seller_remark = $this->order['seller_remark']; $data->qrcode_url = $template['qrcode_url']; $data->mall_qrcode_url = $this->mall_info['web_url']; //var_dump($this->mall_info['quick_map_address']); $data->bottom_info = $template['bottom_info']; $data->address = $this->order->region_name. $this->order->address; $data->remark = $this->order->remark; $data->seller_remark = $this->order->seller_remark; // 自提码 if (MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_STORE)) { $packup = StoreOrderPickup::getPickupDataByMallOrderId($this->order->id); $packup && $data->is_show_pickup = empty($template['pickup_code']) ? false : true; $packup && $data->pickup_code = $packup['code']; } $paymentTypeEnum = PayTypeEnum::getMap(); $data->payment_type = isset($paymentTypeEnum[$this->order->payment_type]) ? $paymentTypeEnum[$this->order->payment_type] : '未知方式'; $ShippingTypeEnum = ShippingTypeEnum::getMap(); $orderInfo = []; foreach ($this->order_detail as $item) { $orderInfo[] = (object)[ 'attr' => $item->goods_attr_name ?? '', 'num' => $item->num ?? 0, 'total_price' => $item->original_goods_price ?? 0, 'unit_price' => $item->price ?? 0, 'name' => $item->goods_name ?? '' ]; } $data->goods_list = $orderInfo; $data->is_show_price = false; $data->is_show_barcode = false; if (!empty($template['goods_info'])) { $goods_info = json_decode($template['goods_info'], true); if (in_array(1, $goods_info)) { $data->is_show_price = true; } if (in_array(2, $goods_info)) { $data->is_show_barcode = true; } // 是否显示规格 if (in_array(3, $goods_info)) { $data->is_show_attr = true; } } $data->price = $template['price_info'] == 1 ? $data->original_goods_price : $data->pay_money; if (!empty($template['remarks_info'])) { $remarks_info = json_decode($template['remarks_info'], true); if (in_array(1, $remarks_info) && $data->remark) { $data->is_show_remark = true; } if (in_array(2, $remarks_info) && $data->seller_remark) { $data->is_show_seller_remark = true; } } if (!empty($template['buyer_info'])) { $buyer_info = json_decode($template['buyer_info'], true); if (in_array(1, $buyer_info)) { $data->is_show_name = true; } if (in_array(2, $buyer_info)) { $data->is_show_phone = true; } if (in_array(3, $buyer_info)) { $data->is_show_addr = true; } } if (!empty($template['mall_info'])) { $mall_info = json_decode($template['mall_info'], true); if (in_array(1, $mall_info)) { $data->is_show_mall_phone = true; } if (in_array(2, $mall_info)) { $data->is_show_mall_addr = true; } if (in_array(3, $mall_info)) { $data->is_show_mall_code = true; } } if (!empty($template['qrcode_url'])) { $data->qrcode_url = $template['qrcode_url']; $data->is_show_qrcode_url = true; } $data->bottom_info = $template['bottom_info']; return $data; } /** * 补齐空格 * 每n个中文字符长度为一个数组元素 * @param string $input * @param integer $n * @return array */ protected function rStrPad1($input, $n = 7) { $string = ""; $count = 0; $c_count = 0; $arr = array(); for ($i = 0; $i < mb_strlen($input, 'UTF-8'); $i++) { $char = mb_substr($input, $i, 1, 'UTF-8'); $string .= $char; if (strlen($char) == 3) { $count += 2; $c_count++; } else { $count += 1; } if ($count >= $n * 2) { $arr[] = $string; $string = ''; $count = 0; $c_count = 0; } } if ($count < $n * 2) { $string = str_pad($string, $n * 2 + $c_count); $arr[] = $string; } return $arr; } /** * 补齐空格 * 截取七个中文字符长度 * @param string $input * @param integer $n * @return string */ protected function rStrPad($input, $n = 7) { $string = ""; $count = 0; $c_count = 0; for ($i = 0; $i < mb_strlen($input, 'UTF-8'); $i++) { $char = mb_substr($input, $i, 1, 'UTF-8'); $string .= $char; if (strlen($char) == 3) { $count += 2; $c_count++; } else { $count += 1; } if ($count >= $n * 2) { break; } } if ($count < $n * 2) { $string = str_pad($string, $n * 2 + $c_count); } return $string; } /** * @return string * 打印次数 */ public function getTimes() { return ''; } /** * @param $content * @return mixed * 居中 */ public function getCenter($content) { return $content; } /** * @param $content * @return mixed * 加粗 */ public function getBold($content) { return $content; } /** * @param $content * @return string * 居中加粗 */ public function getCenterBold($content) { return "$content"; } /** * @param $content * @return mixed * 换行 */ public function getBR($content) { return $content; } /** * @param OrderContent $data * @return mixed * 表格---不显示规格 */ public function getTableNoAttr($data) { return ''; } /** * @param OrderContent $data * @return mixed * 表格--显示规格 */ public function getTableAttr($data) { return ''; } /** * @param $content * @return string * 价格--后缀 */ public function getPrice($content) { return $content . '元'; } /** * @return mixed * 分隔符 */ public function getDivide($print_width='58mm') { switch ($print_width){ case '58mm': return $this->getBR("--------------------------------"); case '72mm': return $this->getBR("------------------------------------------------"); default: return $this->getBR("--------------------------------"); } } public function getRemarkText($text) { $arrText = $this->rStrPad1($text, 18); $newText = ''; foreach ($arrText as $item) { $newText .= $this->getBR($item); } return $newText; } }