//#region import
|
import BaseService from "../baseService";
|
import { TMSWayBill } from "../../entity/express/tms/tmsWayBill";
|
import { ResultInfo } from "../../public/commonInterface";
|
import { ExpressEMSOrder } from "../../entity/express/ems/expressEMSOrder";
|
import { ExpressEMSOrderRoute } from "../../entity/express/ems/expressEMSOrderRoute";
|
import moment = require("moment");
|
import { ExpressSFOrder } from "../../entity/express/sf/expressSFOrder";
|
import { ExpressSFOrderRoute } from "../../entity/express/sf/expressSFOrderRoute";
|
import { TMSWayBillTracking } from "../../entity/express/tms/tmsWayBillTracking";
|
import { ExpressKD100OrderRoute } from "../../entity/express/kd100/expressKD100OrderRoute";
|
import { Express100BaseInfo } from "../../entity/express/kd100/express100BaseInfo";
|
import { BaseExpressCorp } from "../../entity/basicInfo/base/baseExpressCorp";
|
import { ExpressSFBaseInfo } from "../../entity/express/sf/expressSFBaseInfo";
|
import * as fs from "fs";
|
import * as stream from "stream";
|
import * as crypto from "crypto";
|
import { TMSRouterTask } from "../../entity/express/tmstask/tmsRouterTask";
|
import { ExpressYTOrder } from "../../entity/express/yuantong/expressYTOrder";
|
import { ExpressQZPortOrder } from "../../entity/express/ldg/expressQZPortOrder";
|
import { ExpressZTOrder } from "../../entity/express/zhongtong/expressZTOrder";
|
//#endregion
|
|
/**
|
* 运单轨迹帮助类
|
*/
|
export default class RouterHelperService extends BaseService {
|
//#region isQianShou
|
/**
|
* 判断是否签收
|
* @param msg 路由内容
|
*/
|
public isQianShou(msg?: string) {
|
if (!msg) return false;
|
|
if (
|
msg.indexOf("已签收") >= 0 ||
|
msg.indexOf("收件人已取走邮件") >= 0 ||
|
msg.indexOf("投递员:*") >= 0 ||
|
msg.indexOf("失败签收") >= 0 ||
|
msg.indexOf("签收人") >= 0 ||
|
msg.indexOf("快件被快递员取出") >= 0 ||
|
msg.indexOf("安排投递") >= 0 ||
|
msg.indexOf("重新派送") >= 0 ||
|
msg.indexOf("代签收") >= 0 ||
|
//|| msg.indexOf("揽投部") >= 0
|
//|| msg.indexOf("投递组") >= 0
|
msg.indexOf("上门自提") >= 0 ||
|
msg.indexOf("收回人员") >= 0 ||
|
msg.indexOf("快件领取成功") >= 0 ||
|
msg.indexOf("快件已退回") >= 0 ||
|
msg.indexOf("快件作废") >= 0 ||
|
msg.indexOf("待自取") >= 0 ||
|
msg.indexOf("请及时取件") >= 0 ||
|
msg.indexOf("失败签收录入") >= 0 ||
|
msg.indexOf("派件中") >= 0 ||
|
msg.indexOf("已取走邮件") >= 0 ||
|
msg.indexOf("快件被退回") >= 0 ||
|
msg.indexOf("感谢使用菜鸟驿站") >= 0 ||
|
msg.indexOf("快件已暂存至") >= 0 ||
|
msg.indexOf("签收退回") >= 0 ||
|
msg.indexOf("已妥投") >= 0 ||
|
msg.indexOf("国内快递妥投") >= 0 ||
|
msg.indexOf("邮件投递到") >= 0 ||
|
msg.indexOf("妥投") >= 0 ||
|
(msg.indexOf("驿站") >= 0 && msg.indexOf("已到达") >= 0 && msg.indexOf("联系电话") >= 0) ||
|
(msg.indexOf("快件已暂存至") >= 0 && msg.indexOf("菜鸟驿站") >= 0) ||
|
(msg.indexOf("到达") >= 0 && msg.indexOf("投递组") >= 0) ||
|
(msg.indexOf("安排投递") >= 0 && msg.indexOf("投递员") >= 0) ||
|
(msg.indexOf("到达") >= 0 && msg.indexOf("营业部") >= 0) ||
|
(msg.indexOf("已接收") >= 0 && msg.indexOf("自提点") >= 0) ||
|
(msg.indexOf("快件已由") >= 0 && msg.indexOf("代收") >= 0)
|
) {
|
return true;
|
}
|
|
return false;
|
}
|
//#endregion
|
|
//#region getRouter
|
/**
|
* 获取运单轨迹
|
* @param waybill 运单信息
|
* @param isUseKuaiDi100 是否使用快递100
|
* @param addQingGuan 是否添加清关,默认为true
|
*/
|
public async getRouter(
|
waybill: TMSWayBill,
|
isUseKuaiDi100: boolean,
|
addQingGuan: boolean = true,
|
isRepeat: boolean = false
|
): Promise<ResultInfo> {
|
let { ctx } = this;
|
let info: ResultInfo = {
|
result: false,
|
msg: undefined
|
};
|
|
if (!waybill) {
|
info.result = false;
|
info.msg = "运单不存在";
|
return info;
|
}
|
if (waybill.orderStatus == "已签收" && !isRepeat) {
|
info.result = true;
|
info.msg = "已签收";
|
return info;
|
}
|
console.log(
|
`etRouter开始=${waybill.wayBillCode}, 快递公司${waybill.expressCorpName}, isUseKuaiDi100=${isUseKuaiDi100}, addQingGuan=${addQingGuan}`
|
);
|
try {
|
//#region 获取路由
|
if (waybill.expressCorpType == "3" && waybill.expressCorpName == "EMS标准") {
|
info.result = true;
|
|
//#region 通过宏远获取对应EMS标准运单路由
|
let EMSOrderInfo = await this.dbRead.findOne(ExpressEMSOrder, {
|
orderCode: waybill.wayBillCode
|
});
|
if (EMSOrderInfo != null) {
|
info = await this.ExpressHY_OrderRoute(waybill.wayBillCode);
|
if (info.result) {
|
// 清除订单所有路由然后重新写入
|
//ExpressEMS_OrderRouteRepository.Instance.Delete("EMSOrder_Id=" + EMSOrderInfo.EMSOrder_Id);
|
var orderInfo = await this.dbRead.findOne(ExpressEMSOrderRoute, {
|
where: { eMSOrder_Id: EMSOrderInfo.eMSOrder_Id },
|
order: { accept_time: "DESC" }
|
});
|
var lastMsg: string = "";
|
if (info.data && Array.isArray(info.data)) {
|
// 顺序排
|
let dataAsc = info.data.sort((a, b) => {
|
return a.updateTime > b.updateTime ? 1 : -1;
|
});
|
for (var item of dataAsc) {
|
var updateTime = moment(item.updateTime);
|
if (!lastMsg) {
|
lastMsg = item.action;
|
}
|
|
// 已经记录的不在记录
|
if (orderInfo != null) {
|
let accept_time = moment(orderInfo.accept_time);
|
if (updateTime <= accept_time) {
|
continue;
|
}
|
}
|
|
let routeInfo = new ExpressEMSOrderRoute();
|
routeInfo.mailno = EMSOrderInfo.mailno;
|
routeInfo.accept_time = item.updateTime;
|
routeInfo.accept_address = item.action;
|
routeInfo.eMSOrder_Id = EMSOrderInfo.eMSOrder_Id;
|
routeInfo.order_Id = 0;
|
await this.dbWrite.insert(ExpressEMSOrderRoute, routeInfo);
|
}
|
}
|
info.msg = lastMsg;
|
}
|
}
|
//#endregion
|
} else if (waybill.expressCorpType == "2" && waybill.expressCorpName == "顺丰快递") {
|
info.result = true;
|
|
//#region 通过宏远获取对应顺丰运单路由
|
let orderInfo = await this.dbRead.findOne(ExpressSFOrder, {
|
orderCode: waybill.wayBillCode,
|
expressCorpName: "顺丰快递"
|
});
|
if (orderInfo) {
|
info = await this.ExpressHY_OrderRoute(waybill.wayBillCode);
|
if (info.result) {
|
// 清除订单所有路由然后重新写入
|
//ExpressSF_OrderRouteRepository.Instance.Delete("SFOrder_Id=" + orderInfo.SFOrder_Id);
|
var sfOrderInfo = await this.dbRead.findOne(ExpressSFOrderRoute, {
|
where: { sFOrder_Id: orderInfo.sFOrder_Id },
|
order: { accept_time: "DESC" }
|
});
|
var lastMsg: string = "";
|
if (info.data && Array.isArray(info.data)) {
|
// 顺序排
|
let dataAsc = info.data.sort((a, b) => {
|
return a.updateTime > b.updateTime ? 1 : -1;
|
});
|
// 获得最后轨迹
|
if (dataAsc[dataAsc.length - 1]) {
|
lastMsg = dataAsc[dataAsc.length - 1].action;
|
}
|
for (var item of dataAsc) {
|
var updateTime = moment(item.updateTime);
|
|
// 已经记录的不在记录
|
if (sfOrderInfo != null) {
|
let accept_time = moment(sfOrderInfo.accept_time);
|
if (updateTime <= accept_time) {
|
continue;
|
}
|
}
|
|
let routeInfo = new ExpressSFOrderRoute();
|
routeInfo.mailno = orderInfo.mailno;
|
routeInfo.accept_time = item.updateTime;
|
routeInfo.accept_address = item.action;
|
routeInfo.sFOrder_Id = orderInfo.sFOrder_Id;
|
routeInfo.order_Id = waybill.wayBill_Id;
|
routeInfo.orderid = orderInfo.mailno;
|
await this.dbWrite.insert(ExpressSFOrderRoute, routeInfo);
|
}
|
}
|
info.msg = lastMsg;
|
}
|
}
|
//#endregion
|
} else if (waybill.expressCorpType == "5" && waybill.expressCorpName == "圆通") {
|
info.result = true;
|
|
//#region 通过.net圆通接口获取运单路由
|
// if (waybill) {
|
// info.msg = await this.netGetRouter(waybill.wayBillCode);
|
// }
|
|
//#region 通过node圆通接口获取运单路由
|
let ytOrderInfo = await this.dbRead.findOne(ExpressYTOrder, {
|
orderCode: waybill.wayBillCode
|
});
|
if (ytOrderInfo) {
|
var ytResultInfo = await ctx.service.express.yuantongHelper.getRouteByYT(ytOrderInfo.yTOrder_Id);
|
info.msg = ytResultInfo.msg;
|
}
|
//#endregion
|
} else if (waybill.expressCorpType == "18" && waybill.expressCorpName == "福州EMS") {
|
info.result = true;
|
|
//#region 通过福州EMS接口获取福州EMS运单路由
|
info.msg = await this.expressEMS_OrderRoute(
|
waybill.expressCode,
|
waybill.expressCorp_Id,
|
waybill.expressCorpName
|
);
|
//#endregion
|
} else if (waybill.expressCorpName == "邮政小包" && isUseKuaiDi100) {
|
info.result = true;
|
|
//#region 通过kd100获取邮政小包运单路由
|
info.msg = await this.expressKD100_OrderRoute_startNewByKD(
|
waybill.expressCode,
|
waybill.expressCorp_Id,
|
waybill.expressCorpName
|
);
|
//#endregion
|
} else if (waybill.expressCorpType == "19" && waybill.expressCorpName == "泉州顺丰") {
|
info.result = true;
|
// info.msg = await this.netGetRouter(waybill.wayBillCode);
|
let where = "orderCode=:orderCode and expressCorpName='泉州顺丰'";
|
var qzSfInfo = await this.dbRead
|
.createQueryBuilder(ExpressSFOrder, "t")
|
.where(where, {
|
orderCode: waybill.wayBillCode
|
})
|
.getOne();
|
var sfResultInfo = await ctx.service.express.shunfengHelper.getRouteByFQ(qzSfInfo.sFOrder_Id);
|
info.msg = sfResultInfo.msg;
|
} else if (waybill.expressCorpName == "广州EMS" && isUseKuaiDi100) {
|
info.result = true;
|
//#region 通过kd100获取广州EMS运单路由
|
info.msg = await this.expressKD100_OrderRoute_startNewByKD(
|
waybill.expressCode,
|
waybill.expressCorp_Id,
|
waybill.expressCorpName
|
);
|
//#endregion
|
} else if (waybill.expressCorpName == "厦门EMS" && isUseKuaiDi100) {
|
info.result = true;
|
//#region 通过kd100获取广州EMS运单路由
|
info.msg = await this.expressKD100_OrderRoute_startNewByKD(
|
waybill.expressCode,
|
waybill.expressCorp_Id,
|
waybill.expressCorpName
|
);
|
//#endregion
|
} else if (waybill.expressCorpName == "陆地港顺丰") {
|
//#region
|
info.result = true;
|
info.msg = await this.ctx.service.express.ldgHelper.getRoute(waybill.expressCode);
|
//#endregion
|
} else if (waybill.expressCorpName == "陆地港圆通") {
|
//#region
|
info.result = true;
|
var ldgResultInfo = await this.ctx.service.express.ldgHelper.getRouteByYT(waybill.expressCode);
|
info.msg = ldgResultInfo.msg;
|
//#endregion
|
} else {
|
info.result = true;
|
info.msg = "没有可用快递接口";
|
}
|
//#endregion
|
|
var wayBillCode = waybill.wayBillCode;
|
//#region 新增清关记录
|
if (addQingGuan) {
|
var expressCorpName = waybill.expressCorpName;
|
var sql = "";
|
if (expressCorpName == "EMS标准") {
|
sql = `SELECT accept_address as AcceptAddress, accept_time AS AcceptTime, '快递' AS StatusType
|
FROM dbo.ExpressEMS_OrderRoute R with(nolock)
|
WHERE R.mailno='${waybill.expressCode}'`;
|
} else if (expressCorpName == "顺丰快递" || expressCorpName == "泉州顺丰") {
|
sql = `SELECT accept_address as AcceptAddress, accept_time AS AcceptTime, '快递' AS StatusType
|
FROM dbo.ExpressSF_OrderRoute R with(nolock)
|
WHERE R.mailno='${waybill.expressCode}'`;
|
} else if (
|
expressCorpName == "福州EMS" ||
|
expressCorpName == "邮政小包" ||
|
expressCorpName === "广州EMS" ||
|
expressCorpName === "厦门EMS"
|
) {
|
sql = `SELECT AcceptAddress as AcceptAddress, AcceptTime AS AcceptTime, '快递' AS StatusType
|
FROM dbo.ExpressKD100_OrderRoute R with(nolock)
|
WHERE R.TrackNo='${waybill.expressCode}'`;
|
} else if (expressCorpName == "圆通") {
|
sql = `SELECT accept_address as AcceptAddress, accept_time AS AcceptTime, '快递' AS StatusType
|
FROM dbo.ExpressYT_OrderRoute R with(nolock)
|
WHERE R.mailNo='${waybill.expressCode}'`;
|
} else if (expressCorpName == "陆地港圆通" || expressCorpName == "陆地港顺丰") {
|
sql = `SELECT acceptAddress as AcceptAddress, acceptTime AS AcceptTime, '快递' AS StatusType
|
FROM dbo.ExpressQZPort_OrderRoute R with(nolock)
|
WHERE R.mailNo='${waybill.expressCode}'`;
|
} else {
|
sql = `SELECT AcceptAddress+'-1' AS AcceptAddress, AcceptTime, '快递' AS StatusType
|
FROM dbo.vExpress_OrderRoute R with(nolock)
|
WHERE R.ExpressCode='${waybill.expressCode}'`;
|
}
|
|
//没有国内快递轨迹
|
let existRouter = await this.dbRead.query(sql);
|
if (!existRouter.length) {
|
var where = `wayBillCode='${wayBillCode}' And ToStatus='清关中'
|
And (CreateDate>=convert(date, getdate()) And CreateDate<DateAdd(day, 1, convert(date, getdate())))`;
|
var trackingInfo = await this.dbRead.findOne(TMSWayBillTracking, {
|
where: where
|
});
|
|
var qgTrackingInfo = await this.dbRead.findOne(TMSWayBillTracking, {
|
wayBillCode: wayBillCode,
|
toStatus: "清关中"
|
});
|
console.log("!trackingInfo=", !trackingInfo, "qgTrackingInfo=", !!qgTrackingInfo);
|
//没有快递轨迹时,每天增加一条清关中记录
|
if (!trackingInfo && qgTrackingInfo) {
|
this.service.tms.wayBillHelper.setStatusHistory(waybill, "清关中", "清关中", "清关中");
|
}
|
}
|
}
|
//#endregion
|
} catch (ex) {
|
console.log(waybill.wayBillCode + "异常=" + ex.message);
|
}
|
|
return info;
|
}
|
//#endregion
|
|
//#region 轮询获取所有运单轨迹
|
/// <summary>
|
/// 获得单条路由
|
/// </summary>
|
/// <param name="oddRow">奇数行</param>
|
/// <returns></returns>
|
public async getAllRouter(modeNum: number) {
|
var where = "taskStatus IN('排队中') And routerTask_Id%5=0";
|
if (modeNum == 1) {
|
where = "taskStatus IN('排队中') And routerTask_Id%5=1";
|
} else if (modeNum == 2) {
|
where = "taskStatus IN('排队中') And routerTask_Id%5=2";
|
} else if (modeNum == 3) {
|
where = "taskStatus IN('排队中') And routerTask_Id%5=3";
|
} else if (modeNum == 4) {
|
where = "taskStatus IN('排队中') And routerTask_Id%5=4";
|
}
|
var info = this.doAllRouter(where);
|
|
return info;
|
}
|
//#endregion
|
|
//#region doAllRouter
|
public async doAllRouter(where: string, isRepeat: boolean = false) {
|
let { ctx } = this;
|
var beginTime = new Date();
|
var taskList = await this.dbRead
|
.createQueryBuilder(TMSRouterTask, "t")
|
.where(where)
|
.orderBy("routerTask_Id")
|
.take(50)
|
.getMany();
|
var idList = taskList.map(s => s.routerTask_Id);
|
if (!idList.length) {
|
console.log("获取路由,没有可执行的作业数据", where);
|
return;
|
}
|
await this.dbWrite.update(TMSRouterTask, idList, {
|
taskStatus: "进行中"
|
});
|
|
for (var taskInfo of taskList) {
|
try {
|
console.log("开始获取路由", taskInfo.wayBillCode);
|
var wayBill = await this.dbRead.findOne(TMSWayBill, {
|
wayBillCode: taskInfo.wayBillCode
|
});
|
|
// 运单不存在
|
if (!wayBill) {
|
console.log(taskInfo.wayBillCode + "运单不存在");
|
taskInfo.taskStatus = "执行完成";
|
taskInfo.actionCount += 1;
|
taskInfo.lastActionTime = new Date();
|
await this.dbWrite.save(taskInfo);
|
continue;
|
}
|
|
var isKuaiDi100 = false;
|
if (taskInfo.actionCount >= 2) isKuaiDi100 = true;
|
var result = await this.getRouter(wayBill, isKuaiDi100, true, isRepeat);
|
var end = new Date();
|
var span = moment(end).diff(moment(beginTime), "seconds");
|
console.log(taskInfo.wayBillCode + "获得单条路由秒数=" + span);
|
|
taskInfo.taskStatus = "执行完成";
|
taskInfo.actionCount += 1;
|
taskInfo.lastActionTime = new Date();
|
if (result.result && result.msg) {
|
if (this.isQianShou(result.msg)) {
|
await this.dbWrite.update(
|
TMSWayBill,
|
{
|
wayBillCode: wayBill.wayBillCode
|
},
|
{
|
orderStatus: "已签收"
|
}
|
);
|
await ctx.service.tms.wayBillHelper.setStatusHistory(wayBill, "快递轨迹", "已签收");
|
|
taskInfo.orderStatus = "已签收";
|
}
|
taskInfo.remark = result.msg;
|
} else {
|
taskInfo.remark = wayBill.orderStatus;
|
}
|
|
await this.dbWrite.save(taskInfo);
|
} catch (error) {
|
console.log("获取路由错误:", error.message);
|
}
|
}
|
var endTime = new Date();
|
var span = moment(endTime).diff(moment(beginTime), "seconds");
|
console.log("执行完成,总耗时=" + span + ", idList=" + idList);
|
}
|
//#endregion
|
|
//#region ExpressHY_OrderRoute
|
/**
|
* 通过宏远接口获取运单
|
* @param ordernoOid 运单号
|
*/
|
public async ExpressHY_OrderRoute(ordernoOid: string): Promise<ResultInfo> {
|
let info: ResultInfo = {
|
result: false
|
};
|
let { ctx } = this;
|
let enteCode = "20190415155054514";
|
let timestamp = moment(new Date()).format("YYYY-MM-DD HH:mm:ss");
|
var md5 = crypto.createHash("md5");
|
let sign = md5.update("enteCode=" + enteCode + "&mailNo=" + ordernoOid + "×tamp=" + timestamp).digest("hex");
|
|
info.result = false;
|
let url = "http://tms.ubonex.com/website/getPekkjTrace.do";
|
|
let json = {
|
version: "1.0",
|
enteCode: enteCode,
|
timestamp: timestamp,
|
sign: sign,
|
data: {
|
mailNo: ordernoOid,
|
queryType: "0"
|
},
|
timeout: [30000, 30000]
|
};
|
|
const result = await ctx.curl(url, {
|
// 必须指定 method
|
method: "POST",
|
// 通过 contentType 告诉 HttpClient 以 JSON 格式发送
|
contentType: "json",
|
data: json,
|
// 明确告诉 HttpClient 以 JSON 格式处理返回的响应 body
|
dataType: "json"
|
});
|
|
if (result.data.retCode == "000000") {
|
let isHave = result.data.retMsg.trackList.length > 0;
|
if (!isHave) {
|
info.msg = "订单[" + ordernoOid + "]未获取到路由信息。";
|
info.result = false;
|
} else {
|
info.msg = "订单[" + ordernoOid + "]获取路由成功。";
|
info.data = result.data.retMsg.trackList;
|
info.result = true;
|
}
|
} else {
|
info.msg = "订单[" + ordernoOid + "]获取路由失败:" + result.data.retMsg;
|
info.result = false;
|
}
|
|
return info;
|
}
|
//#endregion
|
|
//#region expressEMS_OrderRoute
|
/**
|
* 获得EMS运单号轨迹
|
* @param trackingNumber 运单号
|
*/
|
public async expressEMS_OrderRoute(
|
trackingNumber: string,
|
expressCorp_Id: number,
|
expressCorpName: string
|
): Promise<string> {
|
let { ctx } = this;
|
|
try {
|
let url = "http://211.156.193.140:8000/cotrackapi/api/track/mail/" + trackingNumber;
|
|
const dynData = await ctx.curl(url, {
|
headers: {
|
version: "ems_track_cn_1.0",
|
authenticate: "97c6b994123247f7b2a66f3cc045ff9a"
|
},
|
// 必须指定 method
|
method: "GET",
|
// 通过 contentType 告诉 HttpClient 以 JSON 格式发送
|
contentType: "json",
|
// 明确告诉 HttpClient 以 JSON 格式处理返回的响应 body
|
dataType: "json"
|
});
|
|
var lastMsg = "";
|
var routeList = await this.dbRead.find(ExpressKD100OrderRoute, {
|
where: {
|
trackNo: trackingNumber
|
}
|
});
|
|
for (var item of dynData.data.traces) {
|
let routeInfo = routeList.find(_item => _item.acceptAddress.indexOf(item.remark) >= 0);
|
if (!routeInfo) routeInfo = new ExpressKD100OrderRoute();
|
|
routeInfo.acceptAddress = item.acceptAddress + item.remark;
|
routeInfo.acceptTime = item.acceptTime;
|
routeInfo.createDate = new Date();
|
routeInfo.createID = 1;
|
routeInfo.creator = "api";
|
routeInfo.expressCorp_Id = expressCorp_Id;
|
routeInfo.expressCorpName = expressCorpName;
|
routeInfo.trackNo = trackingNumber;
|
routeInfo.userProduct_Id = 1007;
|
routeInfo.platUser_Id = 1;
|
if (!(routeInfo.orderRout_Id > 0)) {
|
await this.dbWrite.insert(ExpressKD100OrderRoute, routeInfo);
|
}
|
if (lastMsg.indexOf("已签收") < 0) {
|
lastMsg = item.acceptAddress + item.remark;
|
}
|
}
|
return lastMsg;
|
} catch (e) {
|
return e.message;
|
}
|
}
|
//#endregion
|
|
//#region expressKD100_OrderRoute_startNewByKD
|
/**
|
* 快递100接口
|
* @param trackingNumber 运单号
|
* @param expressCorp_Id 快递ID
|
* @param expressCorpName 快递名称
|
*/
|
public async expressKD100_OrderRoute_startNewByKD(
|
trackingNumber: string,
|
expressCorp_Id: number,
|
expressCorpName: string
|
) {
|
try {
|
console.log(
|
"快递100获取路由",
|
"trackingNumber=" + trackingNumber,
|
"expressCorp_Id=" + expressCorp_Id,
|
"expressCorpName=" + expressCorpName
|
);
|
let { ctx } = this;
|
let expressInfo = await this.dbRead.findOne(Express100BaseInfo, {
|
where: { baseInfoType: 1, userProduct_Id: 1007 }
|
});
|
let url = "";
|
let customer = ""; //"FFC62E843C3FC124E40D5BFAEB86E30F";
|
let key = ""; //"BrKpTKzm2848";
|
if (expressInfo) {
|
url = expressInfo.apiUrl || "";
|
customer = expressInfo.clientCode || ""; //"FFC62E843C3FC124E40D5BFAEB86E30F";
|
key = expressInfo.verifyCode || ""; //"BrKpTKzm2848";
|
}
|
let corpInfo = await this.dbRead.findOne(BaseExpressCorp, { expressCorp_Id: expressCorp_Id });
|
let customerCode: string | undefined;
|
if (corpInfo) {
|
customerCode = corpInfo.customerCode;
|
}
|
//参数
|
let str = trackingNumber.trim();
|
let param = '{"com":"' + customerCode + '","num":"' + str + '","from":"","to":""}';
|
var md5 = crypto.createHash("md5");
|
let sign = md5
|
.update(param + key + customer)
|
.digest("hex")
|
.toUpperCase();
|
|
const dataResult = await ctx.curl(url, {
|
// 必须指定 method
|
method: "POST",
|
contentType: "application/x-www-form-urlencoded",
|
data: {
|
param: param,
|
customer: customer,
|
sign: sign
|
}
|
});
|
|
let lastMsg = "";
|
let data = Buffer.from(dataResult.data).toString();
|
let dataJson = JSON.parse(data);
|
console.log("快递单号:", trackingNumber, "快递100获取数据:", data);
|
|
if (dataJson.status == "200") {
|
var routeList = await this.dbRead.find(ExpressKD100OrderRoute, {
|
trackNo: trackingNumber
|
});
|
for (let dataInfo of dataJson.data) {
|
let routeInfo = routeList.find(
|
item =>
|
item.acceptAddress === dataInfo.context &&
|
moment(item.acceptTime).format("YYYY-MM-DD HH:mm:ss") == dataInfo.time
|
);
|
if (routeInfo == null) routeInfo = new ExpressKD100OrderRoute();
|
|
routeInfo.acceptAddress = dataInfo.context;
|
routeInfo.acceptTime = dataInfo.time;
|
routeInfo.createDate = new Date();
|
routeInfo.createID = 1;
|
routeInfo.creator = "api";
|
routeInfo.expressCorp_Id = expressCorp_Id;
|
routeInfo.expressCorpName = expressCorpName;
|
routeInfo.trackNo = trackingNumber;
|
routeInfo.userProduct_Id = 1007;
|
routeInfo.platUser_Id = 1;
|
if (!routeInfo.orderRout_Id) {
|
await this.dbWrite.insert(ExpressKD100OrderRoute, routeInfo);
|
}
|
// 取第一条
|
if (!lastMsg || (routeInfo.acceptAddress || "").indexOf("已签收") >= 0) {
|
lastMsg = routeInfo.acceptAddress || "";
|
}
|
}
|
} else {
|
console.log("快递100未获取到数据:param=", param, "lastMsg=", lastMsg);
|
lastMsg = dataJson.message;
|
}
|
return lastMsg;
|
} catch (error) {
|
console.log("快递单号:", trackingNumber, "快递100获取数据错误:", error.message);
|
return error.message;
|
}
|
}
|
//#endregion
|
|
//#region netGetRouter
|
/**
|
* 通过.net获取快递路由
|
* @param wayBillCode 运单号
|
*/
|
public async netGetRouter(wayBillCode: string) {
|
let { ctx } = this;
|
|
// let url = "http://transport-api.yrt.cn/api/open/getRouter";
|
let url = "http://baidu.auodexpress.com/api/open/getRouter";
|
const dataResult = await ctx.curl(url, {
|
data: {
|
code: wayBillCode
|
},
|
method: "POST",
|
contentType: "json",
|
dataType: "json",
|
timeout: [30000, 30000]
|
});
|
|
return dataResult.data.msg;
|
}
|
//#endregion
|
|
//#region expressHY_OrderRouteByYT
|
/**
|
* 获得圆通运单号轨迹 - 暂未调通
|
* @param trackingNumber 运单号
|
*/
|
public async expressHY_OrderRouteByYT(trackingNumber: string): Promise<string> {
|
let { ctx } = this;
|
let url = "http://MarketingInterface.yto.net.cn"; //请求地址
|
let user_id = "AUOD2144"; //用户在开放平台注册时填写的客户标识
|
let app_key = "cKbkXv"; //分配给用户的app_key
|
let method = "yto.Marketing.WaybillTrace"; //分配给用户的方法名
|
let timestamp = moment(new Date()).format("YYYY-MM-DD HH:mm:ss");
|
let v = "1.01"; //API协议的版本号
|
let format = "XML";
|
let Secret_Key = "ntdyg2"; //由开放平台分配给用户的Secret_Key,生成签名时使用
|
let Num = "1.0";
|
let formatInfo =
|
'<?xml version="' +
|
Num +
|
'"?>' +
|
"<ufinterface>" +
|
"<result>" +
|
"<WaybillCode>" +
|
"<Number>" +
|
trackingNumber +
|
"</Number>" +
|
"</WaybillCode>" +
|
"</result>" +
|
"</ufinterface>";
|
let Xml =
|
Secret_Key +
|
"app_key" +
|
app_key +
|
"format" +
|
format +
|
"method" +
|
method +
|
"timestamp" +
|
timestamp +
|
"user_id" +
|
user_id +
|
"v" +
|
v +
|
"";
|
var md5 = crypto.createHash("md5");
|
let sign = md5
|
.update(Xml)
|
.digest("hex")
|
.toUpperCase();
|
let XmlString =
|
"sign=" +
|
sign +
|
"&app_key=" +
|
app_key +
|
"&format=" +
|
format +
|
"&method=" +
|
method +
|
"×tamp=" +
|
timestamp +
|
"&user_id=" +
|
user_id +
|
"&v=" +
|
v +
|
"¶m=" +
|
formatInfo +
|
"";
|
console.log("expressHY_OrderRouteByYT", XmlString);
|
let c = fs.createReadStream("d:\\a.txt");
|
const dataResult: any = await ctx.curl(url, {
|
// 必须指定 method
|
method: "POST",
|
contentType: "application/x-www-form-urlencoded",
|
stream: c,
|
timeout: [30000, 30000]
|
});
|
c.close();
|
let data = "";
|
if (dataResult.status == 200) {
|
let b = Buffer.from(dataResult.res.data);
|
data = b.toString();
|
}
|
|
return data;
|
}
|
//#endregion
|
|
//#region expressSF_OrderRouteFQ
|
/**
|
* 通过丰桥获取泉州顺丰运单路由 - 暂未调通
|
* @param sFOrder_Id 数据ID
|
*/
|
public async expressSF_OrderRouteFQ(sFOrder_Id: number) {
|
let { ctx } = this;
|
try {
|
let orderInfo = await this.dbRead.findOne(ExpressSFOrder, {
|
sFOrder_Id: sFOrder_Id
|
});
|
if (!orderInfo) {
|
return "";
|
}
|
|
if (orderInfo.expressCorpName != "泉州顺丰") {
|
return "错误信息:只有泉州顺丰才可以通过丰桥获取路由轨迹。";
|
}
|
if (!orderInfo.mailno) {
|
return "错误信息:未获取快递单号不允许获取路由轨迹。";
|
}
|
// let name: string | undefined;
|
// let expressSF_OrderListInfo = await this.dbRead.findOne(ExpressSFOrderList, { sFOrder_Id: sFOrder_Id });
|
// if (expressSF_OrderListInfo != null) {
|
// name = expressSF_OrderListInfo.name;
|
// }
|
|
let ExpressSF_BaseInfo = await this.dbRead.findOne(ExpressSFBaseInfo, {
|
baseInfo_Id: 20000
|
});
|
let msg = "";
|
let Checkword = "";
|
let verifyCode = "";
|
let clientCode = "";
|
let url = ""; //地址
|
if (ExpressSF_BaseInfo) {
|
Checkword = ExpressSF_BaseInfo.verifyCode;
|
clientCode = ExpressSF_BaseInfo.clientCode;
|
url = ExpressSF_BaseInfo.apiUrl; //地址
|
}
|
|
let xml = `<?xml version=""1.0"" encoding=""utf-8""?>
|
<Request service='RouteService' lang='zh-CN'><Head>${clientCode}</Head>
|
<Body><RouteRequest tracking_type='2' method_type='1' tracking_number='${orderInfo.orderCode}'/>
|
</Body></Request>`;
|
|
var md5 = crypto.createHash("md5");
|
verifyCode = md5.update(xml + Checkword).digest("hex");
|
verifyCode = Buffer.from(verifyCode).toString("base64");
|
|
let bufferToStream = function (buffer) {
|
let _stream = new stream.Duplex();
|
_stream.push(buffer);
|
_stream.push(null);
|
return _stream;
|
};
|
let postData = `xml=${xml}&verifyCode=${verifyCode}`;
|
let _stream = bufferToStream(Buffer.from(postData));
|
const result: any = await ctx.curl(url, {
|
// 必须指定 method
|
method: "POST",
|
contentType: "application/x-www-form-urlencoded",
|
stream: _stream
|
});
|
|
let Head = "OK";
|
let orderMsg = "";
|
if (Head == "OK") {
|
var sfOrderInfo = await this.dbRead.findOne(ExpressSFOrderRoute, {
|
where: { sFOrder_Id: orderInfo.sFOrder_Id },
|
order: { accept_time: "DESC" }
|
});
|
let nodeList = [];
|
for (let node of nodeList) {
|
let accept_time = node;
|
let remark = "";
|
msg = remark;
|
var accept_timeDate = moment(accept_time);
|
// 已经记录的不再记录
|
if (sfOrderInfo && accept_timeDate <= moment(sfOrderInfo.accept_time)) {
|
continue;
|
}
|
let routeInfo = new ExpressSFOrderRoute();
|
routeInfo.mailno = orderInfo.mailno;
|
routeInfo.accept_time = moment(accept_time).toDate();
|
routeInfo.accept_address = remark;
|
routeInfo.sFOrder_Id = orderInfo.sFOrder_Id;
|
await this.dbWrite.insert(ExpressSFOrderRoute, routeInfo);
|
}
|
} else {
|
let ERROR = result.ERROR;
|
let code = result.code;
|
orderMsg = "错误信息:" + ERROR + ",错误编号为" + code;
|
msg = "订单[" + orderInfo.orderCode + "]取消结果," + orderMsg + "<br/>";
|
}
|
return msg;
|
} catch (ex) {
|
return ex.message;
|
}
|
}
|
|
//#endregion
|
|
//#region getFQExpressCodeByNode
|
/**
|
* 通过丰桥轮询获取所有泉州顺丰快递单号(node)
|
*/
|
public async getFQExpressCodeByNode(modeNum): Promise<ResultInfo> {
|
let { ctx } = this;
|
let info: ResultInfo = {
|
result: false,
|
msg: undefined,
|
dynamic: null
|
};
|
try {
|
var beginTime = new Date();
|
var where = "InterfaceStatusID=1 and expressCorpName='泉州顺丰' And SFOrder_Id%5=0";
|
if (modeNum == 1) {
|
where = "InterfaceStatusID=1 and expressCorpName='泉州顺丰' And SFOrder_Id%5=1";
|
} else if (modeNum == 2) {
|
where = "InterfaceStatusID=1 and expressCorpName='泉州顺丰' And SFOrder_Id%5=2";
|
} else if (modeNum == 3) {
|
where = "InterfaceStatusID=1 and expressCorpName='泉州顺丰' And SFOrder_Id%5=3";
|
} else if (modeNum == 4) {
|
where = "InterfaceStatusID=1 and expressCorpName='泉州顺丰' And SFOrder_Id%5=4";
|
}
|
var expressSFOrderList = await this.dbRead
|
.createQueryBuilder(ExpressSFOrder, "t")
|
.where(where)
|
.orderBy("sFOrder_Id")
|
.take(10)
|
.getRawMany();
|
// var index = 0;
|
for (let item of expressSFOrderList) {
|
// index++;
|
ctx.service.express.shunfengHelper.pushOrderbyFQ(item.sFOrder_Id);
|
}
|
var endTime = new Date();
|
var span = moment(endTime).diff(moment(beginTime), "seconds");
|
info.result = true;
|
info.msg = modeNum + "==执行完成,执行单量:" + expressSFOrderList.length + ",总耗时=" + span + "s";
|
} catch (ex) {
|
info.result = false;
|
info.msg = ex.message;
|
}
|
return info;
|
}
|
//#endregion
|
|
//#region getLdgExpressCodeByNode
|
/**
|
* 通过陆地港获取所有泉州顺丰、圆通快递单号(node)
|
*/
|
public async getLdgExpressCodeByNode(): Promise<ResultInfo> {
|
let { ctx } = this;
|
let info: ResultInfo = {
|
result: false,
|
msg: undefined,
|
dynamic: null
|
};
|
try {
|
var beginTime = new Date();
|
var where = "InterfaceStatusID=1 and (PushNum IS NULL OR PushNum<5)";
|
|
var expressQZPortOrderList = await this.dbRead
|
.createQueryBuilder(ExpressQZPortOrder, "t")
|
.where(where)
|
.take(50)
|
.getMany();
|
// var index = 0;
|
for (let item of expressQZPortOrderList) {
|
// index++;
|
await ctx.service.express.ldgHelper.pushOrderByLgd(item.qZPortOrder_Id);
|
}
|
var endTime = new Date();
|
var span = moment(endTime).diff(moment(beginTime), "seconds");
|
info.result = true;
|
info.msg = "==执行完成,执行单量:" + expressQZPortOrderList.length + ",总耗时=" + span + "s";
|
} catch (ex) {
|
info.result = false;
|
info.msg = ex.message;
|
}
|
return info;
|
}
|
//#endregion
|
|
//#region autoGetSortingCode
|
/**
|
* 自动获取分拣码
|
*/
|
public async autoGetSortingCode(): Promise<ResultInfo> {
|
let { ctx } = this;
|
let info: ResultInfo = {
|
result: false,
|
msg: undefined,
|
dynamic: null
|
};
|
try {
|
var beginTime = new Date();
|
var where = ` CreateDate>=DATEADD(day, -20, getdate())
|
AND ExpressCorpType=11
|
AND ISNULL(ApiSendCount,0) <=5
|
AND ExpressCode IS NOT NULL
|
AND (BigPen IS NULL or BigPen='(未知格口)')`;
|
|
var wayBillList = await this.dbRead
|
.createQueryBuilder(TMSWayBill, "t")
|
.where(where)
|
.take(50)
|
.getMany();
|
// var msg = "";
|
for (let wayBillInfo of wayBillList) {
|
let resultInfo = await ctx.service.express.sortingCodeHelper.getSortingCode(wayBillInfo.wayBill_Id); // = SortingCodeService.GetSortingCode(wayBillInfo);
|
if (resultInfo.result) {
|
var sortingCode = resultInfo.dynamic;
|
wayBillInfo.bigPen = sortingCode.data.SortingCode;
|
|
// msg += wayBillInfo.wayBillCode + "获取分拣码完成。";
|
} else {
|
// msg += wayBillInfo.wayBillCode + "获取分拣码失败。";
|
}
|
if (wayBillInfo.apiSendCount == null) {
|
wayBillInfo.apiSendCount = 1;
|
} else {
|
wayBillInfo.apiSendCount += 1;
|
}
|
await this.dbWrite.update(TMSWayBill, wayBillInfo.wayBill_Id, {
|
apiSendCount: wayBillInfo.apiSendCount,
|
bigPen: wayBillInfo.bigPen
|
});
|
}
|
|
var endTime = new Date();
|
var span = moment(endTime).diff(moment(beginTime), "seconds");
|
info.result = true;
|
info.msg = "自动获取分拣码执行完成,执行单量:" + wayBillList.length + ",总耗时=" + span + "s";
|
} catch (ex) {
|
info.result = false;
|
info.msg = "自动获取分拣码错误:" + ex.message;
|
}
|
return info;
|
}
|
//#endregion
|
|
//#region 自动获取快递单号 autoGetExpressCodeByNode
|
/**
|
* 自动获取快递单号(node)
|
*/
|
public async autoGetExpressCodeByNode() {
|
let { ctx } = this;
|
let msgList = [];
|
let beginTime = new Date();
|
let count = 0;
|
try {
|
// 北京-顺丰
|
let expressSFList = await this.dbRead
|
.createQueryBuilder(ExpressSFOrder, "t")
|
.where(`InterfaceStatusID=1 and expressCorpName='顺丰快递' and (PushNum IS NULL OR PushNum<5)`)
|
.take(100)
|
.getMany();
|
for (let item of expressSFList) {
|
await ctx.service.express.shunfengHelper.pushOrderByHY(item.sFOrder_Id, 2);
|
}
|
count = expressSFList.length;
|
} catch (ex) {
|
msgList.push("北京顺丰错误=" + ex.message);
|
}
|
let endTime = new Date();
|
let span = moment(endTime).diff(moment(beginTime), "seconds");
|
msgList.push("北京顺丰执行完成,执行单量:" + count + ",总耗时=" + span + "s");
|
|
beginTime = new Date();
|
try {
|
// EMS
|
let expressEMSList = await this.dbRead
|
.createQueryBuilder(ExpressEMSOrder, "t")
|
.where(`InterfaceStatusID=1 and (PushNum IS NULL OR PushNum<5)`)
|
.take(100)
|
.getMany();
|
for (let item of expressEMSList) {
|
await ctx.service.express.emsHelper.pushOrderByHY(item.eMSOrder_Id, 2);
|
}
|
count = expressEMSList.length;
|
} catch (ex) {
|
msgList.push("EMS错误=" + ex.message);
|
}
|
endTime = new Date();
|
span = moment(endTime).diff(moment(beginTime), "seconds");
|
msgList.push("EMS执行完成,执行单量:" + count + ",总耗时=" + span + "s");
|
|
// 圆通
|
beginTime = new Date();
|
try {
|
let expressYTList = await this.dbRead
|
.createQueryBuilder(ExpressYTOrder, "t")
|
.where(`InterfaceStatusID=1 and (PushNum IS NULL OR PushNum<5) And CreateDate>=DATEADD(day, -20, getdate())`)
|
.take(100)
|
.getMany();
|
for (let item of expressYTList) {
|
await ctx.service.express.yuantongHelper.pushOrderbyYT(item.yTOrder_Id);
|
}
|
count = expressYTList.length;
|
} catch (ex) {
|
msgList.push("圆通错误=" + ex.message);
|
}
|
endTime = new Date();
|
span = moment(endTime).diff(moment(beginTime), "seconds");
|
msgList.push("圆通执行完成,执行单量:" + count + ",总耗时=" + span + "s");
|
|
// 中通
|
beginTime = new Date();
|
try {
|
// 获取物流信息
|
let expressZTList = await this.dbRead
|
.createQueryBuilder(ExpressZTOrder, "t")
|
.where(
|
`interfaceStatusText!='推送成功' and ISNULL(PushCount, 0)<=5 And CreateDate>=DATEADD(day, -20, getdate())`
|
)
|
.getMany();
|
let orderList = expressZTList.map(item => item.zTOrder_Id);
|
let result = await ctx.service.express.zhongtongHelper.pushOrder(orderList);
|
msgList.push("物流信息" + result.msg);
|
count = expressZTList.length;
|
// 获取获取大头笔
|
expressZTList = await this.dbRead
|
.createQueryBuilder(ExpressZTOrder, "t")
|
.where(`interfaceStatusText='推送成功' And marke is null and CreateDate>=DATEADD(day, -2, getdate())`)
|
.getMany();
|
orderList = expressZTList.map(item => item.zTOrder_Id);
|
result = await ctx.service.express.zhongtongHelper.getMark(orderList);
|
msgList.push(`获取大头笔(${orderList.length})` + result.msg);
|
} catch (ex) {
|
msgList.push("中通错误=" + ex.message);
|
}
|
endTime = new Date();
|
span = moment(endTime).diff(moment(beginTime), "seconds");
|
msgList.push("中通执行完成,执行单量:" + count + ",总耗时=" + span + "s");
|
|
// 自动获取分拣码
|
beginTime = new Date();
|
let codeResult = await this.ctx.service.tms.routerHelper.autoGetSortingCode(); // 自动获取分拣码
|
endTime = new Date();
|
span = moment(endTime).diff(moment(beginTime), "seconds");
|
msgList.push(codeResult.msg + ",总耗时=" + span + "s");
|
|
this.info.result = true;
|
this.info.msg = msgList.join(";");
|
return this.info;
|
}
|
//#endregion
|
}
|