//#region import
|
import BaseApiService from "../baseApiService";
|
import { ResultInfo } from "../../public/commonInterface";
|
import moment = require("moment");
|
import * as crypto from "crypto";
|
import xml2js = require("xml2js");
|
import { ExpressYTOrder } from "../../entity/express/yuantong/expressYTOrder";
|
import { ExpressYTBaseInfo } from "../../entity/express/yuantong/expressYTBaseInfo";
|
import { ExpressYTOrderList } from "../../entity/express/yuantong/expressYTOrderList";
|
import { ExpressYTOrderRoute } from "../../entity/express/yuantong/expressYTOrderRoute";
|
import { SaleOrder } from '../../entity/outbound/sale/saleOrder';
|
|
//#endregion
|
|
/**
|
* 运单轨迹帮助类
|
*/
|
export default class YuantongHelperService extends BaseApiService {
|
//#region 圆通推送运单 pushOrderbyYT
|
public async pushOrderbyYT(orderId): Promise<ResultInfo> {
|
let { ctx } = this;
|
let info: ResultInfo = {
|
result: false,
|
msg: undefined
|
};
|
try {
|
let orderInfo = await this.dbRead.findOne(ExpressYTOrder, {
|
yTOrder_Id: orderId
|
});
|
var pushNum = 0;
|
if (orderInfo.pushNum) {
|
pushNum = orderInfo.pushNum;
|
}
|
if (pushNum >= 5) {
|
info.result = false;
|
info.msg = "订单[" + orderInfo.orderCode + "]推送次数超过5次,无法推送!";
|
return info;
|
}
|
pushNum = pushNum + 1;
|
//获得账户信息
|
// if (!orderInfo.interfaceAccount_Id) {
|
// info.result = false;
|
// info.msg = "订单[" + orderInfo.orderCode + "]位置接口账号,无法推送!";
|
// return info;
|
// }
|
let baseInfo = await this.dbRead.findOne(ExpressYTBaseInfo, {
|
userProduct_Id: orderInfo.userProduct_Id,
|
apiName: '圆通电子面单接口'
|
});
|
var yT_WebService = baseInfo.apiUrl;
|
var clientId = baseInfo.clientId;
|
var partnerID = baseInfo.partnerID;
|
var type = baseInfo.type;
|
let orderList = await this.dbRead
|
.createQueryBuilder(ExpressYTOrderList, "t")
|
.where(`yTOrder_Id=:yTOrder_Id`, {
|
yTOrder_Id: orderId
|
})
|
.getMany();
|
var items = "";
|
var special = 0;
|
for (let list of orderList) {
|
special = parseInt(list.special);
|
items +=
|
" <item>" +
|
" <itemName>" +
|
list.itemName +
|
"</itemName>" +
|
" <number>" +
|
list.number +
|
"</number>" +
|
" <itemValue>" +
|
list.itemValue +
|
"</itemValue>" +
|
" </item>";
|
}
|
//发货人市区
|
var sendercity = "";
|
if (orderInfo.sendercity) {
|
sendercity = orderInfo.sendercity;
|
}
|
if (orderInfo.sendercounty) {
|
if (sendercity) {
|
sendercity += ",";
|
}
|
sendercity += orderInfo.sendercounty;
|
}
|
|
//收货人市区
|
var city = "";
|
if (orderInfo.city) {
|
city = orderInfo.city;
|
}
|
if (orderInfo.county) {
|
if (city) city += ",";
|
city += orderInfo.county;
|
}
|
|
var xmlBuilder =
|
"<RequestOrder>" +
|
" <clientID>" +
|
clientId +
|
"</clientID>" +
|
" <logisticProviderID>YTO</logisticProviderID>" +
|
" <customerId>" +
|
clientId +
|
"</customerId>" +
|
" <txLogisticID>" +
|
orderInfo.orderCode +
|
"</txLogisticID>" +
|
" <tradeNo></tradeNo>" +
|
" <mailNo></mailNo>" +
|
" <totalServiceFee>" +
|
orderInfo.totalServiceFee +
|
"</totalServiceFee>" +
|
" <codSplitFee>" +
|
orderInfo.codSplitFee +
|
"</codSplitFee>" +
|
" <orderType>" +
|
orderInfo.orderType +
|
"</orderType>" +
|
" <serviceType>" +
|
orderInfo.serviceType +
|
"</serviceType>" +
|
" <flag>" +
|
orderInfo.flag +
|
"</flag>" +
|
" <sendStartTime>" +
|
orderInfo.sendEndTime +
|
"</sendStartTime>" +
|
" <sendEndTime>" +
|
orderInfo.sendEndTime +
|
"</sendEndTime>" +
|
" <goodsValue>" +
|
orderInfo.goodsValue +
|
"</goodsValue>" +
|
" <insuranceValue>" +
|
orderInfo.itemsWeight +
|
"</insuranceValue>" +
|
" <special>" +
|
special +
|
"</special>" +
|
" <remark>" +
|
orderInfo.remark +
|
"</remark>" +
|
" <type>" +
|
orderInfo.type +
|
"</type>" +
|
" <totalValue>" +
|
orderInfo.totalValue +
|
"</totalValue>" +
|
" <itemsWeight>" +
|
orderInfo.itemsWeight +
|
"</itemsWeight>" +
|
" <sender>" +
|
" <name>" +
|
orderInfo.sendername +
|
"</name>" +
|
" <postCode>" +
|
orderInfo.senderpostCode +
|
"</postCode>" +
|
" <phone>" +
|
orderInfo.senderphone +
|
"</phone>" +
|
" <mobile>" +
|
orderInfo.sendermobile +
|
"</mobile>" +
|
" <prov>" +
|
orderInfo.senderprov +
|
"</prov>" +
|
" <city>" +
|
sendercity +
|
"</city>" +
|
" <address>" +
|
orderInfo.senderaddress +
|
"</address>" +
|
" </sender>" +
|
" <receiver>" +
|
" <name>" +
|
orderInfo.name +
|
"</name>" +
|
" <postCode>" +
|
orderInfo.postCode +
|
"</postCode>" +
|
" <phone>" +
|
orderInfo.phone +
|
"</phone>" +
|
" <mobile>" +
|
orderInfo.mobile +
|
"</mobile>" +
|
" <prov>" +
|
orderInfo.prov +
|
"</prov>" +
|
" <city>" +
|
city +
|
"</city>" +
|
" <address>" +
|
orderInfo.address +
|
"</address>" +
|
" </receiver>" +
|
" <items>" +
|
items +
|
" </items>" +
|
"</RequestOrder>";
|
xmlBuilder = xmlBuilder.replace("&", "&");
|
// var orderMsg = "";
|
var md5 = crypto.createHash("md5");
|
var data_digest = md5.update(xmlBuilder + partnerID, "utf8").digest("base64");
|
let result = await this.ctx.curl(yT_WebService, {
|
method: "POST",
|
contentType: "application/x-www-form-urlencoded;charset=utf-8",
|
data: {
|
logistics_interface: xmlBuilder,
|
data_digest: data_digest,
|
clientId: clientId,
|
type: type
|
}
|
});
|
// result.data="";
|
let data = Buffer.from(result.data).toString();
|
ctx.logger.info("圆通获取单号xml返回信息-=======" + data);
|
//xml解析器
|
var xmlParser = new xml2js.Parser();
|
var success = "";
|
var mailNo = "";
|
var shortAddress = "";
|
var errorStr = "";
|
var errorcode = "";
|
await xmlParser.parseString(data, function (err, result) {
|
ctx.logger.info("圆通获取单号返回信息error-=======" + err);
|
ctx.logger.info("圆通获取单号返回信息josnResult-=======" + JSON.stringify(result));
|
success = result.Response.success[0];
|
if (success == "true") {
|
mailNo = result.Response.mailNo[0];
|
shortAddress = result.Response.distributeInfo[0].shortAddress[0];
|
} else {
|
errorStr = result.Response.reason[0];
|
errorcode = result.Response.code[0];
|
}
|
});
|
if (success == "true") {
|
await this.dbWrite
|
.createQueryBuilder(ExpressYTOrder, "t")
|
.update()
|
.set({
|
trackingNumber: mailNo,
|
mailNo: mailNo,
|
bigPen: shortAddress,
|
pushDate: new Date(),
|
interfaceStatusID: 3,
|
interfaceStatusText: "推送成功"
|
})
|
.where(`yTOrder_Id=:yTOrder_Id`, {
|
yTOrder_Id: orderInfo.yTOrder_Id
|
})
|
.execute();
|
// 更新销售单
|
await this.dbWrite
|
.createQueryBuilder(SaleOrder, "t")
|
.update()
|
.set({
|
expressCode: mailNo,
|
bigPen: shortAddress
|
})
|
.where(`order_Id=:order_Id and expressCode is null and expressCorpType=:expressCorpType`, {
|
order_Id: orderInfo.order_Id,
|
expressCorpType: 5
|
})
|
.execute();
|
let where = "order_Id=:order_Id";
|
var saleOrderInfo = await this.dbRead
|
.createQueryBuilder(SaleOrder, "t")
|
.where(where, {
|
order_Id: orderInfo.order_Id
|
})
|
.getOne();
|
// 记录销售单轨迹
|
if (saleOrderInfo) {
|
await ctx.service.outbound.orderHelper.setStatusHistory(saleOrderInfo.order_Id, saleOrderInfo.statusID, saleOrderInfo.statusID, "获取圆通快递单号", "快递单号:" + mailNo);
|
}
|
// await this.dbWrite
|
// .createQueryBuilder(TMSWayBill, "t")
|
// .update()
|
// .set({
|
// expressCode: mailNo,
|
// bigPen: shortAddress
|
// })
|
// .where(`wayBill_Id=:wayBill_Id and expressCode is null `, {
|
// wayBill_Id: orderInfo.order_Id
|
// })
|
// .execute();
|
|
// let where = "wayBill_Id=:wayBill_Id";
|
// var tmsWayBillInfo = await this.dbRead
|
// .createQueryBuilder(TMSWayBill, "t")
|
// .where(where, {
|
// wayBill_Id: orderInfo.order_Id
|
// })
|
// .getOne();
|
// if (tmsWayBillInfo) {
|
// await ctx.service.tms.wayBillHelper.setStatusHistory(tmsWayBillInfo, "获取快递号", "圆通单号" + mailNo);
|
// }
|
info.msg = "订单[" + orderInfo.orderCode + "]推送结果为成功。";
|
info.result = true;
|
} else {
|
info.result = false;
|
var orderMsg = "错误信息:" + errorStr + ",错误编号为" + errorcode;
|
info.msg = "订单[" + orderInfo.orderCode + "]获取结果:" + orderMsg;
|
await this.dbWrite
|
.createQueryBuilder(ExpressYTOrder, "t")
|
.update()
|
.set({
|
pushNum: pushNum,
|
remark: orderMsg
|
})
|
.where(`yTOrder_Id=:yTOrder_Id`, {
|
yTOrder_Id: orderInfo.yTOrder_Id
|
})
|
.execute();
|
}
|
} catch (error) {
|
info.msg = error.message;
|
info.result = false;
|
}
|
return info;
|
}
|
// #endregion
|
|
//#region 圆通运单获取路由 getRouteByYT
|
public async getRouteByYT(orderId): Promise<ResultInfo> {
|
let { ctx } = this;
|
let info: ResultInfo = {
|
result: false,
|
msg: undefined
|
};
|
try {
|
let orderInfo = await this.dbRead.findOne(ExpressYTOrder, {
|
yTOrder_Id: orderId
|
});
|
let baseInfo = await this.dbRead.findOne(ExpressYTBaseInfo, {
|
userProduct_Id: orderInfo.userProduct_Id,
|
apiName: '圆通走件流程查询接口'
|
});
|
// var yT_WebService = "http://MarketingInterface.yto.net.cn"; //请求地址
|
var yT_WebService = baseInfo.apiUrl; //请求地址
|
// var user_id = "AUOD2144"; //用户在开放平台注册时填写的客户标识
|
var app_key = baseInfo.app_key; //分配给用户的app_key "sF1Jzn"
|
var user_id = baseInfo.clientId; //用户在开放平台注册时填写的客户标识
|
//var app_key = baseInfo.partnerID; //分配给用户的app_key
|
var method = "yto.Marketing.WaybillTrace"; //分配给用户的方法名
|
var timestamp = moment(new Date()).format("YYYY-MM-DD HH:mm:ss"); //时间戳,格式为yyyy-MM-dd HH:mm:ss,例如2012-06-20 11:00:00
|
var v = "1.01"; //API协议的版本号
|
var format = "XML";
|
//var secret_Key = "ntdyg2"; //由开放平台分配给用户的Secret_Key,生成签名时使用
|
var secret_Key = baseInfo.partnerID; //由开放平台分配给用户的Secret_Key,生成签名时使用
|
var num = "1.0";
|
var formatInfo =
|
'<?xml version="' +
|
num +
|
'"?>' +
|
"<ufinterface>" +
|
"<Result>" +
|
"<WaybillCode>" +
|
"<Number>" +
|
orderInfo.trackingNumber +
|
"</Number>" +
|
"</WaybillCode>" +
|
"</Result>" +
|
"</ufinterface>";
|
var xml =
|
secret_Key +
|
"app_key" +
|
app_key +
|
"format" +
|
format +
|
"method" +
|
method +
|
"timestamp" +
|
timestamp +
|
"user_id" +
|
user_id +
|
"v" +
|
v +
|
"";
|
var md5 = crypto.createHash("md5");
|
var sign = md5
|
.update(xml)
|
.digest("hex")
|
.toUpperCase();
|
let result = await this.ctx.curl(yT_WebService, {
|
method: "POST",
|
contentType: "application/x-www-form-urlencoded;charset=utf-8",
|
data: {
|
sign: sign,
|
app_key: app_key,
|
format: format,
|
method: method,
|
timestamp: timestamp,
|
user_id: user_id,
|
v: v,
|
param: formatInfo
|
}
|
});
|
let data = Buffer.from(result.data).toString();
|
ctx.logger.info("圆通获取单号xml返回信息-=======" + data);
|
// data = "<?xml version='1.0'?><ufinterface> <Result> <WaybillProcessInfo> <Waybill_No>500121003301</Waybill_No> <Upload_Time>2015/5/5 19:34:55</Upload_Time> <ProcessInfo>北京市海淀区中关村公司 已揽收</ProcessInfo> </WaybillProcessInfo> <WaybillProcessInfo> <Waybill_No>500121003301</Waybill_No> <Upload_Time>2015/5/5 20:13:20</Upload_Time> <ProcessInfo>北京市海淀区中关村公司 已打包,发往下一站 济南转运中心</ProcessInfo> </WaybillProcessInfo> <WaybillProcessInfo> <Waybill_No>500121003301</Waybill_No> <Upload_Time>2015/5/6 10:21:10</Upload_Time> <ProcessInfo>济南转运中心公司 已发出,下一站 山东省济南市千佛山</ProcessInfo> </WaybillProcessInfo> <WaybillProcessInfo> <Waybill_No>500121003301</Waybill_No> <Upload_Time>2015/5/6 13:36:31</Upload_Time> <ProcessInfo>快件到达 山东省济南市千佛山公司</ProcessInfo> </WaybillProcessInfo> <WaybillProcessInfo> <Waybill_No>500121003301</Waybill_No> <Upload_Time>2015/5/6 13:41:55</Upload_Time> <ProcessInfo>山东省济南市千佛山公司 派件人: ***** 派件中 派件员电话1234567891</ProcessInfo> </WaybillProcessInfo> </Result> </ufinterface>";
|
var xmlParser = new xml2js.Parser();
|
var errorStr = "";
|
var success = true;
|
var nodeList = [];
|
await xmlParser.parseString(data, function (err, result) {
|
ctx.logger.info("圆通查询路由error-=======" + err);
|
ctx.logger.info("圆通查询路由josnResult-=======" + JSON.stringify(result));
|
var successStr = "";
|
if (result.Response) {
|
successStr = result.Response.Success[0];
|
}
|
if (successStr == "false") {
|
success = false;
|
errorStr = result.Response.reason[0];
|
} else {
|
success = true;
|
if (result.ufinterface) {
|
nodeList = result.ufinterface.Result[0].WaybillProcessInfo;
|
}
|
else {
|
success = false;
|
errorStr = "查询结果为空。";
|
}
|
}
|
});
|
var lastMsg = "";
|
if (success) {
|
var ytOrderRouteInfo = await this.dbRead.findOne(ExpressYTOrderRoute, {
|
where: { mailno: orderInfo.trackingNumber },
|
order: { orderRoute_Id: "DESC" }
|
});
|
for (var item of nodeList) {
|
var accept_time = item.Upload_Time[0];
|
var remark = item.ProcessInfo[0];
|
var mailno = item.Waybill_No[0];
|
var accept_timeDate = moment(accept_time);
|
if (lastMsg.indexOf("已签收") < 0) {
|
lastMsg = remark;
|
}
|
if (ytOrderRouteInfo && accept_timeDate <= moment(ytOrderRouteInfo.accept_time)) {
|
continue;
|
}
|
let routeInfo = new ExpressYTOrderRoute();
|
routeInfo.mailNo = mailno;
|
routeInfo.accept_time = moment(accept_time).toDate();
|
routeInfo.accept_address = remark;
|
routeInfo.yTOrder_Id = orderInfo.yTOrder_Id;
|
routeInfo.order_Id = orderInfo.order_Id;
|
await this.dbWrite.insert(ExpressYTOrderRoute, routeInfo);
|
}
|
info.msg = lastMsg;
|
info.result = true;
|
} else {
|
info.result = false;
|
var orderMsg = "错误信息:" + errorStr;
|
info.msg = "订单[" + orderInfo.orderCode + "]获取结果:" + orderMsg;
|
}
|
} catch (error) {
|
info.msg = error.message;
|
info.result = false;
|
}
|
return info;
|
}
|
// #endregion
|
}
|