如果看了上篇文章就知道。我先是用java去对接了丰桥物流接口。老本行对接还是快。毕竟java涉猎时间最长的。对接时间也是最短的。java对接成功以后。就开始转移到小程序。因为手里已经上线的是微信小程序。最终要查询物流信息的程序也是微信小程序。
刚开始一直走入一个误区。想着微信小程序也要用java一样的方法去实现。就做的和java一模一样的去请求。java 传的字符串json数据原封不动的做到小程序里。去请求。刚开始确实拿到了数据。但是我样式做完的时候。发现返回来的数据是错误的。只有一个数据。说明这个方法还是不行。
后来仔细的研究了丰桥的nodejs的sdk。我发现这两个sdk连请求路径都不一样。nodejs的请求路径和java的是不一样的。童鞋们一定要注意了。后来根据丰桥的这个sdk去修改代码。最终拿到了我想要的数据。在这里卡了好几天。最后拿到数据的时候,还是非常开心的。
如果还没有申请顺丰账号的先去官网申请顺丰顾客编码和校验码。可以先看我的上篇文章。
1、下载相对应的nodejs的sdk.下载完成以后解压。看到nodejs的sdk还是有一个lib下面有一个可以调用的类。
2、lib下的类我先复制上来。这是顺丰sdk下的lib。这个后期用不到。先大家看看。我把这个类复制到微信小程序里以后。crypto 这个类是找不到的。朋友们可以自己去下载这个类,去实现sdk给的这个类对应的功能。
const request = require('request')
const crypto = require('crypto');
const md5 = crypto.createHash('md5');
class httpClient {
constructor() {
}
callSfExpressServiceByCSIM(reqURL, myReqXml, clientCode, checkword) {
if(!reqURL){
reqURL = "https://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService"
}
//加密生成verifyCode;
let verifyCode = md5.update(myReqXml + checkword, 'utf8').digest('base64');
request.post(reqURL, {
form: {
"xml": myReqXml,
"verifyCode": verifyCode
}
}, function (error, response, body) {
if (error) {
console.log("--------------------------------------");
console.error(`请求遇到问题: ${error}`);
console.log("--------------------------------------");
}
if (body) {
console.log("--------------------------------------");
console.log("返回报文: " + body);
console.log("--------------------------------------");
}
})
}
}
module.exports = httpClient;
3、我这里是直接用了小程序的云开发。通过云去得到这个md5。
创建一个云函数,部署到云端。下面是云里的js代码。就是把顺丰自己的那个lib下的东西拿过来。
//获取顺丰的数据,根据云函数
const cloud = require('wx-server-sdk')
let crypto = require('crypto');
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
let md5 = crypto.createHash('md5');
//加密生成verifyCode;
let verifyCode = md5.update(event.text, 'utf8').digest('base64');
console.log("verifyCode",verifyCode)
return {
verifyCode
}
}
4、仔细观察,发下请求的时候只需要两个参数。一个是xml。就是需要上传的查询订单信息的xml数据。还有一个就是加密过后的md5值。
"xml": myReqXml
"verifyCode": verifyCode
想办法得到这两个数据就可以去做请求了。
5、丰桥的sdk下有很多xml的模板
5、我用的是第5个xml模板,我们可以打开看下这个模板。这是一个标准的xml格式的数据。
通过观看sdk发下。只需要替换掉 head为自己的顾客编码。然后替换掉单号就可以用这个数据去做网络请求了。
<Request service='RouteService' lang='zh-CN'>
<Head>SLKJ2019</Head>
<Body>
<RouteRequest
tracking_type='1'
method_type='1'
tracking_number='444000092338'/>
</Body>
</Request>
6、微信小程序没法生成xml格式的string。我先把tracking_number的值修改为ordercode一个固定的字符串。后期替换了这个head的参数还有tracking_number的参数为自己想要的就可以达到动态查询的目的。这个字符串如何读到程序里为string 呢。用了很多办法都没实现。我想到的就是把这个数据传入云数据库。然后通过云去下载这个数据。下载完存入本地在读为string再去替换。最后就是这样操作的然后也成功了。见下图代码。
const URL_SF = "https://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService"
const CLIENT_CODE = ""; //SF顾客编码
const CHECK_WORD = "";//SF校验码
let myReqXml;//顺丰保存在本地的xml文本/或者通过云函数网络访问得到的
_downFile() {
//下载xml顺丰模板,将模板存入本地,避免每次进入下载
if (wx.getStorageSync('xmlText') == "" || wx.getStorageSync('xmlText') == undefined) {
// 下载文件
wx.cloud.downloadFile({
// 返回链接地址 仅支持小程序中展示 cloud协议
// 此处修改自己需要的下载模板的路径
fileID: "cloud://xyt-beta-6g6kynagdd99b9b6.7879-xyt-beta-6g6kynagdd99b9b6-1306328447/queryByMailNo.txt",
success: res => {
console.log(res)
let fs = wx.getFileSystemManager()
var reqXml = fs.readFileSync(res.tempFilePath, "utf-8")
// 读取文件内容到result
let oriReqXml = reqXml.replace(/SLKJ2019/ig, CLIENT_CODE)
wx.setStorageSync("xmlText", oriReqXml)
myReqXml = oriReqXml
//扫码快递单号。根据快递单号去查询快递信息
this.checkKDFromImg()
},
fail(err) {
console.log(err);
}
})
} else {
myReqXml = wx.getStorageSync('xmlText')
console.log("myReqXmlelse", myReqXml)
//扫码快递单号。根据快递单号去查询快递信息
this.checkKDFromImg()
}
},
此处得到的myReqXml是xml格式的string。然后去修改运单号即可查询自己想要的运单内容了。代码如下
//请求快递单详情SF LogisticCode为传入的顺丰单号,替换前面写死的ordercode字符串
getLogisticsSF(LogisticCode) {
var that = this;
myReqXml = wx.getStorageSync('xmlText')
myReqXml = myReqXml.replace(/ordercode/ig, LogisticCode)//"SF1199158951874"
//云函数得到加载后的加密数据
wx.cloud.callFunction({
name: 'getMd5',
data: { //传递
text: myReqXml + CHECK_WORD,
}
}).then(res => {
wx.request({
url: URL_SF,
method: "post",
data: {
xml: myReqXml,
verifyCode: res.result.verifyCode
},
header: {
"Content-type": "application/x-www-form-urlencoded;charset=UTF-8"
//POST 请求会将data的值放在Request Payload里面,而不是Query String Parameters里面,后端服务器如果不注意,就无法取到数据。加上此句处理成功
},
success(res) {
console.log("success", res)
},
fail(res) {
console.log(res)
}
})
}).catch(err => {
console.log(err)
})
}
打印res就是小程序通过顺丰拿到的 运单物流信息。