9、ABPZero系列教程之拼多多卖家工具 拼团提醒类库封装

  本篇开始正式做功能,我在开发拼团提醒之前,拼多多并没有放出拼团人数不足就提醒卖家的功能。

有这个想法主要来源于朋友的抱怨,我想这应该是大部分卖家的心声吧。

经过分析,拿到了几个api,不要问我api怎么拿到的,这不是本系列的内容。

接口1:http://apiv4.yangkeduo.com/mall/{0}/info?pdduid=0(传入店铺编号,可以获取店铺资料)

接口2:http://apiv4.yangkeduo.com/v2/mall/{0}/goods?page=1&size=500&sort_type=PRIORITY&pdduid=0(传入店铺编号,可以拿到店铺商品资料,拼多多限制最多获取500个商品)

接口3:http://apiv2.yangkeduo.com/v2/goods/{0}/local_group(传入商品id,可以获取拼团信息)

有了这几个api,拼团提醒功能就不在话下,接下来讲解实现过程。

建立新项目

在解决方案下建立PddTool项目,目的是把拼多多相关业务逻辑以专门的一个类库来实现。

在解决方案右键选择“管理解决方案的 NuGet程序包”,搜索安装如下NuGet包,注意版本号。

创建目录,先创建好几个目录,如下图所示:

在Response目录下新建MallEntity类,代码如下:

public class MallEntity
    {
        /// <summary>
        ///
        /// </summary>
        public int mall_id { get; set; }
        /// <summary>
        /// 木子缘
        /// </summary>
        public string mall_name { get; set; }
        /// <summary>
        ///
        /// </summary>
        public string logo { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int goods_num { get; set; }
        /// <summary>
        /// 小店主要经营时尚潮流女装,品质女装,质量有保障!
        /// </summary>
        public string mall_desc { get; set; }
        /// <summary>
        ///
        /// </summary>
        public string company_phone { get; set; }
        /// <summary>
        ///
        /// </summary>
        public string offline_note { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int chat_enable { get; set; }
        /// <summary>
        /// 广东广州天河区
        /// </summary>
        public string refund_address { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int score_avg { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int staple_id { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int mall_sales { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int region_emergent { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int is_open { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int status { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int wms_id { get; set; }
        /// <summary>
        ///
        /// </summary>
        public List<string> mall_coupons { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int server_time { get; set; }
    }

这是请求api之后,根据返回json数据所生成的类,

http://www.bejson.com/convert/json2csharp/(通过这个工具,可以把json转C#实体类)

再同目录下新建ProductEntity类,代码如下:

/// <summary>
    /// 拼团
    /// </summary>
    public class Group
    {
        /// <summary>
        /// 拼团人数
        /// </summary>
        public int customer_num { get; set; }
        /// <summary>
        /// 拼团价格÷100
        /// </summary>
        public int price { get; set; }
    }

    public class Goods_listItem
    {
        /// <summary>
        /// 单买价÷100
        /// </summary>
        public int normal_price { get; set; }
        /// <summary>
        /// 已拼数量
        /// </summary>
        public int cnt { get; set; }
        /// <summary>
        /// 小图连接
        /// </summary>
        public string thumb_url { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int event_type { get; set; }
        /// <summary>
        /// 市场价÷100
        /// </summary>
        public int market_price { get; set; }
        /// <summary>
        /// 【木子缘】毛呢外套女中长款韩版2017新款宽松显廋修身学生百搭大码加厚外套bf过膝气质呢子大衣
        /// </summary>
        public string goods_name { get; set; }
        /// <summary>
        /// 商品id
        /// </summary>
        public int goods_id { get; set; }
        /// <summary>
        /// 【木子缘】毛呢外套女中长款韩版2017新款宽松显廋修身学生百搭大码加厚外套bf过膝气质呢子大衣
        /// </summary>
        public string short_name { get; set; }
        /// <summary>
        ///
        /// </summary>
        public Group group { get; set; }
        /// <summary>
        ///
        /// </summary>
        public string country { get; set; }
        /// <summary>
        /// 商品主图
        /// </summary>
        public string image_url { get; set; }
        /// <summary>
        /// 高清图
        /// </summary>
        public string hd_thumb_url { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int is_app { get; set; }
    }

    public class ProductEntity
    {
        /// <summary>
        ///
        /// </summary>
        public List<string> recommend_subject { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int server_time { get; set; }
        /// <summary>
        ///
        /// </summary>
        public List<Goods_listItem> goods_list { get; set; }
        /// <summary>
        ///
        /// </summary>
        public List<string> subject_list { get; set; }
    }

同目录下再创建KaiTuanEntity类,代码如下:

public class Local_groupItem
    {
        /// <summary>
        /// 拼团订单id
        /// </summary>
        public string group_order_id { get; set; }
        /// <summary>
        /// 商品id
        /// </summary>
        public string goods_id { get; set; }
        /// <summary>
        /// 城市名称
        /// </summary>
        public string city_name { get; set; }
        /// <summary>
        /// 昵称
        /// </summary>
        public string nickname { get; set; }
        /// <summary>
        /// 头像
        /// </summary>
        public string avatar { get; set; }
        /// <summary>
        ///
        /// </summary>
        public string expire_time { get; set; }
        /// <summary>
        /// 用户id
        /// </summary>
        public string uid { get; set; }
    }

    public class KaiTuanEntity
    {
        /// <summary>
        /// 正在拼团列表
        /// </summary>
        public List<Local_groupItem> local_group { get; set; }
        /// <summary>
        ///
        /// </summary>
        public int server_time { get; set; }
        /// <summary>
        /// 正在拼团人数
        /// </summary>
        public int total { get; set; }
    }

然后在Entities目录下,创建KaiTuan类,代码如下:

public class KaiTuan
    {
        /// <summary>
        /// 商品id
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 昵称
        /// </summary>
        public string NickName { get; set; }

        /// <summary>
        ///
        /// </summary>
        public string SKU { get; set; }

        /// <summary>
        /// 订单号
        /// </summary>
        public string OrderNum { get; set; }

        /// <summary>
        /// 剩余时间
        /// </summary>
        public double TimeLeft { get; set; }

        /// <summary>
        /// 开团单号
        /// </summary>
        public string KaiTuanOrderNum { get; set; }
    }

继续在Entities目录下创建KaiTuanProduct类,代码如下:

/// <summary>
    /// 开团商品
    /// </summary>
   public  class KaiTuanProduct
    {
        /// <summary>
        /// 商品id
        /// </summary>
        public int GoodId { get; set; }
        /// <summary>
        /// 商品名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 商品图片
        /// </summary>
        public string Img { get; set; }
        /// <summary>
        /// 开团人数
        /// </summary>
        public int KaiTuanCount { get; set; }
    }

再类库下创建DateTimeHelper类,代码如下:

public class DateTimeHelper
    {
        /// <summary>
        /// 传入unix时间戳,计算与当前时间之间的小时数
        /// </summary>
        /// <param name="unixTimeStamp"></param>
        /// <returns></returns>
        public static double GetHours(long unixTimeStamp)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
            DateTime dt = startTime.AddSeconds(unixTimeStamp);
            var a = dt - DateTime.Now;

            return Math.Round(a.TotalHours, 1);
        }
    }

再类库下创建MallTool类,实现几个方法,代码如下:

public class MallTool
    {
        /// <summary>
        /// 按店铺id获取店铺资料
        /// </summary>
        /// <param name="mallId"></param>
        public static MallEntity GetInfo(string mallId)
        {
            string url = string.Format("http://apiv4.yangkeduo.com/mall/{0}/info?pdduid=0", mallId);
            var client = new RestClient(url);
            var request = new RestRequest(Method.GET);
            request.AddHeader("cache-control", "no-cache");
            request.AddHeader("referer", url);
            IRestResponse response = client.Execute(request);
            if (string.IsNullOrWhiteSpace(response.Content) || response.Content.Contains("mall not exists"))
            {
                throw new Exception("店铺编号错误!");
            }
            var mall = JsonConvert.DeserializeObject<MallEntity>(response.Content);
            return mall;
        }

        /// <summary>
        /// 最多拿到500个商品
        /// </summary>
        /// <param name="mallId"></param>
        /// <returns></returns>
        public static ProductEntity GetGoods(string mallId)
        {
            string url =
                string.Format(
                    "http://apiv4.yangkeduo.com/v2/mall/{0}/goods?page=1&size=500&sort_type=PRIORITY&pdduid=0", mallId);
            var client = new RestClient(url);
            var request = new RestRequest(Method.GET);
            request.AddHeader("cache-control", "no-cache");
            request.AddHeader("referer", url);
            IRestResponse response = client.Execute(request);
            var product = JsonConvert.DeserializeObject<ProductEntity>(response.Content);
            return product;
        }

        /// <summary>
        /// 根据商品id ,获取开团信息
        /// </summary>
        /// <param name="goodId"></param>
        /// <returns></returns>
        public static KaiTuanEntity GetKaiTuanInfo(int goodId)
        {
            string url = string.Format("http://apiv2.yangkeduo.com/v2/goods/{0}/local_group", goodId);
            var client = new RestClient(url);
            var request = new RestRequest(Method.GET);
            request.AddHeader("cache-control", "no-cache");
            request.AddHeader("referer", url);
            IRestResponse response = client.Execute(request);
            var content = response.Content.Replace("\\\"", "\"");
            content = content.Replace("\\\\", "\\").Replace("\"{", "{").Replace("}\"", "}");
            var kaiTuan = JsonConvert.DeserializeObject<KaiTuanEntity>(content);
            return kaiTuan;
        }

        /// <summary>
        /// 根据商品id,获取此商品所有开团信息
        /// </summary>
        /// <param name="goodId"></param>
        /// <returns></returns>
        public static List<KaiTuan> GetAllKaiTuanByGoodId(int mallId, int goodId)
        {
            int total = 0;// 总开团数量
            var kaituan = GetKaiTuanInfo(goodId);
            total = kaituan.total;
            List<KaiTuan> groups = new List<KaiTuan>();
            int maxNoKaituan = 20;//获取拼团
            int noKaituan = 0;//获取拼团,返回的数据中没有新的拼团则+1
            //获取开团信息存放集合里面
            AddRange(groups, kaituan, mallId, goodId, ref noKaituan);

            //开团数量大于5就分页循环
            if (kaituan.total > 5)
            {
                while (true)
                {
                    //重试了maxNoKaituan次,还是没有新数据就退出
                    if (noKaituan >= maxNoKaituan)
                    {
                        break;
                    }
                    kaituan = GetKaiTuanInfo(goodId);
                    //已获取到的开团数>=获取回来的开团数 就退出
                    if (groups.Count >= kaituan.total)
                    {
                        break;
                    }
                    AddRange(groups, kaituan, mallId, goodId, ref noKaituan);
                }
            }
            return groups;
        }

        /// <summary>
        /// 根据店铺id,获取所有商品的开团人数
        /// </summary>
        /// <param name="mallId"></param>
        /// <returns></returns>
        public static List<KaiTuanProduct> GetKaiTuanList(string mallId)
        {
            var goods = GetGoods(mallId);
            if (goods.goods_list.Count == 0)
            {
                throw new UserFriendlyException("此店铺商品为 0");
            }
            List<KaiTuanProduct> kaiTuanProducts = new List<KaiTuanProduct>();
            foreach (var goodsListItem in goods.goods_list)
            {
                var kaituanProduct = GetKaiTuanCountByGoodId(goodsListItem.goods_id);
                if (kaituanProduct == null)
                {
                    continue;
                }
                kaituanProduct.Name = goodsListItem.goods_name;
                kaituanProduct.GoodId = goodsListItem.goods_id;
                kaituanProduct.Img = goodsListItem.thumb_url;
                kaiTuanProducts.Add(kaituanProduct);
            }
            return kaiTuanProducts;
        }

        /// <summary>
        ///根据商品id, 获取开团人数
        /// </summary>
        /// <param name="goodId"></param>
        public static KaiTuanProduct GetKaiTuanCountByGoodId(int goodId)
        {
            var kaituanInfo = GetKaiTuanInfo(goodId);
            if (kaituanInfo.total == 0)
            {
                return null;
            }
            return new KaiTuanProduct()
            {
                KaiTuanCount = kaituanInfo.total
            };
        }

        public static void AddRange(List<KaiTuan> groups, KaiTuanEntity kaiTuan, int mallId, int goodId, ref int noKaituan)
        {
            bool isExist = true;
            int count = 0;
            foreach (var localGroupItem in kaiTuan.local_group)
            {
                //过滤已经存在的拼团
                if (groups.Any(a => a.KaiTuanOrderNum == localGroupItem.group_order_id))
                {
                    count++;
                    isExist = false;
                    continue;
                }
                //过滤时间小于0的拼团
                var t = DateTimeHelper.GetHours(Convert.ToInt64(localGroupItem.expire_time));
                if (t <= 0)
                {
                    count++;
                    isExist = false;
                    continue;
                }

                var item = new KaiTuan()
                {
                    Id = Convert.ToInt32(localGroupItem.goods_id),
                    KaiTuanOrderNum = localGroupItem.group_order_id,
                    NickName = localGroupItem.nickname,
                    TimeLeft = DateTimeHelper.GetHours(Convert.ToInt64(localGroupItem.expire_time)),
                };
                groups.Add(item);
                isExist = true;
            }
            if (isExist == false && count == kaiTuan.local_group.Count)
            {
                noKaituan++;
            }
        }
    }

可以看到UserFriendlyException报异常,这是abp的异常类,接着解决方案再打开”管理解决方案的 NuGet程序包”,搜索:“abp”安装。

最后项目结构如下,拼团提醒功能就封装好了。

创建单元测试

在解决方案Tests目录下新建单元测试项目,如下图所示:

新建MallTool_Test类,用来测试刚刚封装的几个方法,代码如下:

[TestClass]
    public class MallTool_Test
    {
        public string mallId { get; set; } = "1277675";
        [TestMethod]
        public void TestGetInfo()
        {
            MallEntity result=MallTool.GetInfo(mallId);
            Console.WriteLine(result.mall_name);
        }
    }

下图为调试输出结果:

以上代码传入店铺编号,获取店铺资料,

店铺编号哪里来?

http://mobile.yangkeduo.com/search_result.html?search_key=%E6%89%93%E5%BA%95%E8%A1%AB%E5%A5%B3&search_src=history&search_met=history_sort&search_met_track=history&refer_page_name=search&refer_page_id=&page_id=&sp=0&item_index=1&is_back=1

通过以上连接可以查询拼多多商品信息,接着随便点入一个商品,点击“进店逛逛”,如下图所示:

进来之后就可以看到地址栏就有店铺编号,如下图所示:

其它几个方法测试类似,就不一一说明。

返回总目录

原文地址:https://www.cnblogs.com/shensigzs/p/8302521.html

时间: 2024-10-06 03:08:51

9、ABPZero系列教程之拼多多卖家工具 拼团提醒类库封装的相关文章

1、ABPZero系列教程之拼多多卖家工具 前言

此系列文章围绕着拼多多卖家工具来介绍ABPZero的使用,内容包括手机登录.手机注册.拼团提醒.微信公众号绑定帐号.有拼团发送消息到微信公众号(只要关注过微信公众号并已绑定系统帐号). 学习此系列必备: 手机验证码:使用阿里云短信,可注册阿里云帐号订购(后续会介绍) 微信公众号:我所使用的是认证过的服务号 邮箱:配置系统发送邮件 ABPZero框架:我所使用的是3.4版本,版本不一样可能个别地方也会有些异同,为了让学习过程比较顺利,最好版本跟我一样. 群号:104390185(加入这个群可以下载

2、ABPZero系列教程之拼多多卖家工具 更改数据库为Mysql

因为要部署项目到云服务器,不想在服务器上装SqlServer,所以需要把项目改为Mysql. 项目初始化 1.下载项目压缩包,前面文章已经说到,可以加群到群文件里下载.解压缩下载的项目源码,使用VS2015打开项目 这里需要还原包,选择解决方案---右键(还原NuGet包),现在还原NuGet包比之前快了好多了,这都是微软重视中国开发者的功劳. 包还原好了之后,点击解决方案重新生成一次.可以看到项目生成成功,接下来进入修改Mysql数据库步骤. 注:如果你不想使用Mysql数据库,可以跳过以下一

4、ABPZero系列教程之拼多多卖家工具 集成短信发送模块

ABPZero并没有手机短信发送功能,现在我们来集成一个,为后面注册.登录作铺垫. 阿里云短信服务 首先需要在阿里云开通短信服务,连接地址 开通后,在签名管理中添加一个签名 在模板管理中添加一个模板,如下图所示 最后需要使用阿里云提供的.NET发送短信类库,下面可以直接下载我上传的类库,也可以去官方下载,然后提取我所说的2个类库(aliyun-net-sdk-core.dll.aliyun-net-sdk-dysmsapi.dll) 直接下载文件:https://files.cnblogs.co

13、ABPZero系列教程之拼多多卖家工具 微信公众号开发前的准备

因为是开发阶段,我需要在本地调试,而微信开发需要配置域名,这样natapp.cn就有了用武之地,应该说natapp就是为此而生的. natapp.cn是什么 这是一个内网映射的网站,支持微信公众号.小程序本地开发调试,具体详情请到官网去了解:https://natapp.cn/ 虽然官网已经有配置教程,但在这里还是要简单说一下. 申请隧道 注册用户可以免费获取得一个隧道,但是免费的就是有缺陷,每次域名都会变,这给开发带来了很多麻烦. 这里建议购买一个隧道,每个月5元的就可以,购买的时候可以输入我

5、ABPZero系列教程之拼多多卖家工具 修改User表结构

毕竟这个框架是外国人开发的,对于我们国人来说还是有些地方并不合适,就好比如注册时需要填写名字.姓氏一样,今天要说的就是如何去掉这2个字段. 先看如下修改完成的效果图 User表结构修改 修改User类,添加如下代码: 文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Core\Authorization\Users\User.cs //Can add applicat

6、ABPZero系列教程之拼多多卖家工具 框架后台的设置

接着上篇文章,现在去修改注册登录逻辑代码还为时过早,我们还需要到后台去设置一些配置. 管理---设置 先配置好这2项设置,邮箱配置是为了验证注册时功能是否正常,下一篇文章需要用到. 注:邮箱配置中的密码并不是QQ密码,而是在QQ邮箱中生成的授权码,具体获取请登录QQ邮箱查看 语言翻译 进入后台可以看到圈出来这些单词,我们的语言已经设置为简体中文,但一些地方没有中文出现,可能作者还没来得及更新语言文件,只得我们自己去完善了. 这里我以“[Appearance]”为例,其它翻译以此类推即可. 打开A

8、ABPZero系列教程之拼多多卖家工具 添加手机注册登录功能

现在网站基本都用手机注册,很少用邮箱注册,本篇内容比较多,代码我会尽量加备注,有些操作需要连续添加几个文件才不报错,如果VS显示错误,请继续后续步骤. 前面已经有一篇文章讲到集成短信发送模块:http://www.cnblogs.com/shensigzs/category/1147235.html 在此基础上才能做手机注册功能,没有完成的同学请先去整合后再回来. 语言文件 AbpZeroTemplate-zh-CN.xml文件末尾添加如下键值对: 文件路径:D:\abp version\asp

拼多多怎么开店,拼多多店群何如做好客服

店群管家大讲堂-拼多多店群何如做好客服,上节课我们介绍了拼多多店群是什么,一个人开多个拼多多店铺,高效操作上货和一键派单.那么我们来聊一聊拼多多店群如何做好客服.拼多多店群采集上家宝贝,让上家发货.客户问题汇总:1.从哪发的货回答:我们仓库全国有参加,我们是就近发货.2.你们快递多久能到回答:两三天(不要给他一个准话)3.用什么快递,能不能用韵达.EMS回答:四通一达,EMS我们都是可以发,但是我们不能自选,我们会根据亲的地区来发货4.退货沟通是退货,还是说给他补差价,我们要及时跟商家沟通查看售

估值上百亿的拼多多,为什么被淘宝点名成新的假货聚集地?

一个星期之前,阿里巴巴对外发布了<2017年阿里巴巴知识产权保护年度报告>,其中提及一批原淘宝网的制假售假商家已转移至微信和拼多多. 事实真的如阿里发布的报告所言吗?下面何玺和大家一起来聊聊. 一.拼多多为什么成了阿里的点名对象? 时间回到两年前,拼多多还只是一个依靠微信公众号起家的初创公司,名不见经传.可是短短的两年,这家创业公司已经完成B轮融资,估值也达到了惊人的百亿级,俨然成为独角兽公司. 2017年12月,拼多多在综合电商APP渗透率排行榜中位列第三,仅次于淘宝和京东. 1.拼多多是独