关于菜鸟的圆通电子面单打印
- https://open.taobao.com/docs/doc.htm?spm=a21da.7629140.0.0.97iBG8&docType=1&articleId=107052 电子面单接入文档(LINK接入)
- https://dayin.cainiao.com/miandan/subscription/branchRechargeInfo.htm?spm=a2d3a.8498240.0.0.558119b3hxhtix 订购关系查询
- https://lcp.cloud.cainiao.com/ 后台地址
- http://pac.i56.taobao.com/apiinfo/showDetail.htm?spm=0.0.0.0.3tcf05&apiId=TMS_WAYBILL_SUBSCRIPTION_QUERY&type=merchant_electronic_sheet API地址
前面的地址是需要仔细看的,我做的电子面单打印是依靠菜鸟的打印组件预览出来再手动打印,并不是全部用菜鸟的打印组件打印,下面是正式的介绍情况了.
第一步
申请需要申请的账号,这些你就看文档,我也帮不了你什么,我也是别人先申请我在用的.
第二部
单独创建一个控制器,这是控制器的内容,我并不是靠ajax传递数据到控制器接收的,而是用form表单提交,这里说清楚,接收的数据按照你要传递的情况自己组装
1 //圆通信息
2 $a=time()+1;//随机订单号
3 $b=time();//随机包裹号 这两个参数不许是变量,不然每次返回的快递单号都是同一个,也就是合单,你也可以在群里问客服
4 //下面是需要传递到接口的数据
5 $eorderi ='{"cpCode":"YTO","dmsSorting":"false","needEncrypt":"false","resourceCode":"无",
6 "sender":{
7 "address":{
8 "city":"宿迁市",
9 "detail":"淮海东路*********",
10 "district":"泗阳县",
11 "province":"江苏省",
12 "town":""
13 },
14 "mobile":"18***742",
15 "name":"曲*",
16 "phone":"1865***42",
17 },//这些是发货地址,和你在订购关系里申请的内容要一样
18 "storeCode":"无",
19 "tradeOrderInfoDtos":[
20 {
21 "logisticsServices":"",
22 "objectId":"1",
23 "orderInfo":{
24 "orderChannelsType":"OTHERS",
25 "tradeOrderList":[
26 "'.$a.'"//订单号
27 ]
28 },
29 "packageInfo":{
30 "id":"'.$b.'",//包裹号
31 "items":[
32 {
33 "count":"'.$total_number.'",
34 "name":"衣服"
35 }
36 ],
37 "volume":"1",
38 "weight":"1"
39 },
40 "recipient":{
41 "address":{
42 "city":"'.$ship_order_data['city'].'",
43 "detail":"'.$ship_order_data['address'].'",
44 "district":"'.$ship_order_data['exparea'].'",
45 "province":"'.$ship_order_data['province'].'",
46 "town":""
47 },
48 "mobile":"'.$ship_order_data['phone'].'",
49 "name":"'.$ship_order_data['username'].'",
50 "phone":"'.$ship_order_data['phone'].'"
51 },//这些是发货地址
52 "templateUrl":" http://cloudprint.cainiao.com/template/standard/101/572",//我用的是圆通,所以这是模板的地址,自己在API里面找
53 "userId":"12"//随便填写
54 }
55 ]
56 }';57 58 $jsonResult = $this->submitEOrderi($eorderi);5960 $str=json_decode($jsonResult);
$this->assign('list',$str->waybillCloudPrintResponseList[0]->printData);//只需要打印里面的printData里的数据
return $this->fetch('ce');//新写一个空白的前端.数据在那边接收
第三部
后端代码
//圆通电子面单接口
/**
* Json方式 调用电子面单接口
*/
public function submitEOrderi($requestData)
{
$url='http://link.cainiao.com/gateway/link.do';//正式地址 必须
$appSecret ='z026yj********83S3B6cv86';必须
//
$datas = array(
'msg_type' =>'TMS_WAYBILL_GET',
'logistic_provider_id' =>'UFI1c3dkR2tNRWpX*********************1zWWZxS2V5Y1FrWi90K21jelhOSTMwQ3pKaA==',必须
'data_digest'=>$this->encrypti($requestData,$appSecret),//获取签名
'logistics_interface' =>$requestData,
);
$result = $this->sendPosti($url,$datas);提交数据
return $result;
}
/**
* 电商Sign签名生成
* @param data 内容
* @param appkey Appkey
* @return DataSign签名
*/
public function encrypti($data,$appSecret)
{
return base64_encode(md5($data.$appSecret,true));
}
/**
* post提交数据
* @param string $url 请求Url
* @param array $datas 提交的数据
* @return url响应返回的html
*/
function sendPosti($url, $datas) {
$temps = array();
foreach ($datas as $key => $value) {
$temps[] = sprintf('%s=%s', $key, $value);
}
$post_data = implode('&', $temps);
$url_info = parse_url($url);
if(empty($url_info['port']))
{
$url_info['port']=80;
}
$httpheader = "POST " . $url_info['path'] . " HTTP/1.0\r\n";
$httpheader.= "Host:" . $url_info['host'] . "\r\n";
$httpheader.= "Content-Type:application/x-www-form-urlencoded\r\n";
$httpheader.= "Content-Length:" . strlen($post_data) . "\r\n";
$httpheader.= "Connection:close\r\n\r\n";
$httpheader.= $post_data;
$fd = fsockopen($url_info['host'], $url_info['port']);
fwrite($fd, $httpheader);
$gets = "";
$headerFlag = true;
while (!feof($fd)) {
if (($header = @fgets($fd)) && ($header == "\r\n" || $header == "\n")) {
break;
}
}
while (!feof($fd)) {
$gets.= fread($fd, 128);
}
fclose($fd);
return $gets;
}
前端页面的代码
<include file="public@header"/>
<head>
<title>Print Test</title>
<style type="text/css">
/*div#ctlDiv {height:750px;width:50%;float:left;border-style:solid;border-color:red;border-width:0px;}*/
div#pdfDiv {height:750px;width:49%;border-style:solid;border-color:red;border-width:0px;}
</style>
<script type="text/javascript">
var socket;
window.onload = function load()
{
document.getElementById("pdfDiv").style.visibility="hidden";
}
function setStatusLabel(msg)
{
var eStatus = document.getElementById("connectionStatus");
eStatus.innerHTML = msg;
}
function doConnect(callback)
{
var serviceUrl = document.getElementById("serviceUrl").value;
socket = new WebSocket(serviceUrl);
// 监听消息
socket.onmessage = function(event)
{
console.log('Client received a message',event);
document.getElementById("pdfDiv").style.visibility="hidden";
// parse json
var obj = eval('('+event.data+')');
if (obj && (obj.previewURL || obj.previewImage))
{
var url;
if (obj && obj.previewURL) {
url = obj.previewURL;
} else if (obj && obj.previewImage) {
url = obj.previewImage;
}
var pdf = document.getElementById('pdf');
if (pdf) {
pdf.setAttribute('src', url);
document.getElementById("pdfDiv").style.visibility="visible";
}
}
var resultElement = document.getElementById("resultMessage");
resultElement.value = resultElement.value + event.data + "\n";
resultElement.scrollTop = resultElement.scrollHeight;
};
socket.onopen = function(event)
{
if (callback != null) {
callback();
}
setStatusLabel("已连接");
}
socket.onerror = function(error)
{
console.log("Failed to connect CN print at " + serviceUrl, error);
setStatusLabel("连接错误");
}
// 监听Socket的关闭
socket.onclose = function(event)
{
console.log('Client notified socket has closed',event);
setStatusLabel("连接关闭");
};
}
function sendCommand()
{
if (typeof socket == "undefined" || socket.readyState == WebSocket.CLOSED) {
doConnect(sendCommand);
return;
}
if (socket.readyState != WebSocket.OPEN) {
alert("无效连接: " + socket.readyState);
return;
}
var msg = document.getElementById('printmessage').value;
var repeatCount = document.getElementById('repeatCount').value;
var isPreview = document.getElementById('isPreview').checked;
var time = new Date().getTime();
for (var index = 0; index < repeatCount; index++) {
var obj = JSON.parse(msg);
if (obj["task"])
{
// taskID
obj["task"]["taskID"] = time.toString() + "_TASK_" + index;
// preview
obj["task"]["preview"] = isPreview;
}
var newMsg = JSON.stringify(obj);
socket.send(newMsg);
}
}
function clearResult()
{
var resultElement = document.getElementById("resultMessage");
resultElement.value = "";
}
</script>
</head>
<body>
<div id="ctlDiv">
<form name="formname" action="javascript:sendCommand()">
<p hidden>重复发送请求:<input id="repeatCount" type="number" min="1" max="1000" step="1" value="1">
<input hidden id="isPreview" type="checkbox" checked="true">预览模式
</p>
<p> <input hidden type="text" id="serviceUrl" name="serviceUrl" value="ws://localhost:13528" />
<label hidden id="connectionStatus">未知</label>
<input hidden id="dianji" type="submit" value="发送请求"/>
</p>
<textarea hidden cols="80" rows="20" id="printmessage" name="printmessage">{
"cmd": "print",
"requestID": "123458976",
"version": "1.0",
"task": {
"taskID": "7293666",
"preview": false,
"printer": "",
"notifyMode": "allInOne",
"previewType": "html",
"documents": [
{
"documentID": "0123456789",
"contents": [
{$list}//数据是在这里哦接收的,你不需要改什么,如果你觉得这不是你想要的,你也可以借鉴一下方法
]
}
]
}
}
</textarea>
<br/><br/>
<textarea hidden cols="80" rows="20" id="resultMessage" name="resultMessage" readonly="readonly"></textarea>
<br/>
<input hidden type="button" value="清除返回消息" onclick="clearResult()"/>
</form>
</div>
<div style="margin: 0 auto" id="pdfDiv" align="middle">
<iframe id="pdf" src="" width="100%" height="100%">
</iframe>
</div>
</body>
</html>
<script>
$('#dianji').click();
</script>
最后放一张预览成功的图片(注:必须安装菜鸟打印组件菜鸟预览)
这个需要右键打印,或点击打印的图标才能打印,打印情况就说到这里了