Example #1
0
        /// <summary>
        /// 查询物流记录
        /// </summary>
        /// <param name="company"></param>
        /// <param name="number"></param>
        /// <returns></returns>
        public static DeliveryTransation Query(string company, string number)
        {
            String code = ServiceContainer.GetService <DeliveryCompanyService>().GetDeliveryCompany(company).PopMapKuaidi100;
            Dictionary <string, string> para = new Dictionary <string, string>();

            para["type"]   = code;
            para["postid"] = number;
            para["temp"]   = "0." + r.Next() + "" + r.Next();
            var content = MsHttpRestful.GetUrlEncodeBodyReturnString(APIURL, para, Encoding.UTF8, null, "http://www.kuaidi100.com/", "*/*");
            var ret     = Newtonsoft.Json.JsonConvert.DeserializeObject <Kuaidi100DeliveryResult>(content);
            var item    = new DeliveryTransation();

            item.IsSigned = ret.ischeck == "1" ? true : false;
            if (ret.message.ToUpper().Equals("OK") == false)
            {
                throw new Exception(ret.message);
            }
            item.Items = new List <DeliveryTransationItem>();
            foreach (var o in ret.data)
            {
                item.Items.Add(new DeliveryTransationItem {
                    Time = DateTime.Parse(o.ftime), Description = o.context
                });
            }

            return(item);
        }
Example #2
0
        public byte[] GetImage(string image)
        {
            Console.WriteLine("GetImage:" + image);
            string url = ServiceContainer.ServerAddress + "/image/getimage.html?image=" + image;

            return(MsHttpRestful.GetUrlEncodeBodyReturnBytes(url, null));
        }
Example #3
0
        private HtmlAgilityPack.HtmlDocument GetHtmlDocWithRetry(string url)
        {
            string html = MsHttpRestful.GetUrlEncodeBodyReturnString(url, null);

            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);
            return(doc);
        }
Example #4
0
        public static T DoPostWithUrl <T>(string url, IDictionary <string, object> para, IDictionary <string, string> headers = null) where T : ResponseBase
        {
            if (headers == null)
            {
                headers = new Dictionary <string, string>();
            }
            headers["session"] = ServiceContainer.AccessToken;
            string json = MsHttpRestful.PostJsonBodyReturnString(ServiceContainer.ServerAddress + "/" + url, para, Encoding.UTF8, headers);

            return(DeserializeObject <T>(json));
        }
Example #5
0
        public static object ConvertWeb(string value)
        {
            Dictionary <string, string> para = new Dictionary <string, string>();

            para["image"] = value;
            BitmapImage image = new BitmapImage();

            image.BeginInit();
            image.StreamSource = new MemoryStream(MsHttpRestful.GetUrlEncodeBodyReturnBytes(ServiceContainer.ServerAddress + "//image/getimage.html", para));
            image.EndInit();
            return(image);
        }
Example #6
0
        public static T DoPostFileWithUrl <T>(string url, IDictionary <string, string> para, byte[] file, IDictionary <string, string> headers = null) where T : ResponseBase
        {
            if (headers == null)
            {
                headers = new Dictionary <string, string>();
            }
            headers["session"] = ServiceContainer.AccessToken;
            string param = string.Join("&", para.Select(obj => obj.Key + "=" + MsHttpRestful.UrlEncode(obj.Value, Encoding.UTF8)));
            string json  = MsHttpRestful.PostBytesBodyReturnString(ServiceContainer.ServerAddress + "/" + url + "?" + param, file, Encoding.UTF8, headers);

            return(DeserializeObject <T>(json));
        }
Example #7
0
        private string[] UploadImage(Shop shop, string[] images)
        {
            SortedDictionary <string, string> param = new SortedDictionary <string, string>();

            string[] urls = new string[images.Length];
            for (int i = 0; i < images.Length; i++)
            {
                byte[] bytes  = MsHttpRestful.DoWithRetry(() => MsHttpRestful.GetUrlEncodeBodyReturnBytes(images[i], null));
                string base64 = Convert.ToBase64String(bytes, Base64FormattingOptions.None);
                param["image"] = "data:image/jpeg;base64," + base64;
                PddRspUploadImg ret = MsHttpRestful.DoWithRetry(() => Invoke <PddRspUploadImg>(shop, "pdd.goods.image.upload", param));
                urls[i] = ret.image_url;
            }
            return(urls);
        }
Example #8
0
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if ("不显示" == IMAGE_MODE)
            {
                return(DISABLEIMAGE);
            }

            string img = value as string;

            if (string.IsNullOrWhiteSpace(img))
            {
                return(EMPTYIMAGE);
            }

            try
            {
                if (img.StartsWith("//"))
                {
                    img = "http:" + img;
                }

                if (img.StartsWith("http"))
                {
                    BitmapImage image = new BitmapImage();
                    image.BeginInit();
                    image.StreamSource = new MemoryStream(MsHttpRestful.GetUrlEncodeBodyReturnBytes(img, null));
                    image.EndInit();
                    return(image);
                }

                if (string.IsNullOrWhiteSpace(IMAGE_MODE) || IMAGE_MODE == "内网")
                {
                    return(ConvertLocal(img));
                }
                else if (IMAGE_MODE == "外网")
                {
                    return(ConvertWeb(img));
                }
                else
                {
                    return(null);
                }
            }
            catch
            {
                return(READIMAGEERROR);
            }
        }
Example #9
0
        private static byte[] GetImage(string image)
        {
            if (string.IsNullOrWhiteSpace(image))
            {
                return(new byte[0]);
            }
            if ("abcdefghijklmnopqrstuvwxyz".Any(c => char.ToLower(image[0]) == c) && image[1] == ':')
            {
                return(File.ReadAllBytes(image));
            }

            if (image.StartsWith("http", StringComparison.OrdinalIgnoreCase) || image.StartsWith("ftp", StringComparison.OrdinalIgnoreCase))
            {
                return(MsHttpRestful.GetUrlEncodeBodyReturnBytes(image, null));
            }

            throw new Exception("无法处理的图片网址:" + image);
        }
Example #10
0
        private T Invoke <T>(Domain.Shop shop, string apiName, SortedDictionary <string, string> param, int trimJsonWrapperLevel = 1) where T : PddRspBase
        {
            string timeStamp = ((long)DateTime.UtcNow.Subtract(UNIX_START_TIME).TotalSeconds).ToString();

            param["type"]         = apiName;
            param["client_id"]    = shop.AppKey;
            param["access_token"] = shop.AppAccessToken;
            param["timestamp"]    = timeStamp;
            param["data_type"]    = "JSON";
            param["sign"]         = Sign(shop.AppSecret, param);
            var content = MsHttpRestful.PostUrlEncodeBodyReturnString(SERVER_URL, param);

            if (string.IsNullOrWhiteSpace(content))
            {
                throw new Exception("接口调用失败:返回空数据");
            }
            //去除PHP有可能产生的BOM头
            if (content[0] != '{')
            {
                if (content.IndexOf('{') < 0)
                {
                    throw new Exception("拼多多返回错误数据");
                }
                content = content.Substring(content.IndexOf('{'));
            }
            //去除内容头
            string bodyContent = TrimJsonWrapper(content, trimJsonWrapperLevel);
            var    t           = Newtonsoft.Json.JsonConvert.DeserializeObject <T>(bodyContent);

            if (string.IsNullOrWhiteSpace(t.error_code) == false)
            {
                if (t.error_msg.Contains("access_token已过期"))
                {
                    throw new PopAccesstokenTimeOutException();
                }
                if (t.error_msg.Contains("refresh_token已过期"))
                {
                    throw new Exception("拼多多调用失败:授权已到期,请到店铺里面进行授权");
                }
                Debug.WriteLine("请求参数:" + string.Join(Environment.NewLine, param.Select(obj => obj.Key + " " + obj.Value)));
                throw new Exception("拼多多调用失败:接口:" + apiName + " 错误信息" + t.error_code + "," + t.error_msg + "," + t.sub_msg);
            }
            return(t);
        }
Example #11
0
        public override Vendor GetVendorInfoByUrl(string url)
        {
            var vendor = new Vendor {
                Alias = "", AveragePrice = 0, Comment = "", Count = 0, CreateTime = DateTime.Now, HomePage = "", Id = 0, MarketAddress = "", MarketAddressShort = "", Name = "", PingyingName = "", Watch = false
            };
            string html = MsHttpRestful.GetUrlEncodeBodyReturnString(url, null);

            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);

            var title = doc.DocumentNode.SelectSingleNode("//div[@class='name']/a");

            if (title == null)
            {
                throw new Exception("未找到名称 //div[@class='name']/a");
            }
            vendor.Name     = title.InnerText.Trim();
            vendor.HomePage = title.GetAttributeValue("href", "").TrimEnd('/');

            var adds = doc.DocumentNode.SelectNodes("//div[@class = 'site_right']/div");

            if (adds == null || adds.Count < 1)
            {
                throw new Exception("未找到地址 div[@class = 'site_right']/div ");
            }
            foreach (var addN in adds)
            {
                var add = addN.InnerText.Trim().Replace(":", "").Replace(":", "").Replace(";", "").Replace(";", "").Replace("&nbsp", "");
                if (add.StartsWith("地址"))
                {
                    add = add.Substring(2);
                    vendor.MarketAddress = add.Trim();
                    break;
                }
            }

            return(vendor);
        }
Example #12
0
        public override Goods GetGoodsInfoByUrl(string url, ref string vendorHomePage, ref string videoUrl, bool raiseExceptionOnGoodsNotSale)
        {
            Goods g = new Goods {
                Comment = "", CreateTime = DateTime.Now, Image = "", Number = "", Price = 0, Type = 0, UpdateEnabled = true, UpdateTime = DateTime.Now, Url = url, VendorId = 0, Weight = 0, Id = 0, Colors = "", CreateOperator = "", Flag = ColorFlag.UN_LABEL, IgnoreEdtion = false, ImageDir = "", Material = "", Shops = new List <GoodsShop>(), Star = 0, VideoType = GoodsVideoType.NONE, Shipper = "WL"
            };
            string html = MsHttpRestful.GetUrlEncodeBodyReturnString(url, null);

            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);

            //厂家网址
            var title = doc.DocumentNode.SelectSingleNode("//div[@class='name']/a");

            if (title == null)
            {
                throw new Exception("未找到名称 //div[@class='name']/a");
            }
            vendorHomePage = title.GetAttributeValue("href", "").TrimEnd('/');

            //货号
            var hnNumber = doc.DocumentNode.SelectSingleNode("//div[@class='huohao']");

            if (hnNumber == null)
            {
                throw new Exception("未找到货号 //div[@class='huohao']");
            }
            g.Number = hnNumber.InnerText.Split(new string[] { "&amp;" }, StringSplitOptions.RemoveEmptyEntries)[1].Trim();

            //价格
            var hnPrice = doc.DocumentNode.SelectSingleNode("//span[@class='sku-price']");

            if (hnPrice == null)
            {
                throw new Exception("未找到价格 //span[@class='sku-price']");
            }
            g.Price = float.Parse(hnPrice.InnerText.Trim());

            //商品图片
            var hnImages = doc.DocumentNode.SelectSingleNode("//ul[@class='tb-thumb']/li/div/a/img");

            if (hnImages == null)
            {
                throw new Exception("未找到主图 //ul[@class='tb-thumb']/li/div/a/img");
            }
            g.Image = hnImages.GetAttributeValue("src", "");

            //类型
            var hnTypes = doc.DocumentNode.SelectNodes("//div[@class='category']/span");

            if (hnTypes == null || hnTypes.Count < 1)
            {
                throw new Exception("未找到类型结点 //div[@class='category']/span");
            }
            var type = hnTypes.First().InnerText.Replace("类型:", "");

            g.Type = EnumUtil.GetEnumValueByDesc <GoodsType>(type);
            //主图视频

            //颜色
            var hnColors = doc.DocumentNode.SelectNodes("//div[@class='default-color']/div/span/a");

            if (hnColors != null && hnColors.Count > 0)
            {
                string[] colors = hnColors.Select(obj => obj.InnerText.Trim()).ToArray();
                g.Colors = string.Join(",", colors);
            }
            else
            {
                hnColors = doc.DocumentNode.SelectNodes("//div[@class='color_box']/div/p");
                if (hnColors != null && hnColors.Count > 0)
                {
                    string[] colors = hnColors.Select(obj => obj.InnerText.Trim()).ToArray();
                    g.Colors = string.Join(",", colors);
                }
            }
            //帮面材质
            var hnPropertys = doc.DocumentNode.SelectNodes("//div[@class='shoes_info']/span[@class='text_box']");

            if (hnPropertys != null)
            {
                foreach (var v in hnPropertys)
                {
                    if (v.InnerText.Contains("帮面材质"))
                    {
                        var hnA = v.SelectSingleNode("a");
                        if (hnA != null)
                        {
                            g.Material = hnA.InnerText.Trim();
                            break;
                        }
                    }
                }
            }
            return(g);
        }
        private List <PopGoods> QueryHtmlGoodsPage(Shop shop, int pageIndex, PopGoodsState state)
        {
            Uri    goodsListPageUri     = new Uri(shop.PopType == PopType.TMALL ? "https://item.manager.tmall.com/tmall/manager/table.htm" : "https://item.publish.taobao.com/taobao/manager/table.htm");
            string goodsEditPageDomain  = shop.PopType == PopType.TMALL ? "item.upload.tmall.com" : "item.publish.taobao.com";
            string goodsEditPageUrlBase = shop.PopType == PopType.TMALL ? "https://item.upload.tmall.com/tmall/publish.htm?id=" : "https://item.publish.taobao.com/sell/publish.htm?itemId=";

            var goodsListPageXsrfCookieValue = CefCookieVisitor.GetCookieValues(goodsListPageUri.Host, "XSRF-TOKEN");

            if (string.IsNullOrWhiteSpace(goodsListPageXsrfCookieValue))
            {
                throw new Exception("没有找到相应XSRF-TOKEN,刷新页面重新登录");
            }
            var goodsListPageDomainCookie = CefCookieVisitor.GetCookieValues(goodsListPageUri.Host, null);

            if (string.IsNullOrWhiteSpace(goodsListPageDomainCookie))
            {
                throw new Exception("未找到域:" + goodsListPageUri.Host + " 的任何COOKIE ,刷新页面重新登录");
            }
            var    goodsEditPageCookie = CefCookieVisitor.GetCookieValues(goodsEditPageDomain, null);
            string goodsState          = state == PopGoodsState.NONE ? "all" : (state == PopGoodsState.ONSALE ? "on_sale" : "in_stock");
            var    xhrdata             = "jsonBody=" + MsHttpRestful.UrlEncode("{\"filter\":{},\"pagination\":{\"current\":" + pageIndex + ",\"pageSize\":20},\"table\":{\"sort\":{}},\"tab\":\"" + goodsState + "\"}", Encoding.UTF8);
            var    header = new Dictionary <string, string>();

            header.Add("X-XSRF-TOKEN", goodsListPageXsrfCookieValue.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[1]);

            var             content = MsHttpRestful.SendTbData(System.Net.Http.HttpMethod.Post, goodsListPageUri, header, goodsListPageDomainCookie, xhrdata);
            var             resp    = Newtonsoft.Json.JsonConvert.DeserializeObject <TaobaoQueryGoodsListResponse>(content);
            List <PopGoods> goods   = new List <PopGoods>();

            if (resp == null || resp.success == false)
            {
                throw new Exception("返回数据错误,请点击页面分页进行验证后重新开始");
            }
            if (resp.data.table.dataSource == null)
            {
                return(goods);
            }
            foreach (var g in resp.data.table.dataSource)
            {
                if (this.WaitGoOn() == false)
                {
                    break;
                }
                //每个商品获取的时候,都有可能,登录超时或者其它问题,需要循环
                PopGoods pg = null;
                string   goodsEditPageUrl = goodsEditPageUrlBase + g.itemId;

                for (int i = 0; i < 5; i++)
                {
                    if (this.WaitGoOn() == false)
                    {
                        break;
                    }
                    Debug.WriteLine("开始抓取商品:" + g.itemId);
                    this.OnDownload("暂停", true, "第:" + (i + 1) + " 次下载,第:" + pageIndex + "/" + ((resp.data.pagination.total / resp.data.pagination.pageSize) + 1) + "页,第" + (goods.Count + 1) + "条商品详情", false);
                    bool ret = QueryHtmlGoods(g, goodsEditPageUrl, goodsEditPageCookie, ref pg);
                    if (ret == true)
                    {
                        goods.Add(pg);
                        break;
                    }
                }
                if (this.isStop == false && pg == null)
                {
                    throw new Exception("抓取商品5次都为成功:" + g.itemId);
                }
                if (this.WaitGoOn() == false)
                {
                    break;
                }
                //每次等待3秒,太快淘宝会返回错误
                Thread.Sleep(3000);
            }
            return(goods);
        }
        private void BtnCheckImage_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var shop = this.cbbShops.SelectedItem as ShopErp.Domain.Shop;
                if (shop == null)
                {
                    throw new Exception("只有淘宝天猫可以进行匹配");
                }
                string tadgetDomainCookies = CefCookieVisitor.GetCookieValues("tadget.taobao.com", null);
                string tbToken             = CefCookieVisitor.GetCookieValues("tadget.taobao.com", "_tb_token_");
                if (string.IsNullOrWhiteSpace(tbToken))
                {
                    throw new Exception("获取_tb_token cookie 为空");
                }
                var    url       = new Uri("https://tadget.taobao.com/redaction/redaction/json.json?cmd=json_dirTree_query&count=true&_input_charset=utf-8&_tb_token_=" + tbToken.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[1]);
                string json      = MsHttpRestful.SendTbData(System.Net.Http.HttpMethod.Get, url, null, tadgetDomainCookies, null);
                var    rsp       = Newtonsoft.Json.JsonConvert.DeserializeObject <ImageRsp>(json);
                var    imageDirs = rsp.module.dirs.children.FirstOrDefault(obj => obj.name == "商品图片").children.Select(obj => obj.name).ToArray();
                var    allGoods  = ServiceContainer.GetService <GoodsService>().GetByAll((this.cbbShops.SelectedItem as Shop).Id, GoodsState.UPLOADED, 0, DateTime.MinValue, DateTime.MinValue, "", "", GoodsType.GOODS_SHOES_NONE, "", ColorFlag.None, GoodsVideoType.NONE, "", "", "", 0, 0).Datas.OrderBy(obj => obj.VendorId).ToList();
                var    vendors   = ServiceContainer.GetService <VendorService>().GetByAll("", "", "", "", 0, 0).Datas.ToList();

                List <ShopErp.Domain.Goods> unMatchGoods = new List <ShopErp.Domain.Goods>();
                List <string> unMatchDirs = new List <string>();

                foreach (var g in allGoods)
                {
                    var vendor = vendors.FirstOrDefault(obj => obj.Id == g.VendorId);
                    if (vendor == null)
                    {
                        throw new Exception("商品未找到对应厂家:" + g.Number + " 商品ID:" + g.Id);
                    }
                    if (string.IsNullOrWhiteSpace(vendor.PingyingName))
                    {
                        throw new Exception("厂家没有配置拼音:" + vendor.Name);
                    }
                    string nn = vendor.PingyingName.Trim() + "&" + g.Number.Trim();
                    var    pg = imageDirs.FirstOrDefault(obj => obj.IndexOf(nn, StringComparison.OrdinalIgnoreCase) >= 0);
                    if (pg == null)
                    {
                        unMatchGoods.Add(g);
                    }
                }

                foreach (var pg in imageDirs)
                {
                    string[] skus = pg.Split(',');
                    foreach (var code in skus)
                    {
                        string[] nn = code.Split('&');
                        var      g  = allGoods.FirstOrDefault(obj => obj.Number.Equals(nn[1], StringComparison.OrdinalIgnoreCase) && vendors.FirstOrDefault(o => o.Id == obj.VendorId).PingyingName.Equals(nn[0], StringComparison.OrdinalIgnoreCase));
                        if (g == null)
                        {
                            unMatchDirs.Add(pg);
                        }
                    }
                }
                if (unMatchGoods.Count > 0 || unMatchDirs.Count > 0)
                {
                    string msg1 = string.Join(",", unMatchGoods.Select(obj => vendors.FirstOrDefault(o => o.Id == obj.VendorId).Name + "&" + obj.Number));
                    string msg2 = string.Join(",", unMatchDirs);
                    string msg  = string.Format("系统中未在网站上匹配的:{0}\r\n,网站上未在系统中匹配的:{1}", msg1, msg2);
                    MessageBox.Show(msg);
                    Debug.WriteLine(msg);
                }
                else
                {
                    MessageBox.Show("完全匹配");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
Example #15
0
        /// <summary>
        /// </summary>
        /// <returns></returns>
        public void Print()
        {
            try
            {
                this.orderVmToOrder             = new Dictionary <Order, List <PrintOrderViewModel> >();
                this.IsUserStop                 = false;
                this.IsRunning                  = true;
                this.PrintButtonString          = "停止";
                this.WuliuPrintTemplate.XOffset = this.XOffset;
                this.WuliuPrintTemplate.YOffset = this.YOffset;
                string senderName  = ServiceContainer.GetService <SystemConfigService>().Get(-1, SystemNames.CONFIG_CAINIAO_SENDER_NAME, "");
                string senderPhone = ServiceContainer.GetService <SystemConfigService>().Get(-1, SystemNames.CONFIG_CAINIAO_SENDER_PHONE, "");

                if (string.IsNullOrWhiteSpace(senderName) || string.IsNullOrWhiteSpace(senderPhone))
                {
                    throw new Exception("系统中没有配置发货姓名和电话无法打印");
                }
                var selectedOrderVMs = this.OrderViewModels.Where(obj => obj.IsChecked).ToArray();
                var selectedOrders   = selectedOrderVMs.Select(obj => obj.Source).ToArray();
                if (selectedOrderVMs.Length < 1)
                {
                    throw new Exception("没有需要打印的订单");
                }

                this.WorkStateMessage = "第一步:正在检查是否打印过...";
                WPFHelper.DoEvents();
                foreach (var o in selectedOrderVMs)
                {
                    if (printHistoryService.GetByAll(o.Source.Id, "", "", 0, DateTime.Now.AddDays(-30), DateTime.Now, 0, 0).Total > 0)
                    {
                        o.State      = "已经打印过,请先删除打印历史";
                        o.Background = Brushes.Red;
                        throw new Exception("订单编号:" + o.Source.Id + " 已经打印过,请先删除打印历史");
                    }
                    WPFHelper.DoEvents();
                }

                this.WorkStateMessage = "第二步:正在重置当前打印数据...";
                WPFHelper.DoEvents();
                foreach (var v in selectedOrderVMs)
                {
                    v.WuliuNumber     = null;
                    v.DeliveryNumber  = "";
                    v.DeliveryCompany = "";
                    v.State           = "";
                    v.Background      = null;
                    WPFHelper.DoEvents();
                }

                this.WorkStateMessage = "第三步:正在合并订单数据...";
                WPFHelper.DoEvents();
                //在线支付,需要合并订单
                var mergedOrders = new List <Order>();
                if (selectedOrders[0].PopPayType == PopPayType.ONLINE)
                {
                    //合并相同订单
                    foreach (var or in selectedOrders)
                    {
                        if (this.IsUserStop)
                        {
                            throw new Exception("用户已停止打印");
                        }
                        WPFHelper.DoEvents();
                        var first = mergedOrders.FirstOrDefault(obj => HasSameReceiverInfo(or, obj));
                        if (first == null)
                        {
                            mergedOrders.Add(or);
                            List <PrintOrderViewModel> vms = new List <PrintOrderViewModel>();
                            vms.Add(this.OrderViewModels.First(obj => obj.Source.Id == or.Id));
                            orderVmToOrder.Add(or, vms);
                        }
                        else
                        {
                            //合并商品,订单可能被重复打印,以前合并过的,不再合并
                            foreach (var og in or.OrderGoodss)
                            {
                                if (first.OrderGoodss.Any(obj => obj.Id == og.Id) == false)
                                {
                                    first.OrderGoodss.Add(og);
                                }
                            }
                            orderVmToOrder[first].Add(this.OrderViewModels.First(obj => obj.Source.Id == or.Id));
                        }
                    }
                }
                else
                {
                    mergedOrders.AddRange(selectedOrders);
                    foreach (var mo in mergedOrders)
                    {
                        orderVmToOrder.Add(mo, this.OrderViewModels.Where(obj => obj.Source.Id == mo.Id).ToList());
                    }
                }
                //生成快递单号
                var wuliuNumbers = new WuliuNumber[mergedOrders.Count];
                for (int i = 0; i < wuliuNumbers.Length; i++)
                {
                    if (this.IsUserStop)
                    {
                        throw new Exception("用户已停止打印");
                    }

                    try
                    {
                        this.WorkStateMessage = string.Format("第四步:正在获取快递单号{0}/{1}...", i + 1, wuliuNumbers.Length);
                        WPFHelper.DoEvents();
                        wuliuNumbers[i] = ServiceContainer.GetService <WuliuNumberService>().GenWuliuNumber(this.Shop, this.WuliuPrintTemplate, mergedOrders[i], GetMatchOrderViewModelsWuliuId(mergedOrders[i]), this.PackageId > 0 ? this.PackageId.ToString() : "", senderName, senderPhone, this.WuliuBranch.SenderAddress).First;
                        foreach (var ov in this.orderVmToOrder[mergedOrders[i]])
                        {
                            ov.WuliuNumber     = wuliuNumbers[i];
                            ov.DeliveryCompany = wuliuNumbers[i].DeliveryCompany;
                            ov.DeliveryNumber  = wuliuNumbers[i].DeliveryNumber;
                            ov.State           = "";
                            ov.PageNumber      = i + 1;
                        }
                    }
                    catch (Exception ex)
                    {
                        var vms = this.orderVmToOrder[mergedOrders[i]];
                        foreach (var v in vms)
                        {
                            v.State      = ex.Message;
                            v.Background = Brushes.Red;
                        }
                        throw;
                    }
                }

                var allShops = ServiceContainer.GetService <ShopService>().GetByAll().Datas;
                var vs       = ServiceContainer.GetService <VendorService>();
                //生成自定义打印数据
                var userDatas = new Dictionary <string, string> [mergedOrders.Count];
                for (int i = 0; i < userDatas.Length; i++)
                {
                    if (this.IsUserStop)
                    {
                        throw new Exception("用户已停止打印");
                    }

                    this.WorkStateMessage = string.Format("第五步:正在生成自定义数据{0}/{1}...", i + 1, wuliuNumbers.Length);
                    WPFHelper.DoEvents();
                    userDatas[i] = new Dictionary <string, string>();
                    StringBuilder goods_commment = new StringBuilder();
                    if (mergedOrders[i].Type == OrderType.NORMAL)
                    {
                        if (mergedOrders[i].OrderGoodss != null && mergedOrders[i].OrderGoodss.Count > 0)
                        {
                            foreach (var goods in mergedOrders[i].OrderGoodss.Where(obj => (int)obj.State <= (int)OrderState.SUCCESS))
                            {
                                goods_commment.AppendLine(vs.GetVendorPingyingName(goods.Vendor).ToUpper() + " " + goods.Number + " " + goods.Edtion + " " + goods.Color + " " + goods.Size + " (" + goods.Count + ")");
                            }
                        }
                        if (mergedOrders[i].PopPayType != PopPayType.COD)
                        {
                            goods_commment.AppendLine(mergedOrders[i].PopSellerComment);
                        }
                    }
                    userDatas[i].Add("goodsInfoSellerComment", goods_commment.ToString());
                    userDatas[i].Add("suminfo", string.Format("店:{0},数:{1},付:{2}", allShops.FirstOrDefault(obj => obj.Id == mergedOrders[i].ShopId).Mark, mergedOrders[i].OrderGoodss.Select(obj => obj.Count).Sum().ToString(), mergedOrders[i].PopPayTime.ToString("yyyy-MM-dd HH:mm:ss")));
                }

                this.WorkStateMessage = string.Format("第六步:输出打印数据...");
                WPFHelper.DoEvents();
                this.printDoc = new CainiaoPrintDocument(mergedOrders.ToArray(), wuliuNumbers, userDatas, this.WuliuPrintTemplate);
                string file = printDoc.StartPrint(this.Printer, this.PrintServerAdd);
                this.WorkStateMessage = string.Format("第七步:保存打印记录...");
                WPFHelper.DoEvents();
                UploadPrintHistory(selectedOrderVMs);
                HandelPrintEnded();
                if (this.WuliuPrintTemplate.SourceType == WuliuPrintTemplateSourceType.CAINIAO)
                {
                    LocalConfigService.UpdateValue(SystemNames.CONFIG_PRINTSERVERADD_CAINIAO, this.PrintServerAdd);
                }
                else if (this.WuliuPrintTemplate.SourceType == WuliuPrintTemplateSourceType.PINDUODUO)
                {
                    LocalConfigService.UpdateValue(SystemNames.CONFIG_PRINTSERVERADD_PDD, this.PrintServerAdd);
                }
                if (string.IsNullOrWhiteSpace(file) == false && file.StartsWith("http"))
                {
                    //下载文件
                    byte[] content = MsHttpRestful.GetUrlEncodeBodyReturnBytes(file, null);
                    Microsoft.Win32.SaveFileDialog sfd = new Microsoft.Win32.SaveFileDialog();
                    sfd.AddExtension     = true;
                    sfd.DefaultExt       = "pdf";
                    sfd.Filter           = "*.pdf|PDF 文件";
                    sfd.FileName         = "快递单 " + this.WuliuPrintTemplate.DeliveryCompany + " " + DateTime.Now.ToString("MM-dd") + ".pdf";
                    sfd.InitialDirectory = LocalConfigService.GetValue("PrintFileSaveDir_" + this.shipper, "");
                    if (sfd.ShowDialog().Value == false)
                    {
                        return;
                    }
                    File.WriteAllBytes(sfd.FileName, content);
                    LocalConfigService.UpdateValue("PrintFileSaveDir_" + this.shipper, new FileInfo(sfd.FileName).DirectoryName);
                }
                LocalConfigService.UpdateValue(SystemNames.CONFIG_PRINTER_DELIVERY_HOT, this.Printer);
                var    offsets   = LocalConfigService.GetValue(SystemNames.CONFIG_PRINT_OFFSETS, "").Split(new string[] { "###" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                string url       = this.WuliuPrintTemplate.UserOrIsvTemplateAreaUrl ?? this.WuliuPrintTemplate.StandTemplateUrl;
                string urlOffset = url + "," + XOffset + "," + YOffset;
                offsets.RemoveAll(obj => obj.Contains(url));
                offsets.Add(urlOffset);
                string strOffsets = string.Join("###", offsets);
                LocalConfigService.UpdateValue(SystemNames.CONFIG_PRINT_OFFSETS, strOffsets);
            }
            finally
            {
                HandelPrintEnded();
            }
        }
        private bool QueryHtmlGoods(TaobaoQueryGoodsListResponseDataTableDataSource g, string url, string cookie, ref PopGoods popGoods)
        {
            string htmlContent = MsHttpRestful.SendTbData(System.Net.Http.HttpMethod.Get, new Uri(url), null, cookie, null);

            if (string.IsNullOrWhiteSpace(htmlContent))
            {
                throw new Exception("读取商品详情返回为空:" + g.itemId);
            }

            try
            {
                if (htmlContent[0] == '{' && htmlContent.Last() == '}')
                {
                    var error = Newtonsoft.Json.JsonConvert.DeserializeObject <TaobaoQueryGoodsDetailErrorResponse>(htmlContent);
                    if (error.success == false)
                    {
                        if ("SYS_REQUEST_TOO_FAST".Equals(error.code, StringComparison.OrdinalIgnoreCase))
                        {
                            int wait = error.data == null ? 70 : error.data.wait + 10;
                            this.Pause(false, "程序读取商品详情过快,等待:" + wait + "秒", wait);
                            return(false);
                        }
                        else
                        {
                            Log.Logger.Log("获取淘宝详情失败,错误信息:" + htmlContent);
                            throw new Exception("获取淘宝详情失败,错误信息:" + error.code + "," + error.msg);
                        }
                    }
                }
            }
            catch (Newtonsoft.Json.JsonException)
            {
            }

            if (htmlContent.Contains("客官别急") && htmlContent.Contains("交通拥堵"))
            {
                Debug.WriteLine(DateTime.Now + "检测到返回网页操作过快");
                this.Pause(false, "程序读取商品详情过快,等待:70 秒", 70);
                return(false);
            }

            //第一步找JS JSON 起始符
            int startIndex = htmlContent.IndexOf("window.Json =");

            if (startIndex < 0)
            {
                Debug.WriteLine("商品详情:" + g.itemId + ":" + htmlContent);
                throw new Exception("分析商品编辑页失败,未找到window.Json =:" + g.itemId);
            }

            //第二步,找JSON开始符
            startIndex = htmlContent.IndexOf("{\"", startIndex);
            if (startIndex < 0)
            {
                Debug.WriteLine("商品详情:" + g.itemId + ":" + htmlContent);
                throw new Exception("分析商品编辑页失败,未找到window.Json =:之后的{\"" + g.itemId);
            }
            startIndex = htmlContent.IndexOf("{\"", startIndex);

            //第三步找JSON结尾字符串
            int end = htmlContent.IndexOf("}}};", startIndex);

            if (end <= 0)
            {
                Debug.WriteLine("商品详情:" + g.itemId + ":" + htmlContent);
                throw new Exception("分析商品编辑页失败,未找到JSON结束符}}};" + g.itemId);
            }
            string json        = htmlContent.Substring(startIndex, end + 3 - startIndex);
            var    goodsDetail = Newtonsoft.Json.JsonConvert.DeserializeObject <TaobaoQueryGoodsDetailResponse>(json);
            var    pg          = new PopGoods {
                AddTime = "", CatId = g.catId, Code = goodsDetail.models.formValues.outerId, Id = g.itemId, Images = goodsDetail.models.formValues.images.Select(obj => obj.url.StartsWith("http") ? obj.url : "https:" + obj.url).ToArray(), SaleNum = g.soldQuantity_m, UpdateTime = g.upShelfDate_m.value
            };

            //状态
            pg.State = g.upShelfDate_m.status.text == "出售中" ? PopGoodsState.ONSALE : PopGoodsState.NOTSALE;
            pg.Title = g.itemDesc.desc.FirstOrDefault(obj => string.IsNullOrWhiteSpace(obj.href) == false).text.Trim();

            //SKU
            foreach (var vSku in goodsDetail.models.formValues.sku)
            {
                var pSku = new PopGoodsSku
                {
                    Code   = vSku.skuOuterId ?? "",
                    Id     = vSku.skuId ?? "",
                    Stock  = vSku.skuStock.ToString(),
                    Price  = vSku.skuPrice.ToString("F2"),
                    Status = PopGoodsState.ONSALE,
                    Color  = vSku.props[0].text.Trim(),
                    Size   = vSku.props[1].text.Trim(),
                };
                if (vSku.skuImage != null && vSku.skuImage.Length > 0)
                {
                    pSku.Image = vSku.skuImage[0].url;
                }
                else
                {
                    pSku.Image = goodsDetail.models.formValues.saleProp.Colors.FirstOrDefault(obj => obj.text == pSku.Color).img;
                }

                if (string.IsNullOrWhiteSpace(pSku.Image))
                {
                    throw new Exception("商品SKU图片为空:" + pg.Id);
                }
                if (pSku.Image.StartsWith("http") == false)
                {
                    pSku.Image = "https:" + pSku.Image;
                }
                pg.Skus.Add(pSku);
            }
            //属性 天猫
            //基本属性
            if (goodsDetail.models.formValues.bindProp != null)
            {
                foreach (var v in goodsDetail.models.formValues.bindProp)
                {
                    string key    = goodsDetail.models.bindProp.dataSource.First(obj => obj.name == v.name).label;
                    string values = string.Join("@#@", v.values.Select(obj => obj.text));
                    pg.Properties.Add(new KeyValuePairClass <string, string>(key, values));
                }
            }
            if (goodsDetail.models.formValues.itemProp != null)
            {
                foreach (var v in goodsDetail.models.formValues.itemProp)
                {
                    string key    = goodsDetail.models.itemProp.dataSource.First(obj => obj.name == v.name).label;
                    string values = string.Join("@#@", v.values.Select(obj => obj.text));
                    pg.Properties.Add(new KeyValuePairClass <string, string>(key, values));
                }
            }

            if (goodsDetail.models.formValues.catProp != null)
            {
                foreach (var v in goodsDetail.models.formValues.catProp)
                {
                    string key    = goodsDetail.models.catProp.dataSource.First(obj => obj.name == v.name).label;
                    string values = string.Join("@#@", v.values.Select(obj => obj.text));
                    pg.Properties.Add(new KeyValuePairClass <string, string>(key, values));
                }
            }
            pg.PopType      = shop.PopType;
            pg.Type         = goodsDetail.models.catpath.value.Split(new string[] { ">>", "》" }, StringSplitOptions.RemoveEmptyEntries)[1];
            pg.ShippingCity = goodsDetail.models.formValues.location != null ? goodsDetail.models.formValues.location.value.text : goodsDetail.models.global.location.city;
            if (shop.PopType == PopType.TMALL && (goodsDetail.models.formValues.modularDesc == null || goodsDetail.models.formValues.modularDesc.Length < 1))
            {
                throw new Exception("商品:" + g.itemId + " 电脑端描述为空");
            }
            if (shop.PopType == PopType.TAOBAO && string.IsNullOrWhiteSpace(goodsDetail.models.formValues.desc))
            {
                throw new Exception("商品:" + g.itemId + " 电脑端描述为空");
            }

            //详情图片
            pg.DescImages = ParseImages(shop.PopType == PopType.TMALL ? goodsDetail.models.formValues.modularDesc.First().content : goodsDetail.models.formValues.desc);
            popGoods      = pg;
            return(true);
        }
        private void MarkPopDelivery(string popOrderId, string deliveryCompany, string deliveryNumber)
        {
            string formId    = "//form[@id = 'orderForm']";
            string inputMark = "input";
            //第一步读取页面信息
            var    uri     = new Uri("https://wuliu.taobao.com/user/consign.htm?trade_id=" + popOrderId);
            string cookies = CefCookieVisitor.GetCookieValues(uri.Host, null);
            string html    = MsHttpRestful.SendTbData(System.Net.Http.HttpMethod.Get, uri, null, cookies, null);

            //第二步 提取数据
            Dictionary <string, string> paras = new Dictionary <string, string>();

            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);

            var form = doc.DocumentNode.SelectSingleNode(formId);

            if (form == null)
            {
                Debug.WriteLine(form);
                throw new Exception("未在页面中找到:" + formId);
            }

            var inputNodes = doc.DocumentNode.SelectNodes("//input");

            if (inputNodes == null || inputNodes.Count < 1)
            {
                throw new Exception("未找到任何:" + inputMark + " 元素");
            }

            foreach (var v in inputNodes)
            {
                if (string.IsNullOrWhiteSpace(v.GetAttributeValue("name", "")))
                {
                    continue;
                }
                paras[v.GetAttributeValue("name", "")] = v.GetAttributeValue("value", "");
            }
            paras.Remove("q");
            paras.Remove("type");
            paras.Remove("cat");
            paras["companyName"] = "请输入物流公司名称";
            paras["event_submit_do_offline_consign"] = "1";
            paras["offlineNewFlag"]   = "1";
            paras["_fmw.r._0.c"]      = paras["receiverContactName"];
            paras["_fmw.r._0.adr"]    = paras["receiverDetail"];
            paras["_fmw.f._0.fe"]     = "";
            paras["_fmw.f._0.fet"]    = "";
            paras["_fmw.n._0.g"]      = "您可以在此输入备忘信息(仅卖家自己可见)。";
            paras["initialWeightOld"] = "all";
            //进行几种常见错误的检测
            if (paras.ContainsKey("receiverZipCode") == false || paras["receiverZipCode"].Length != 6)
            {
                throw new Exception("邮政编码不为6位,当前值:" + paras["receiverZipCode"]);
            }
            if (paras.ContainsKey("receiverDetail") == false || paras["receiverDetail"].Length < 4)
            {
                throw new Exception("详细地址必须大于等于4个字,当前值:" + paras["receiverDetail"]);
            }

            paras["mailNo"]      = deliveryNumber;
            paras["companyCode"] = deliveryCompany;

            //生成数据,该页面使用GBK编码
            List <string> ss            = paras.Select(obj => obj.Key + "=" + MsHttpRestful.UrlEncode(obj.Value, Encoding.GetEncoding("GBK"))).ToList();
            string        urlEncodeData = string.Join("&", ss);
            string        ret           = MsHttpRestful.SendTbData(System.Net.Http.HttpMethod.Post, uri, null, cookies, urlEncodeData);

            if (ret.Contains("恭喜您,操作成功"))
            {
                return;
            }
            if (ret.Contains("运单号不符合规则或已经被使用"))
            {
                throw new Exception("运单号不符合规则或已经被使用");
            }
            throw new Exception("返回页面数据无法识别,请查看相应结果");
        }