/// <summary>
        /// 获取周边门店-分页
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public QueryPageModel <ShopBranchInfo> GetNearShopBranchs(CommonModel.ShopBranchQuery query)
        {
            decimal latitude = 0, longitude = 0;

            if (query.FromLatLng.Split(',').Length != 2)
            {
                return(new QueryPageModel <ShopBranchInfo>());
            }
            latitude  = TypeHelper.ObjectToDecimal(query.FromLatLng.Split(',')[0]);
            longitude = TypeHelper.ObjectToDecimal(query.FromLatLng.Split(',')[1]);

            QueryPageModel <ShopBranchInfo> result = new QueryPageModel <ShopBranchInfo>();
            DynamicParameters parms                = new DynamicParameters();
            string            countsql             = "select count(1) from himall_shopbranch ";
            string            sql                  = string.Format("select AddressDetail,AddressPath,ContactPhone,Id,ShopBranchName,Status,Latitude,Longitude,truncate(6378.137*2*ASIN(SQRT(POW(SIN(({0}*PI()/180.0-Latitude*PI()/180.0)/2),2)+COS({0}*PI()/180.0)*COS(Latitude*PI()/180.0)*POW(SIN(({1}*PI()/180.0-Longitude*PI()/180.0)/2),2))),2) AS Distance from himall_shopbranch", latitude, longitude);

            string where = GetSearchWhere(query, parms);
            string order = GetSearchOrder(query);

            if (query.OrderKey == 2)
            {
                order = string.Format(" {0}, id desc ", order.TrimEnd(','));//如果存在相同距离,则按ID再次排序
            }
            //暂时不考虑索引
            string page = GetSearchPage(query);

            using (MySqlConnection conn = new MySqlConnection(Connection.ConnectionString))
            {
                result.Models = conn.Query <ShopBranchInfo>(string.Concat(sql, where, order, page), parms).ToList();
                result.Total  = int.Parse(conn.ExecuteScalar(string.Concat(countsql, where), parms).ToString());
            }
            return(result);
        }
        /// <summary>
        /// 获取该商品所在商家下距离用户最近的门店
        /// </summary>
        /// <param name="shopId">商家ID</param>
        /// <returns></returns>
        public object GetStroreInfo(long shopId, long productId, string fromLatLng = "")
        {
            if (shopId <= 0)
            {
                return(Json(new { Success = false, Message = "请传入合法商家ID" }));
            }
            if (!(fromLatLng.Split(',').Length == 2))
            {
                return(Json(new { Success = false, Message = "您当前定位信息异常" }));
            }

            var query = new CommonModel.ShopBranchQuery()
            {
                ShopId     = shopId,
                FromLatLng = fromLatLng,
                Status     = CommonModel.ShopBranchStatus.Normal
            };
            //商家下门店总数
            int total = ShopBranchApplication.GetShopBranchsAll(query).Models.Where(p => (p.Latitude > 0 && p.Longitude > 0)).ToList().Count;

            //商家下有该产品的且距离用户最近的门店
            query.ProductIds = new long[] { productId };
            var shopBranch = ShopBranchApplication.GetShopBranchsAll(query).Models.Where(p => (p.Latitude > 0 && p.Longitude > 0)).OrderBy(p => p.Distance).Take(1).FirstOrDefault <Himall.DTO.ShopBranch>();
            var result     = new
            {
                Success   = true,
                StoreInfo = shopBranch,
                Total     = total
            };

            return(Json(result));
        }
        private IQueryable <ShopBranchInfo> ToWhere(CommonModel.ShopBranchQuery query)
        {
            var shopBranchs = Context.ShopBranchInfo.Where(p => true);

            if (query.Id > 0)
            {
                shopBranchs = shopBranchs.Where(p => p.Id == query.Id); //查询单个门店的时候要用到
            }
            if (query.ShopId > 0)                                       //取商家下的门店数据
            {
                shopBranchs = shopBranchs.Where(p => p.ShopId == query.ShopId);
            }
            if (query.CityId > 0)//同城市的门店 省,市,区,街
            {
                shopBranchs = shopBranchs.Where(p => p.AddressPath.Contains(CommonConst.ADDRESS_PATH_SPLIT + query.CityId + CommonConst.ADDRESS_PATH_SPLIT));
            }

            if (!string.IsNullOrWhiteSpace(query.ShopBranchName))
            {
                shopBranchs = shopBranchs.Where(e => e.ShopBranchName.Contains(query.ShopBranchName));
            }
            if (!string.IsNullOrWhiteSpace(query.ContactUser))
            {
                shopBranchs = shopBranchs.Where(e => e.ContactUser.Contains(query.ContactUser));
            }
            if (!string.IsNullOrWhiteSpace(query.ContactPhone))
            {
                shopBranchs = shopBranchs.Where(e => e.ContactPhone.Contains(query.ContactPhone));
            }
            if (query.Status.HasValue)
            {
                var status = query.Status.Value;
                shopBranchs = shopBranchs.Where(e => e.Status == status);
            }
            if (!string.IsNullOrWhiteSpace(query.AddressPath))
            {
                var addressPath = query.AddressPath;
                if (!addressPath.EndsWith(CommonConst.ADDRESS_PATH_SPLIT))
                {
                    addressPath += CommonConst.ADDRESS_PATH_SPLIT;
                }
                shopBranchs = shopBranchs.Where(p => p.AddressPath.StartsWith(addressPath));
            }
            if (query.ProductIds != null && query.ProductIds.Length > 0)
            {
                var pids   = query.ProductIds.Distinct().ToArray();
                var length = pids.Length;

                var shopBranchIds = this.Context.ShopBranchSkusInfo.Where(p => p.ShopId == query.ShopId && pids.Contains(p.ProductId))
                                    .GroupBy(p => new { p.ShopBranchId, p.ProductId })
                                    .GroupBy(p => p.Key.ShopBranchId)
                                    .Where(p => p.Count() == length)
                                    .Select(p => p.Key);

                shopBranchs = shopBranchs.Where(p => shopBranchIds.Contains(p.Id));
            }

            return(shopBranchs);
        }
        /// <summary>
        /// 是否可允许自提门店
        /// </summary>
        /// <param name="shopId">商家ID</param>
        /// <returns></returns>
        public object GetIsSelfDelivery(long shopId, long productId, string fromLatLng = "")
        {
            if (shopId <= 0)
            {
                return(Json(new { Message = "请传入合法商家ID", IsSelfDelivery = 0 }));
            }
            if (!(fromLatLng.Split(',').Length == 2))
            {
                return(Json(new { Message = "请传入合法经纬度", IsSelfDelivery = 0 }));
            }

            var query = new CommonModel.ShopBranchQuery()
            {
                ShopId = shopId,
                Status = CommonModel.ShopBranchStatus.Normal
            };
            string address = "", province = "", city = "", district = "", street = "";

            ShopbranchHelper.GetAddressByLatLng(fromLatLng, ref address, ref province, ref city, ref district, ref street);
            if (string.IsNullOrWhiteSpace(city))
            {
                return(Json(new { Message = "无法获取当前城市", IsSelfDelivery = 0 }));
            }

            Region cityInfo = RegionApplication.GetRegionByName(city, Region.RegionLevel.City);

            if (cityInfo == null)
            {
                return(Json(new { Message = "获取当前城市异常", IsSelfDelivery = 0 }));
            }
            query.CityId     = cityInfo.Id;
            query.ProductIds = new long[] { productId };

            var shopBranch = ShopBranchApplication.GetShopBranchsAll(query).Models; //获取该商品所在商家下,且与用户同城内门店,且门店有该商品
            var skuInfos   = ProductManagerApplication.GetSKU(productId);           //获取该商品的sku

            //门店SKU内会有默认的SKU
            if (!skuInfos.Exists(p => p.Id == string.Format("{0}_0_0_0", productId)))
            {
                skuInfos.Add(new DTO.SKU()
                {
                    Id = string.Format("{0}_0_0_0", productId)
                });
            }
            var shopBranchSkus = ShopBranchApplication.GetSkus(query.ShopId, shopBranch.Select(p => p.Id));//门店商品SKU

            //门店商品SKU,只要有一个sku有库存即可
            shopBranch.ForEach(p =>
                               p.Enabled = skuInfos.Where(skuInfo => shopBranchSkus.Where(sbSku => sbSku.ShopBranchId == p.Id && sbSku.Stock > 0 && sbSku.SkuId == skuInfo.Id).Count() > 0).Count() > 0
                               );

            return(Json(new { Message = "", IsSelfDelivery = shopBranch.Where(p => p.Enabled).Count() > 0 ? 1 : 0 }));//至少有一个能够自提的门店,才可显示图标
        }
        public QueryPageModel <ShopBranchInfo> GetShopBranchs(CommonModel.ShopBranchQuery query)
        {
            int total       = 0;
            var shopBranchs = ToWhere(query);

            shopBranchs = shopBranchs.GetPage(out total, query.PageNo, query.PageSize, s => s.OrderBy(e => e.Id));
            QueryPageModel <ShopBranchInfo> pageModel = new QueryPageModel <ShopBranchInfo>()
            {
                Models = shopBranchs.ToList(), Total = total
            };

            return(pageModel);
        }
        public JsonResult ExistShopBranch(int shopId, int regionId, long[] productIds)
        {
            var query = new CommonModel.ShopBranchQuery();

            query.Status = CommonModel.ShopBranchStatus.Normal;
            query.ShopId = shopId;

            var region = RegionApplication.GetRegion(regionId, CommonModel.Region.RegionLevel.City);

            query.AddressPath = region.GetIdPath();
            query.ProductIds  = productIds;
            var existShopBranch = ShopBranchApplication.Exists(query);

            return(Json(existShopBranch, JsonRequestBehavior.AllowGet));
        }
        /// <summary>
        /// 是否允许门店自提
        /// </summary>
        /// <param name="shopId"></param>
        /// <param name="regionId"></param>
        /// <param name="productIds"></param>
        /// <returns></returns>
        public object GetExistShopBranch(long shopId, long regionId, string productIds)
        {
            var query = new CommonModel.ShopBranchQuery();

            query.Status = CommonModel.ShopBranchStatus.Normal;
            query.ShopId = shopId;

            var region = RegionApplication.GetRegion(regionId, CommonModel.Region.RegionLevel.City);

            query.AddressPath = region.GetIdPath();
            query.ProductIds  = productIds.Split(',').Select(p => long.Parse(p)).ToArray();
            var existShopBranch = ShopBranchApplication.Exists(query);

            return(Json(new { Success = true, ExistShopBranch = existShopBranch ? 1 : 0 }));
        }
        private void InitOrderSubmitModel(DTO.OrderSubmitModel model)
        {
            if (model.address != null)
            {
                var query = new CommonModel.ShopBranchQuery();
                query.Status = CommonModel.ShopBranchStatus.Normal;

                var region = RegionApplication.GetRegion(model.address.RegionId, CommonModel.Region.RegionLevel.City);
                query.AddressPath = region.GetIdPath();

                foreach (var item in model.products)
                {
                    query.ShopId         = item.shopId;
                    query.ProductIds     = item.freightProductGroup.Select(p => p.ProductId).ToArray();
                    item.ExistShopBranch = ShopBranchApplication.Exists(query);
                }
            }
        }
        /// <summary>
        /// 周边门店匹配查询条件
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        private IQueryable <ShopBranchInfo> ToNearShopWhere(CommonModel.ShopBranchQuery query)
        {
            var shopBranchs = Context.ShopBranchInfo.Where(p => p.Longitude > 0 && p.Latitude > 0); //周边门店只取定位了经纬度的数据

            if (query.ShopId > 0)                                                                   //取商家下的门店数据
            {
                shopBranchs = shopBranchs.Where(p => p.ShopId == query.ShopId);
            }
            if (query.CityId > 0)//同城门店
            {
                shopBranchs = shopBranchs.Where(p => p.AddressPath.Contains(CommonConst.ADDRESS_PATH_SPLIT + query.CityId + CommonConst.ADDRESS_PATH_SPLIT));
            }
            if (query.Status.HasValue)
            {
                shopBranchs = shopBranchs.Where(e => e.Status == query.Status.Value);
            }
            return(shopBranchs);
        }
        public QueryPageModel <ShopBranchInfo> GetShopBranchsAll(CommonModel.ShopBranchQuery query)
        {
            var shopBranchs = ToWhere(query).ToList();

            shopBranchs.ForEach(p =>
            {
                if (p.Latitude.HasValue && p.Longitude.HasValue && p.Latitude.Value > 0 && p.Longitude.Value > 0)
                {
                    p.Distance = GetLatLngDistancesFromAPI(query.FromLatLng, string.Format("{0},{1}", p.Latitude, p.Longitude));
                }
                else
                {
                    p.Distance = 0;
                }
            });
            return(new QueryPageModel <ShopBranchInfo>()
            {
                Models = shopBranchs.AsQueryable().OrderBy(p => p.Distance).ToList()
            });
        }
        /// <summary>
        /// 获取自提门店点
        /// </summary>
        /// <returns></returns>
        public object GetShopBranchs(long shopId, bool getParent, string skuIds, string counts, int page, int rows, long shippingAddressId, long regionId)
        {
            string[] _skuIds = skuIds.Split(',');
            int[]    _counts = counts.Split(',').Select(p => Himall.Core.Helper.TypeHelper.ObjectToInt(p)).ToArray();

            var shippingAddressInfo = ShippingAddressApplication.GetUserShippingAddress(shippingAddressId);
            int streetId = 0, districtId = 0;//收货地址的街道、区域

            var query = new CommonModel.ShopBranchQuery()
            {
                ShopId   = shopId,
                PageNo   = page,
                PageSize = rows,
                Status   = CommonModel.ShopBranchStatus.Normal
            };

            if (shippingAddressInfo != null)
            {
                query.FromLatLng = string.Format("{0},{1}", shippingAddressInfo.Latitude, shippingAddressInfo.Longitude); //需要收货地址的经纬度
                streetId         = shippingAddressInfo.RegionId;
                var parentAreaInfo = RegionApplication.GetRegion(shippingAddressInfo.RegionId, Region.RegionLevel.Town);  //判断当前区域是否为第四级
                if (parentAreaInfo != null && parentAreaInfo.ParentId > 0)
                {
                    districtId = parentAreaInfo.ParentId;
                }
                else
                {
                    districtId = streetId; streetId = 0;
                }
            }
            bool hasLatLng = false;

            if (!string.IsNullOrWhiteSpace(query.FromLatLng))
            {
                hasLatLng = query.FromLatLng.Split(',').Length == 2;
            }

            var region = RegionApplication.GetRegion(regionId, getParent ? CommonModel.Region.RegionLevel.City : CommonModel.Region.RegionLevel.County);//同城内门店

            if (region != null)
            {
                query.AddressPath = region.GetIdPath();
            }

            #region 3.0版本排序规则
            var skuInfos = ProductManagerApplication.GetSKUs(_skuIds);
            query.ProductIds = skuInfos.Select(p => p.ProductId).ToArray();
            var data           = ShopBranchApplication.GetShopBranchsAll(query);
            var shopBranchSkus = ShopBranchApplication.GetSkus(shopId, data.Models.Select(p => p.Id));//获取该商家下具有订单内所有商品的门店状态正常数据,不考虑库存
            data.Models.ForEach(p =>
            {
                p.Enabled = skuInfos.All(skuInfo => shopBranchSkus.Any(sbSku => sbSku.ShopBranchId == p.Id && sbSku.Stock >= _counts[skuInfos.IndexOf(skuInfo)] && sbSku.SkuId == skuInfo.Id));
            });

            List <Himall.DTO.ShopBranch> newList = new List <Himall.DTO.ShopBranch>();
            List <long> fillterIds  = new List <long>();
            var         currentList = data.Models.Where(p => hasLatLng && p.Enabled && (p.Latitude > 0 && p.Longitude > 0)).OrderBy(p => p.Distance).ToList();
            if (currentList != null && currentList.Count() > 0)
            {
                fillterIds.AddRange(currentList.Select(p => p.Id));
                newList.AddRange(currentList);
            }
            var currentList2 = data.Models.Where(p => !fillterIds.Contains(p.Id) && p.Enabled && p.AddressPath.Contains(CommonConst.ADDRESS_PATH_SPLIT + streetId + CommonConst.ADDRESS_PATH_SPLIT)).ToList();
            if (currentList2 != null && currentList2.Count() > 0)
            {
                fillterIds.AddRange(currentList2.Select(p => p.Id));
                newList.AddRange(currentList2);
            }
            var currentList3 = data.Models.Where(p => !fillterIds.Contains(p.Id) && p.Enabled && p.AddressPath.Contains(CommonConst.ADDRESS_PATH_SPLIT + districtId + CommonConst.ADDRESS_PATH_SPLIT)).ToList();
            if (currentList3 != null && currentList3.Count() > 0)
            {
                fillterIds.AddRange(currentList3.Select(p => p.Id));
                newList.AddRange(currentList3);
            }
            var currentList4 = data.Models.Where(p => !fillterIds.Contains(p.Id) && p.Enabled).ToList();//非同街、非同区,但一定会同市
            if (currentList4 != null && currentList4.Count() > 0)
            {
                fillterIds.AddRange(currentList4.Select(p => p.Id));
                newList.AddRange(currentList4);
            }
            var currentList5 = data.Models.Where(p => !fillterIds.Contains(p.Id)).ToList();//库存不足的排最后
            if (currentList5 != null && currentList5.Count() > 0)
            {
                newList.AddRange(currentList5);
            }
            if (newList.Count() != data.Models.Count())//如果新组合的数据与原数据数量不一致
            {
                return(Json(new
                {
                    Success = false
                }));
            }
            var storeList = newList.Select(sb =>
            {
                return(new
                {
                    ContactUser = sb.ContactUser,
                    ContactPhone = sb.ContactPhone,
                    AddressDetail = sb.AddressDetail,
                    ShopBranchName = sb.ShopBranchName,
                    Id = sb.Id,
                    Enabled = sb.Enabled
                });
            });

            #endregion

            var result = new
            {
                Success   = true,
                StoreList = storeList
            };
            return(Json(result));
        }
        /// <summary>
        /// 根据查询条件判断是否有门店
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public bool Exists(CommonModel.ShopBranchQuery query)
        {
            var shopBranchs = ToWhere(query);

            return(shopBranchs.Any());
        }
 /// <summary>
 /// 根据查询条件判断是否有门店
 /// </summary>
 /// <param name="query"></param>
 /// <returns></returns>
 public static bool Exists(CommonModel.ShopBranchQuery query)
 {
     return(_shopBranchService.Exists(query));
 }