订餐系统之同步口碑外卖商家菜单与点点送订单
2015年饿了么、百度外卖、美团外卖、口碑外卖几家几乎分完了外卖这碗羹,让其他外卖网站几乎举步维艰,也让那些蠢蠢欲动想进入外卖领域的人犹豫不决了(这估计是要砸我饭碗的节奏啊,ヾ(@⌒ー⌒@)ノ)。当然了,喝了外卖这碗羹,肯定得有“产物”,不然,还不被撑破了肚皮么。对,这个"产物"就是外卖订单,是大量的外卖订单,商户的配送员能力非常有限,于是第三方的配送公司如雨后春笋般的冒了出来,当然了,市场大,竞争也非常残酷,有些刚冒出头,就被"扼杀"在襁褓里了;估计还有不少的没找好“土壤”,压根就没冒出来;肯定还有好些隔岸观火,跃跃欲试的主儿....反正是你方唱罢我登场,你有张良计我有过墙梯,好不热闹呢!!
热闹落尽,平淡归真,不少配送公司才发现:指望某一个平台,订单有限,壮大何其难?再则,大部分用户估计也和我一样,没有忠诚度,哪家优惠大,就去哪家。于是,一方面开始发展自己的业务(开发一个自己的app),其次接口多家平台(每个平台一个app)..... 就这样,活下来的配送公司业务稳定了,订单也稳定了,但是问题来了:调度人员得几个平台来回切换,操作还不一样,配送员也得在几个app中切换,你要知道每个配送员身上的订单,还得费不小劲....于是,整合各家订单,统一调度,集中配送,让客服与配送员从其他平台解放出来,重复单一动作,效率自然就高了!但是愿望是美好的,现实是残酷的:除了口碑有完整的对配送商的接口外(之前申请还非常麻烦,不知道现在好些了没),美团外卖只对品牌商家开放了接口外,压根没有对配送商的接口;饿了么找半天也没找着相关接口....虽然现在没有,但是我估计着,不久的将来这几个肯定会有针对配送商的接口。既然现在只有口碑有相关接口,那这一系列文章就以口碑外卖接口为准。以后,如果其他平台有了相关接口,我再给大家分享下。说得不好的地方,也请大家海涵、指出哈!
之前的文章《订餐系统之自动确认淘点点订单》已经介绍过相关应用的申请,及获取授权账号下的订单,在这里就赘述了,有兴趣的可以了解下。
在口碑商家后台添加过菜单的人都知道,商品只能一个个添加,如果只有1、2个商家还好,但是配送商要生存,就得不停的开店,开了店就得上传商品,一个店少说也得有百八十个商品,如此激烈的竞争不开个三、五百家商家生存都难啊....于是,我们会看到这一幕:他们在不停的寻找店铺,到口碑上开设店铺,再一个个添加商品....然后再重复着,重复着,重复着...于是想起了我。下图为批量上传菜单的过程,同时也可以同步口碑商家已经有菜单到本地。这里面有一个注意的地方就是:先上传图片到口碑,返回图片地址,再上传菜单。如果是先上传菜单,再上传图片,特别麻烦。另外,就是接口中有些限制比如:原价不能小于现价,商品介绍不能少于5个字等等之类的,了解就可以了。
代码方面都是调用TopSdk.dll封装的方法,自己在简单的封装下,方便使用和复用。我的代码结构如下图:
baseTopAPI.cs 主要是初始化 appkey,appsecret,top_session几个必要的参数,方便子类调用接口。
TopSysFoodSort.cs 主要是处理分类相关的接口。
FoodTopAPI.cs 主要是处理商品相关接口的。
FoodSortSync.cs 客户端调用,同步分类
FoodSync.cs 客户端调用,同步商品
详情代码如下,写得不好,有需要的可以看下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using Hangjing.Model; using Hangjing.SQLServerDAL; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; using Top.Api; /// <summary> /// 淘点点调用接口基类 /// </summary> public class baseTopAPI { public SortedList<string, string> parameters = null; public string appkey { get; set; } public string appsecret { get; set; } public string top_session { get; set; } /// <summary> /// 系统商家编号 /// </summary> public int shopid { get; set; } /// <summary> /// 淘宝商家编号 /// </summary> public long TaoBaoId { get; set; } /// <summary> /// 接口地址 /// </summary> public string serverurl = "http://gw.api.taobao.com/router/rest?"; public baseTopAPI(int shopid) { parameters = new SortedList<string, string>(); IList<taobaoAPIAcountInfo> apis = SectionProxyData.GettaobaoAPIAcountList(); TogoInfo shop = new Togo().GetModelByDataId(shopid); if (shop.shoptype != 0 && shop.ReveVar1 != "") { foreach (var key in apis) { if (shop.shoptype == key.ID) { this.appkey = key.classname; this.appsecret = key.pic; this.top_session = key.hovepic; break; } } } TaoBaoId = Convert.ToInt64(shop.ReveVar1); this.shopid = shopid; } /// <summary> /// 用任意一个api即可 /// </summary> public baseTopAPI() { parameters = new SortedList<string, string>(); taobaoAPIAcountInfo apiconfig = SectionProxyData.GettaobaoAPIAcountList().First(); this.appkey = apiconfig.classname; this.appsecret = apiconfig.pic; this.top_session = apiconfig.hovepic; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using Hangjing.Common; using Hangjing.Model; using Hangjing.SQLServerDAL; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Web; using Top.Api; using Top.Api.Request; using Top.Api.Response; /// <summary> /// 商品分类 /// </summary> public class FoodSortTopAPI : baseTopAPI { public FoodSortTopAPI(int shopid) : base(shopid) { } public apiResultInfo CallServer(int operate, string data) { apiResultInfo rs = new apiResultInfo(); if (TaoBaoId == 0) { rs.error_info = "top_session,或者淘宝商家编号未设置未设置"; rs.error_no = "1"; return rs; } ITopClient client = new DefaultTopClient(serverurl, appkey, appsecret, "json"); WaimaiCategoryOperateRequest req = new WaimaiCategoryOperateRequest(); req.ShopId = TaoBaoId; req.Operate = operate; if (operate > 0) { req.Data = data; } WaimaiCategoryOperateResponse response = client.Execute(req, top_session); if (response != null && response.Result != null) { rs.error_info = ""; rs.error_no = "0"; rs.data = response.Result; } else { rs.error_info = "接口出错:" + response.ErrMsg; rs.error_no = "1"; } return rs; } public TopFoodSort QueryFoodSort() { TopFoodSort model = new TopFoodSort(); apiResultInfo rs = CallServer(0, ""); if (rs.error_no == "0") { model = JsonConvert.DeserializeObject<TopFoodSort>(rs.data.ToString()); if (model == null) { model = new TopFoodSort(); model.cates = new List<CatesItem>(); } model.msg = ""; } else { model.msg = rs.error_info; } return model; } /// <summary> /// 删除分类 /// </summary> /// <param name="shopid"></param> /// <param name="Top_sort_cids">多个用逗号分开</param> /// <returns></returns> public apiResultInfo DelFoodSort(string Top_sort_cids) { TopFoodSort add = new TopFoodSort(); add.cates = new List<CatesItem>(); foreach (var sortid in Top_sort_cids.Split(',')) { CatesItem item = new CatesItem(); item.cid = sortid; add.cates.Add(item); } string data = JsonConvert.SerializeObject(add); apiResultInfo rs = CallServer(3, data); return rs; } /// <summary> /// 添加一个分类 /// </summary> /// <param name="shopid"></param> /// <param name="addsort"></param> /// <returns></returns> public apiResultInfo CreateOneFoodSort(EFoodSortInfo addsort) { IList<EFoodSortInfo> addsorts = new List<EFoodSortInfo>(); addsorts.Add(addsort); return CreateFoodSortS(addsorts); } /// <summary> /// 添加一个分类 /// </summary> /// <param name="shopid"></param> /// <param name="addsort"></param> /// <returns></returns> public apiResultInfo CreateFoodSortS(IList<EFoodSortInfo> addsorts) { TopFoodSort add = new TopFoodSort(); add.cates = new List<CatesItem>(); foreach (var addsort in addsorts) { CatesItem item = new CatesItem(); item.name = addsort.SortName; item.order = 100000 - addsort.Jorder; //这里用10000-排序得到新的排序,是因为系统里是从降序,淘点点是升序 add.cates.Add(item); } string data = JsonConvert.SerializeObject(add); apiResultInfo rs = CallServer(1, data); return rs; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using Hangjing.Common; using Hangjing.Model; using Hangjing.SQLServerDAL; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Web; using Top.Api; using Top.Api.Request; using Top.Api.Response; /// <summary> /// 淘宝商品接口 /// </summary> public class FoodTopAPI : baseTopAPI { public FoodTopAPI(int shopid) : base(shopid) { } public apiResultInfo AddFood(EFoodInfo food, long syssortid, string shopsortid) { apiResultInfo rs = new apiResultInfo(); if (TaoBaoId == 0) { rs.error_info = "top_session,或者淘宝商家编号未设置未设置"; rs.error_no = "1"; return rs; } ITopClient client = new DefaultTopClient(serverurl, appkey, appsecret); WaimaiItemAddRequest req = new WaimaiItemAddRequest(); req.Title = food.Name; req.Price = food.Price.ToString(); req.Oriprice = food.Price.ToString(); req.Quantity = 9999L; req.Picurl = food.Picture.Length == 0 ? SectionProxyData.GetSetValue(39):food.Picture; req.Goodsno = ""; req.Auctionstatus = 0L; req.Limitbuy = 0L; req.Categoryid = syssortid; req.Auctiondesc = food.Introduce; req.Shopids = TaoBaoId.ToString(); req.Categoryids = shopsortid; WaimaiItemAddResponse response = client.Execute(req, top_session); if (response != null && response.Result != null) { rs.error_info = ""; rs.error_no = "0"; rs.data = response.Result; rs.topFoodID = response.Result.ResultData; } else { rs.error_info = "接口出错:" + response.ErrMsg + "(" + response.ErrCode + ")"; rs.error_no = "1"; HJlog.toLog("AddFood错误:" + rs.error_info); } return rs; } public apiResultInfo AddFood(int foodid, long syssortid, string shopsortid) { EFoodInfo addfood = new EFood().GetModel(foodid); return AddFood(addfood, syssortid, shopsortid); } /// <summary> /// 操作商品 /// </summary> /// <param name="ids">待操作宝贝id,多个以英文逗号分隔</param> /// <param name="operate">操作类型(1上架2下架3删除)</param> /// <returns></returns> public void operateFood(string ids, int operate) { int maxsize = 20;//淘点点一次能删除20个商品 string reqids = ""; string[] foodids = ids.Split(','); if (foodids.Length > maxsize) { for (int i = 0; i < foodids.Length; i++) { reqids += foodids[i] + ","; if (i % (maxsize -1) == 0 && i > 0) { operateFoodCallServer(WebUtility.dellast(reqids),operate); reqids = ""; } } } if (reqids != "") { operateFoodCallServer(WebUtility.dellast(reqids), operate); } } /// <summary> /// 操作商品 /// </summary> /// <param name="ids">待操作宝贝id,多个以英文逗号分隔</param> /// <param name="operate">操作类型(1上架2下架3删除)</param> /// <returns></returns> public apiResultInfo operateFoodCallServer(string ids, int operate) { apiResultInfo rs = new apiResultInfo(); ITopClient client = new DefaultTopClient(serverurl, appkey, appsecret); WaimaiItemOperateRequest req = new WaimaiItemOperateRequest(); req.Ids = ids; req.O = operate; WaimaiItemOperateResponse response = client.Execute(req, top_session); if (response != null && response.BatchOperateResult != null) { rs.error_info = ""; rs.error_no = "0"; rs.data = response.BatchOperateResult; } else { rs.error_info = "接口出错:" + response.ErrMsg + "(" + response.ErrCode + ")"; rs.error_no = "1"; HJlog.toLog("operateFood错误:" + rs.error_info); } return rs; } /// <summary> /// 查询商品,如果keyword为空,就不加此参数 /// </summary> /// <param name="keyword"></param> /// <returns></returns> public List<Top.Api.Domain.TopAuction> queryFood(string keyword) { ITopClient client = new DefaultTopClient(serverurl, appkey, appsecret); WaimaiItemlistGetRequest req = new WaimaiItemlistGetRequest(); req.Shopid = TaoBaoId; req.SalesStatus = 0L; if (keyword != "") { req.Keyword = keyword; } req.PageNo = 1L; req.PageSize = 200L; req.Fields = "itemid,title,price,oriprice,goods_no,auction_desc,pic_url,category_id"; WaimaiItemlistGetResponse response = client.Execute(req, top_session); if (response != null) { long total_results = response.TotalResults; return response.DataList; } return null; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Hangjing.Model; using Hangjing.SQLServerDAL; using Hangjing.DBUtility; using System.Data; using Hangjing.Common; /// <summary> /// 商品分类同步 /// </summary> public class FoodSortSync { FoodSortTopAPI sortapid = null; public FoodSortSync(int shopid) { sortapid = new FoodSortTopAPI(shopid); } /// <summary> /// 从淘点点同步到系统 /// </summary> /// <returns></returns> public apiResultInfo SyncFromTop() { TopFoodSort Topsorts = sortapid.QueryFoodSort(); string sql = " DELETE dbo.EFoodSort WHERE TogoNUm = "+sortapid.shopid; WebUtility.excutesql(sql); IList<DBEFoodSortInfo> websorts = new List<DBEFoodSortInfo>(); foreach (var topsort in Topsorts.cates) { DBEFoodSortInfo websort = new DBEFoodSortInfo(); websort.SortName = topsort.name; websort.JOrder = 10000 - topsort.order; websort.TogoNUm = sortapid.shopid; websort.topsortid = topsort.cid; websorts.Add(websort); } DataTable dt = CollectionHelper.ConvertTo(websorts, "EFoodSort"); SQLHelper.SqlBulkCopyData(dt); return null; } /// <summary> /// 上传菜单到口碑 /// </summary> /// <returns></returns> public apiResultInfo Upload() { TopFoodSort Topsorts = sortapid.QueryFoodSort(); IList<EFoodSortInfo> Sysorts = new EFoodSort().GetListByTogoNum(sortapid.shopid); //1,删除系统中没有,而淘宝中有的分类 string notinsyssortids = ""; foreach (var topsort in Topsorts.cates) { if (Sysorts.Where(a => a.SortName == topsort.name).ToList().Count == 0) { notinsyssortids += topsort.cid + ","; } } notinsyssortids = WebUtility.dellast(notinsyssortids); if (notinsyssortids != "") { sortapid.DelFoodSort(notinsyssortids); } //添加系统中有,而淘宝中没有的 IList<EFoodSortInfo> notintopsorts = new List<EFoodSortInfo>(); foreach (var syssort in Sysorts) { if (Topsorts.cates.Where(a => a.name == syssort.SortName).ToList().Count == 0) { notintopsorts.Add(syssort); } } if (notintopsorts.Count > 0) { sortapid.CreateFoodSortS(notintopsorts); } return null; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Hangjing.Model; using Hangjing.SQLServerDAL; using System.Data; using Hangjing.DBUtility; using Hangjing.Common; /// <summary> /// 商品同步 /// </summary> public class FoodSync { FoodTopAPI api = null; public FoodSync(int shopid) { api = new FoodTopAPI(shopid); } /// <summary> /// 从淘点点同步菜单 /// </summary> /// <returns></returns> public apiResultInfo SyncFromTop() { List<Top.Api.Domain.TopAuction> Topfoods = api.queryFood(""); IList<EFoodSortInfo> websorts = new EFoodSort().GetListByTogoNum(api.shopid); string sql = " DELETE dbo.EFood WHERE TogoNum = " + api.shopid; WebUtility.excutesql(sql); IList<DBEFoodInfo> webfoods = new List<DBEFoodInfo>(); foreach (var topfood in Topfoods) { DBEFoodInfo food = new DBEFoodInfo(); food.FoodID = 0; food.Name = topfood.Title; food.Picture = topfood.PicUrl; food.FoodType = 0; foreach (var websort in websorts) { if (topfood.CategoryId.ToString() == websort.topsortid) { food.FoodType = websort.SortID; break; } } food.Price = Convert.ToDecimal(topfood.Price); food.Introduce = topfood.AuctionDesc; food.Discount = 10; food.TogoNum = api.shopid; food.Total = 0; food.IsDelete = 0; food.WeekDay = ""; food.istuan = 0; food.nprice = food.Price; food.allnum = 0; food.joinnum = 0; food.salecount = 0; food.PackageFree = 0; food.IstuanInve = 0; webfoods.Add(food); } DataTable dt = CollectionHelper.ConvertTo(webfoods, "EFood"); SQLHelper.SqlBulkCopyData(dt); return null; } /// <summary> /// 上传菜单 /// </summary> /// <returns></returns> public apiResultInfo Upload() { List<Top.Api.Domain.TopAuction> Topfoods = api.queryFood(""); IList<EFoodInfo> Sysorts = new EFood().GetList(1000, 1, " IsDelete = 0 and TogoNum=" + api.shopid, "Total", 1); //1,删除系统中没有,而淘宝中有的分类 string notinsyids = ""; foreach (var topsort in Topfoods) { if (Sysorts.Where(a => a.Name == topsort.Title).ToList().Count == 0) { notinsyids += topsort.ItemId + ","; } } notinsyids = WebUtility.dellast(notinsyids); if (notinsyids != "") { api.operateFood(notinsyids, 3); } FoodSortTopAPI sortapi = new FoodSortTopAPI(api.shopid); TopFoodSort Topsorts = sortapi.QueryFoodSort(); //添加系统中有,而淘宝中没有的 foreach (var syssort in Sysorts) { if (Topfoods.Where(a => a.Title == syssort.Name).ToList().Count == 0) { foreach (var tsort in Topsorts.cates) { if (tsort.name == syssort.SortName) { apiResultInfo rs = api.AddFood(syssort, Convert.ToInt64(syssort.Weekday), tsort.cid); if (rs.error_no == "0") { WebUtility.excutesql("UPDATE dbo.EFood SET topFoodID = '"+rs.topFoodID+"' WHERE FoodID = "+ syssort.FoodID); } break; } } } } return null; } }
口碑的商家有这样的一个算是要求吧:如果商家在营业中,一天内多次拒单,或者超时不接单,会让你停业整改一天;再则,口碑的商家后台没有批量营业与歇业店铺的功能(想不通是为什么....)天气晴朗,配送高效,订单自然是多多益善,少数实在不能配送的,与用户友好协商,让他取消,多数还是非常理解的;但遇到打雷、刮风、下雨....等恶劣天气时,订单肯定是一增再增,配送效率一降再降,这时,不能配送的订单可能占了很大的比重,再一个个去沟通,这个成本就非常高了,关掉部分店铺是唯一有效的方法,但等你一个个去口碑商家后台关店时,订单已经堆积成山了,投诉也一个接一个的....不生在其中 不知其中苦,还是看代码吧,主要就是调用接口,没有太多可说的!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 商户营业 返回:成功:0,失败:1 /// </summary> public string shopOpen(string shopid, string sessionkey) { string appkey = ""; string appsecret = ""; string top_session = ""; IList<taobaoAPIAcountInfo> apis = SectionProxyData.GettaobaoAPIAcountList(); foreach (var item in apis) { if (item.hovepic == sessionkey) { top_session = item.hovepic; appsecret = item.pic; appkey = item.classname; break; } } //3.生成url string url = "http://gw.api.taobao.com/router/rest?";//线上环境: http://gw.api.taobao.com/router/rest 测试环境: http://gw.sandbox.taobao.com/router/rest ITopClient client = new DefaultTopClient(url, appkey, appsecret, "json"); WaimaiShopOpenRequest req = new WaimaiShopOpenRequest(); req.Shopid = Convert.ToInt64(shopid); WaimaiShopOpenResponse response = client.Execute(req, top_session); string rs = "1"; if (response != null) { rs = response.RetCode; ; } return rs; }
客户端调用如下,使用 BackgroundWorker 响应操作是否完成。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 歇业 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void offline_Click(object sender, EventArgs e) { BackgroundWorker bgw; bgw = new BackgroundWorker(); bgw.WorkerSupportsCancellation = true; bgw.WorkerReportsProgress = true; bgw.DoWork += new DoWorkEventHandler(offline); bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted); bgw.RunWorkerAsync(); } /// <summary> /// 歇业 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void offline(object sender, DoWorkEventArgs e) { try { string IdList = this.hidDels.Value; IList<shopserverInfo> shops = dal.GetList(100, 1, "id in (" + IdList + ")", "id", 0); foreach (var item in shops) { if (new TaoBaoAPI().shopClose(item.Status.ToString(), item.Parentid) == "0") { string sql = "UPDATE dbo.shopserver SET Depth = 0 WHERE id = "+ item.ID; WebUtility.excutesql(sql); } } } catch (Exception ee) { HJlog.toLog(ee.ToString()); } }
点点送,其实是口碑官方配送的名称,后台也是对接多个配送商,商家选择某个配送商配送后,订单就自动通知到相应配送商,也就配送家的管理系统,可以看订单,管理人员,及相关报表,和配送员app。如果直接用他们提供的,也就没有下文了,具体原因前文已有说明,这里就不多说了。
对接主要有发下几个步骤:
1,申请应用
2,申请点点送权限包
3,订阅相关消息
4,消息授权接口调用
5,代码实现接收消息
6,订单操作相关接口调用
具体可参考如下网址 http://open.taobao.com/doc2/detail.htm?articleId=101663&docType=1&treeId=2
代码方面,也是简单的封装了下,接收消息程序以windows service为宿主,随服务启动。
MainService.cs 创建,启动服务, 监听订单消息,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Diagnostics; using System.ServiceProcess; using System.Linq; using System.Text; using System.Collections.Specialized; using System.Text.RegularExpressions; using System.Threading; using System.ServiceModel; using Hangjing.Commond; namespace Hangjing.JobServer { partial class MainService : ServiceBase { MessageListener Listener = new MessageListener(); public MainService() { InitializeComponent(); } protected override void OnStart(string[] args) { try { Listener.Listen(); } catch (Exception ex) { Hangjing.AppLog.AppLog.Info("启动失败:" + ex); throw; } Hangjing.AppLog.AppLog.Info("启动成功"); } protected override void OnStop() { base.OnStop(); } protected override void OnShutdown() { base.OnShutdown(); } } }
MessageListener.cs 监听订单消息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Top.Tmc; namespace Hangjing.Commond { /// <summary> /// 淘宝消息监听器 /// </summary> public class MessageListener { public MessageListener() { } public void Listen() { TmcClient client = new TmcClient(CacheHelper.appkey, CacheHelper.secret, "default"); client.OnMessage += (s, e) => { try { Hangjing.AppLog.AppLog.Info("msg:\r\n" + e.Message.Content + "\r\n" + e.Message.Topic); MessageHandler hanlder = new MessageHandler(e.Message.Topic, e.Message.Content); } catch (Exception exp) { Hangjing.AppLog.AppLog.Info("error:\r\n" + exp); e.Fail(); // 消息处理失败回滚,服务端需要重发 } }; client.Connect("ws://mc.api.taobao.com/"); } } }
MessageHandler.cs 反射机制处理消息报文。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using Newtonsoft.Json; using System.Text.RegularExpressions; using Hangjing.SQLServerDAL; using Hangjing.Model; using Hangjing.Common; using Top.Tmc; using Top.Api; using Top.Api.Response; using Top.Api.Request; namespace Hangjing.Commond { /// <summary> /// 消息处理类 /// </summary> public class MessageHandler { /// <summary> /// 消息名称 /// </summary> public string Topic { set; get; } /// <summary> /// 消息内容 /// </summary> public string Content { set; get; } /// <summary> /// 返回信息 /// </summary> public string replaymsg { set; get; } public MessageHandler(string _Topic, string _Content) { Topic = _Topic; Content = _Content; DynamicMethod(); } /// <summary> /// 动态调用方法 /// </summary> private void DynamicMethod() { if (CacheHelper.goodTopics.Contains(Topic)) { //获取方法的实例 非静态 需要Public访问权限 忽略大小写 MethodInfo methodInfo = this.GetType().GetMethod(Topic, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase); if (methodInfo != null) { //调用方法 methodInfo.Invoke(this, null); } else { Hangjing.AppLog.AppLog.Error(string.Format("没有找到方法{0}", Topic)); } } else { Hangjing.AppLog.AppLog.Error("未处理的消息:" + Topic); } } /// <summary> /// 库存变化 /// </summary> public void taobao_item_ItemStockChanged() { } /// <summary> /// 点点送订单通知消息 /// </summary> public void taobao_waimai_OrderDispatch() { 。。。 } } /// <summary> /// 买家取消订单 /// </summary> public void taobao_waimai_OrderClose() { 。。。 } /// <summary> /// 解析返回的坐标信息 [0]经度,[1]纬度 /// 坐标信息: LngLatAlt{longitude=120.02165, latitude=30.27919, altitude=NaN} /// </summary> /// <param name="LngLatAlt"></param> /// <returns></returns> public string[] ParseLatLng(string LngLatAlt) { string regexstr = @"[a-zA-Z={}]"; //最后的结果:120.02165, 30.27919, string content = Regex.Replace(LngLatAlt, regexstr, string.Empty, RegexOptions.IgnoreCase); return content.Split(','); } } }
另外,关于订单操作,如指定配送员取件、妥投、上传坐标等,按文档,调用接口就完成了,基本没什么可说的。
关于口碑相关接口的介绍就到这里了,基本都是调用封装好的方法,技术上没有太多可说的,他们有很多接口,调用方法基本是一致的,如果应用的好,还是会有不少好处的,这个谁用谁知道!写得不好的地方,或者有误的地方,非常热情的欢迎大家指出,也希望能对大家有所帮助。当然了,写个文章还有一个美好的愿望:希望美团,饿了么可以推出关于团队订单的相关接口(也有可能有接口,只是不给我们申请....)订单还是您们的订单,只是多了一个地方显示,当然,这里多了数据泄露的风险,但是总是有办法降低风险的。还是那句话:大家好,才是真的好!
成为一名优秀的程序员!