• 订餐系统之同步口碑外卖商家菜单与点点送订单


      2015年饿了么、百度外卖、美团外卖、口碑外卖几家几乎分完了外卖这碗羹,让其他外卖网站几乎举步维艰,也让那些蠢蠢欲动想进入外卖领域的人犹豫不决了(这估计是要砸我饭碗的节奏啊,ヾ(@⌒ー⌒@)ノ)。当然了,喝了外卖这碗羹,肯定得有“产物”,不然,还不被撑破了肚皮么。对,这个"产物"就是外卖订单,是大量的外卖订单,商户的配送员能力非常有限,于是第三方的配送公司如雨后春笋般的冒了出来,当然了,市场大,竞争也非常残酷,有些刚冒出头,就被"扼杀"在襁褓里了;估计还有不少的没找好“土壤”,压根就没冒出来;肯定还有好些隔岸观火,跃跃欲试的主儿....反正是你方唱罢我登场,你有张良计我有过墙梯,好不热闹呢!!

      热闹落尽,平淡归真,不少配送公司才发现:指望某一个平台,订单有限,壮大何其难?再则,大部分用户估计也和我一样,没有忠诚度,哪家优惠大,就去哪家。于是,一方面开始发展自己的业务(开发一个自己的app),其次接口多家平台(每个平台一个app)..... 就这样,活下来的配送公司业务稳定了,订单也稳定了,但是问题来了:调度人员得几个平台来回切换,操作还不一样,配送员也得在几个app中切换,你要知道每个配送员身上的订单,还得费不小劲....于是,整合各家订单,统一调度,集中配送,让客服与配送员从其他平台解放出来,重复单一动作,效率自然就高了!但是愿望是美好的,现实是残酷的:除了口碑有完整的对配送商的接口外(之前申请还非常麻烦,不知道现在好些了没),美团外卖只对品牌商家开放了接口外,压根没有对配送商的接口;饿了么找半天也没找着相关接口....虽然现在没有,但是我估计着,不久的将来这几个肯定会有针对配送商的接口。既然现在只有口碑有相关接口,那这一系列文章就以口碑外卖接口为准。以后,如果其他平台有了相关接口,我再给大家分享下。说得不好的地方,也请大家海涵、指出哈!

      之前的文章订餐系统之自动确认淘点点订单已经介绍过相关应用的申请,及获取授权账号下的订单,在这里就赘述了,有兴趣的可以了解下。

    批量上传与下载口碑商家菜单

       在口碑商家后台添加过菜单的人都知道,商品只能一个个添加,如果只有1、2个商家还好,但是配送商要生存,就得不停的开店,开了店就得上传商品,一个店少说也得有百八十个商品,如此激烈的竞争不开个三、五百家商家生存都难啊....于是,我们会看到这一幕:他们在不停的寻找店铺,到口碑上开设店铺,再一个个添加商品....然后再重复着,重复着,重复着...于是想起了我。下图为批量上传菜单的过程,同时也可以同步口碑商家已经有菜单到本地。这里面有一个注意的地方就是:先上传图片到口碑,返回图片地址,再上传菜单。如果是先上传菜单,再上传图片,特别麻烦。另外,就是接口中有些限制比如:原价不能小于现价,商品介绍不能少于5个字等等之类的,了解就可以了。

       

      代码方面都是调用TopSdk.dll封装的方法,自己在简单的封装下,方便使用和复用。我的代码结构如下图:

           baseTopAPI.cs  主要是初始化 appkey,appsecret,top_session几个必要的参数,方便子类调用接口。

           TopSysFoodSort.cs  主要是处理分类相关的接口。

           FoodTopAPI.cs  主要是处理商品相关接口的。

           FoodSortSync.cs  客户端调用,同步分类

           FoodSync.cs   客户端调用,同步商品

          

           详情代码如下,写得不好,有需要的可以看下:

        

    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;
    
        }
    
    }
    baseTopAPI
    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;
        }
    
    }
    FoodSortTopAPI
    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;
        }
    }
    FoodTopAPI
    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;
        }
    }
    FoodSortSync
    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;
        }
    }
    FoodSync
    批量营业与歇业口碑商家

       口碑的商家有这样的一个算是要求吧:如果商家在营业中,一天内多次拒单,或者超时不接单,会让你停业整改一天;再则,口碑的商家后台没有批量营业与歇业店铺的功能(想不通是为什么....)天气晴朗,配送高效,订单自然是多多益善,少数实在不能配送的,与用户友好协商,让他取消,多数还是非常理解的;但遇到打雷、刮风、下雨....等恶劣天气时,订单肯定是一增再增,配送效率一降再降,这时,不能配送的订单可能占了很大的比重,再一个个去沟通,这个成本就非常高了,关掉部分店铺是唯一有效的方法,但等你一个个去口碑商家后台关店时,订单已经堆积成山了,投诉也一个接一个的....不生在其中 不知其中苦,还是看代码吧,主要就是调用接口,没有太多可说的!

        

     /// <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;
        }
    shopOpen

     客户端调用如下,使用 BackgroundWorker 响应操作是否完成。

    /// <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 创建,启动服务, 监听订单消息,

        

    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();
            }
    
        }
    
    
    }
    MainService.cs

          MessageListener.cs 监听订单消息

    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:
    " + e.Message.Content + "
    " + e.Message.Topic);
    
                        MessageHandler hanlder = new MessageHandler(e.Message.Topic, e.Message.Content);
    
                    }
                    catch (Exception exp)
                    {
                        Hangjing.AppLog.AppLog.Info("error:
    " + exp);
                        e.Fail(); // 消息处理失败回滚,服务端需要重发  
                    }
                };
                client.Connect("ws://mc.api.taobao.com/");
            }
        }
    }
    MessageListener.cs

          MessageHandler.cs 反射机制处理消息报文。

    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(',');
            }
    
        }
    }
    MessageHandler.cs

       另外,关于订单操作,如指定配送员取件、妥投、上传坐标等,按文档,调用接口就完成了,基本没什么可说的。

    结语

       关于口碑相关接口的介绍就到这里了,基本都是调用封装好的方法,技术上没有太多可说的,他们有很多接口,调用方法基本是一致的,如果应用的好,还是会有不少好处的,这个谁用谁知道!写得不好的地方,或者有误的地方,非常热情的欢迎大家指出,也希望能对大家有所帮助。当然了,写个文章还有一个美好的愿望:希望美团,饿了么可以推出关于团队订单的相关接口(也有可能有接口,只是不给我们申请....)订单还是您们的订单,只是多了一个地方显示,当然,这里多了数据泄露的风险,但是总是有办法降低风险的。还是那句话:大家好,才是真的好!

           成为一名优秀的程序员!

  • 相关阅读:
    JavaScript的for循环编写九九乘法表
    Python核心编程(切片索引的更多内容)
    js/jq宽高的理解与运用
    七月与安生:不管选择哪条路,都会是辛苦的 — —豆瓣老丑
    Linux命令入门
    jq滚动监听-导航滚动
    jQuery页面滚动监听事件及高级效果插件
    跟随鼠标移动展示内容
    用相对定位和负向移动完成图片相框阴影
    腾讯数据总监:运营人员必须掌握的APP基础数据分析体系(没有比这篇更系统全面的)
  • 原文地址:https://www.cnblogs.com/jijunjian/p/5041675.html
Copyright © 2020-2023  润新知