首页 > 代码库 > NopCommerce 3.4省市联动

NopCommerce 3.4省市联动

做法有两种,一种是在StateProvince表里面加个字段,另一种是新建两个表,用来存市、县的数据,表结构完全按照StateProvince走就好了。我这里用的是第二种做法,菜鸟一枚,代码写的比较烂,哪里写的不好欢迎提出来以便我提高自己。

第一步:去数据库,新建两个表,表我就不给了,直接给对应的Model

 1 using System.Collections.Generic; 2 using Nop.Core.Domain.Localization; 3  4 namespace Nop.Core.Domain.Directory 5 { 6     /// <summary> 7     /// Represents a state/province 8     /// </summary> 9     public partial class City : BaseEntity, ILocalizedEntity10     {11         private ICollection<County> _counties;12         /// <summary>13         /// Gets or sets the country identifier14         /// </summary>15         public int StateProvinceId { get; set; }16 17         /// <summary>18         /// Gets or sets the name19         /// </summary>20         public string Name { get; set; }21 22         /// <summary>23         /// Gets or sets the abbreviation24         /// </summary>25         public string Abbreviation { get; set; }26 27         /// <summary>28         /// Gets or sets a value indicating whether the entity is published29         /// </summary>30         public bool Published { get; set; }31 32         /// <summary>33         /// Gets or sets the display order34         /// </summary>35         public int DisplayOrder { get; set; }36 37         /// <summary>38         /// Gets or sets the country39         /// </summary>40         public virtual StateProvince StateProvince { get; set; }41         public virtual ICollection<County> Countys42         {43             get { return _counties ?? (_counties = new List<County>()); }44             protected set { _counties = value; }45         }46     }47 48 }
City.cs
 1 using Nop.Core.Domain.Localization; 2  3 namespace Nop.Core.Domain.Directory 4 { 5     /// <summary> 6     /// Represents a state/province 7     /// </summary> 8     public partial class County : BaseEntity, ILocalizedEntity 9     {10         /// <summary>11         /// Gets or sets the country identifier12         /// </summary>13         public int CityId { get; set; }14 15         /// <summary>16         /// Gets or sets the name17         /// </summary>18         public string Name { get; set; }19 20         /// <summary>21         /// Gets or sets the abbreviation22         /// </summary>23         public string Abbreviation { get; set; }24 25         /// <summary>26         /// Gets or sets a value indicating whether the entity is published27         /// </summary>28         public bool Published { get; set; }29 30         /// <summary>31         /// Gets or sets the display order32         /// </summary>33         public int DisplayOrder { get; set; }34 35         /// <summary>36         /// Gets or sets the country37         /// </summary>38         public virtual City City { get; set; }39     }40 41 }
County.cs

当然,还需要修改StateProvince的Model

 1 using System.Collections.Generic; 2 using Nop.Core.Domain.Localization; 3  4 namespace Nop.Core.Domain.Directory 5 { 6     /// <summary> 7     /// Represents a state/province 8     /// </summary> 9     public partial class StateProvince : BaseEntity, ILocalizedEntity10     {11         private ICollection<City> _cities;12         /// <summary>13         /// Gets or sets the country identifier14         /// </summary>15         public int CountryId { get; set; }16 17         /// <summary>18         /// Gets or sets the name19         /// </summary>20         public string Name { get; set; }21 22         /// <summary>23         /// Gets or sets the abbreviation24         /// </summary>25         public string Abbreviation { get; set; }26 27         /// <summary>28         /// Gets or sets a value indicating whether the entity is published29         /// </summary>30         public bool Published { get; set; }31 32         /// <summary>33         /// Gets or sets the display order34         /// </summary>35         public int DisplayOrder { get; set; }36 37         /// <summary>38         /// Gets or sets the country39         /// </summary>40         public virtual Country Country { get; set; }41         public virtual ICollection<City> Citys42         {43             get { return _cities ?? (_cities = new List<City>()); }44             protected set { _cities = value; }45         }46     }47 48 }
StateProvince.cs

第二步:去Service层去做Crud,县、市的基本是一样的,我就只列出来一个。另外一个照着写就完了。

先定义接口:

 1 using System.Collections.Generic; 2 using Nop.Core.Domain.Directory; 3  4 namespace Nop.Services.Directory 5 { 6     public interface ICityService 7     { 8         void DeleteCity(City city); 9         City GetCityById(int cityId);10         City GetByAbbreviation(string abbreviation);11         IList<City> GetCityByStateProvinceId(int stateProvinceId, bool showHidden = false);12         void InsertCity(City city);13         void UpdateCity(City city);14     }15 }
ICityService.cs

去实现接口:

  1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using Nop.Core.Caching;  5 using Nop.Core.Data;  6 using Nop.Core.Domain.Directory;  7 using Nop.Services.Events;  8   9 namespace Nop.Services.Directory 10 { 11     public  partial class CityService:ICityService 12     { 13         #region Constants 14  15         /// <summary> 16         /// Key for caching 17         /// </summary> 18         /// <remarks> 19         /// {1} : country ID 20         /// </remarks> 21         private const string CITYS_ALL_KEY = "Nop.city.all-{0}"; 22         /// <summary> 23         /// Key pattern to clear cache 24         /// </summary> 25         private const string CITYS_PATTERN_KEY = "Nop.city."; 26  27         #endregion 28  29         #region Fields 30  31         private readonly IRepository<City> _cityRepository; 32         private readonly IEventPublisher _eventPublisher; 33         private readonly ICacheManager _cacheManager; 34  35         #endregion 36  37         #region Ctor 38  39         /// <summary> 40         /// Ctor 41         /// </summary> 42         /// <param name="cacheManager">Cache manager</param> 43         /// <param name="stateProvinceRepository">State/province repository</param> 44         /// <param name="eventPublisher">Event published</param> 45         public CityService(ICacheManager cacheManager, 46             IRepository<City> cityRepository, 47             IEventPublisher eventPublisher) 48         { 49             _cacheManager = cacheManager; 50             _cityRepository = cityRepository; 51             _eventPublisher = eventPublisher; 52         } 53  54         #endregion 55         public void DeleteCity(City city) 56         { 57             if(city==null) 58                 throw new ArgumentNullException("city"); 59             _cityRepository.Delete(city); 60             _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY); 61             _eventPublisher.EntityDeleted(city); 62         } 63  64         public City GetCityById(int cityId) 65         { 66             if (cityId == 0) 67             { 68                 return null; 69             } 70             return _cityRepository.GetById(cityId); 71         } 72  73         public City GetByAbbreviation(string abbreviation) 74         { 75             var query = from sp in _cityRepository.Table 76                 where sp.Abbreviation == abbreviation 77                 select sp; 78             var city = query.FirstOrDefault(); 79             return city; 80         } 81  82         public IList<City> GetCityByStateProvinceId(int stateProvinceId, bool showHidden = false) 83         { 84             string key = string.Format(CITYS_ALL_KEY, stateProvinceId); 85             return _cacheManager.Get(key, () => 86             { 87                 var query= from sp in _cityRepository.Table  88                                  orderby  sp.DisplayOrder 89                            where sp.StateProvinceId == stateProvinceId && 90                        (showHidden || sp.Published) 91                            select sp; 92                 var city = query.ToList(); 93                 return city; 94             }); 95         } 96  97         public void InsertCity(City city) 98         { 99             if (city == null)100                 throw new ArgumentNullException("city");101 102             _cityRepository.Insert(city);103 104             _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY);105 106             //event notification107             _eventPublisher.EntityInserted(city);108         }109 110         public void UpdateCity(City city)111         {112             if (city == null)113                 throw new ArgumentNullException("city");114 115             _cityRepository.Update(city);116 117             _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY);118 119             //event notification120             _eventPublisher.EntityUpdated(city);121         }122     }123 }
CityService.cs

这是市的,县的照着这个写就完了。注意缓存那块也一定要给把那个Key给改了,不然会重名的。

第三步:去Nop.Web.Framework把刚写的这些Service注入。

1  builder.RegisterType<CityService>().As<ICityService>().SingleInstance();2             builder.RegisterType<CountyService>().As<ICountyService>().SingleInstance();
DependencyRegistrar.cs

第三步:修改他转换po和vo的方法,我这个做的是国内的电子商务网站,所以,国家那里我直接就写死了,而且在后续的界面中,我也直接把国家给干掉了。

  1 public static void PrepareModel(this AddressModel model,  2             Address address, bool excludeProperties,   3             AddressSettings addressSettings,  4             ILocalizationService localizationService = null,  5             IStateProvinceService stateProvinceService = null,  6               #region yunchen.bai  7          ICityService cityService=null,  8             ICountyService countyService=null ,  9     #endregion 10             Func<IList<Country>> loadCountries = null, 11             bool prePopulateWithCustomerFields = false, 12             Customer customer = null 13           14             ) 15         { 16             if (model == null) 17                 throw new ArgumentNullException("model"); 18  19             if (addressSettings == null) 20                 throw new ArgumentNullException("addressSettings"); 21  22             if (!excludeProperties && address != null) 23             { 24                 model.Id = address.Id; 25                 model.FirstName = address.FirstName; 26                 model.LastName = address.LastName; 27                 model.Email = address.Email; 28                 model.Company = address.Company; 29                 model.CountryId = address.CountryId; 30                 model.CountryName = address.Country != null  31                     ? address.Country.GetLocalized(x => x.Name)  32                     : null; 33                 model.StateProvinceId = address.StateProvinceId; 34                 model.StateProvinceName = address.StateProvince != null  35                     ? address.StateProvince.GetLocalized(x => x.Name) 36                     : null; 37                 model.City = address.City; 38                 model.Address1 = address.Address1; 39                 model.Address2 = address.Address2; 40                 model.ZipPostalCode = address.ZipPostalCode; 41                 model.PhoneNumber = address.PhoneNumber; 42                 model.FaxNumber = address.FaxNumber; 43             } 44  45             if (address == null && prePopulateWithCustomerFields) 46             { 47                 if (customer == null) 48                     throw new Exception("Customer cannot be null when prepopulating an address"); 49                 model.Email = customer.Email; 50                 model.FirstName = customer.GetAttribute<string>(SystemCustomerAttributeNames.FirstName); 51                 model.LastName = customer.GetAttribute<string>(SystemCustomerAttributeNames.LastName); 52                 model.Company = customer.GetAttribute<string>(SystemCustomerAttributeNames.Company); 53                 model.Address1 = customer.GetAttribute<string>(SystemCustomerAttributeNames.StreetAddress); 54                 model.Address2 = customer.GetAttribute<string>(SystemCustomerAttributeNames.StreetAddress2); 55                 model.ZipPostalCode = customer.GetAttribute<string>(SystemCustomerAttributeNames.ZipPostalCode); 56                 model.City = customer.GetAttribute<string>(SystemCustomerAttributeNames.City); 57                 //ignore country and state for prepopulation. it can cause some issues when posting pack with errors, etc 58                 //model.CountryId = customer.GetAttribute<int>(SystemCustomerAttributeNames.CountryId); 59                 //model.StateProvinceId = customer.GetAttribute<int>(SystemCustomerAttributeNames.StateProvinceId); 60                 model.PhoneNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.Phone); 61                 model.FaxNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.Fax); 62             } 63  64             //countries and states 65             if (addressSettings.CountryEnabled && loadCountries != null) 66             { 67                 if (localizationService == null) 68                     throw new ArgumentNullException("localizationService"); 69  70                 model.AvailableCountries.Add(new SelectListItem() { Text = localizationService.GetResource("Address.SelectCountry"), Value = http://www.mamicode.com/"0" }); 71                 foreach (var c in loadCountries()) 72                 { 73                     model.AvailableCountries.Add(new SelectListItem() 74                     { 75                         Text = c.GetLocalized(x => x.Name), 76                         Value =http://www.mamicode.com/ c.Id.ToString(), 77                         Selected = c.Id == model.CountryId 78                     }); 79                 } 80                 model.CountryId = 21; 81                 if (address != null) 82                 { 83                     model.CountyId = address.CountyId; 84                     model.CityId = address.CityId; 85                 } 86                 if (addressSettings.StateProvinceEnabled) 87                 { 88                     //states 89                     if (stateProvinceService == null) 90                         throw new ArgumentNullException("stateProvinceService"); 91  92                     var states = stateProvinceService 93                         .GetStateProvincesByCountryId(21)//这块直接给写死成中国 94                         .ToList(); 95                     if (states.Count > 0) 96                     { 97                         foreach (var s in states) 98                         { 99                             model.AvailableStates.Add(new SelectListItem()100                             {101                                 Text = s.GetLocalized(x => x.Name),102                                 Value =http://www.mamicode.com/ s.Id.ToString(), 103                                 Selected = (s.Id == model.StateProvinceId)104                             });105                         }106                     }107                     else108                     {109                         model.AvailableStates.Add(new SelectListItem()110                         {111                             Text = localizationService.GetResource("Address.OtherNonUS"),112                             Value = http://www.mamicode.com/"0"113                         });114                     }115                     #region yunchen.bai 2014.10.27116                     if (cityService == null)117                         throw new ArgumentNullException("cityService");118                     var firstProvince = stateProvinceService.GetStateProvincesByCountryId(21).FirstOrDefault() ??119                                         new StateProvince();120                     var citys =121                         cityService.GetCityByStateProvinceId(model.StateProvinceId != null122                             ? model.StateProvinceId.Value123                             : firstProvince.Id).ToList();124                     var firstCity = cityService.GetCityByStateProvinceId(firstProvince.Id).FirstOrDefault() ??125                                      new City();126                     if (citys.Count > 0)127                     {128                         foreach (var c in citys)129                         {130                            model.AvailableCity.Add(new SelectListItem()131                            {132                                Text = c.GetLocalized(x=>x.Name),133                                Value =http://www.mamicode.com/ c.Id.ToString(),134                                Selected = (c.Id==model.CityId)135                            });136                         }137                     }138                     else139                     {140                         model.AvailableCity.Add(new SelectListItem()141                         {142                             Text = localizationService.GetResource("Address.OtherNonUS"),143                             Value = http://www.mamicode.com/"0"144                         });145                     }146                     if(countyService==null)147                         throw  new ArgumentNullException("countyService");148                     var counties = countyService.GetCountyByCityId(model.CityId.HasValue?model.CityId.Value:firstCity.Id);149                     if (counties.Count > 0)150                     {151                         foreach (var county in counties)152                         {153                             model.AvailableCounty.Add(new SelectListItem()154                             {155                                 Text = county.GetLocalized(x=>x.Name),156                                 Value =http://www.mamicode.com/ county.Id.ToString(),157                                 Selected = (county.Id==model.CityId)158                             });159                         }160                     }161                     else162                     {163                         model.AvailableCity.Add(new SelectListItem()164                         {165                             Text = localizationService.GetResource("Address.OtherNonUS"),166                             Value = http://www.mamicode.com/"0"167                         });168                     }169 170                     #endregion171 172 173                 }174             }
MappingExtensions.cs

未完待续.....

NopCommerce 3.4省市联动