NopCommerce 3.4省市联动
做法有两种,一种是在StateProvince表里面加个字段,另一种是新建两个表,用来存市、县的数据,表结构完全按照StateProvince走就好了。我这里用的是第二种做法,菜鸟一枚,代码写的比较烂,哪里写的不好欢迎提出来以便我提高自己。
第一步:去数据库,新建两个表,表我就不给了,直接给对应的Model
using System.Collections.Generic;
using Nop.Core.Domain.Localization; namespace Nop.Core.Domain.Directory
{
/// <summary>
/// Represents a state/province
/// </summary>
public partial class City : BaseEntity, ILocalizedEntity
{
private ICollection<County> _counties;
/// <summary>
/// Gets or sets the country identifier
/// </summary>
public int StateProvinceId { get; set; } /// <summary>
/// Gets or sets the name
/// </summary>
public string Name { get; set; } /// <summary>
/// Gets or sets the abbreviation
/// </summary>
public string Abbreviation { get; set; } /// <summary>
/// Gets or sets a value indicating whether the entity is published
/// </summary>
public bool Published { get; set; } /// <summary>
/// Gets or sets the display order
/// </summary>
public int DisplayOrder { get; set; } /// <summary>
/// Gets or sets the country
/// </summary>
public virtual StateProvince StateProvince { get; set; }
public virtual ICollection<County> Countys
{
get { return _counties ?? (_counties = new List<County>()); }
protected set { _counties = value; }
}
} }
City.cs
using Nop.Core.Domain.Localization; namespace Nop.Core.Domain.Directory
{
/// <summary>
/// Represents a state/province
/// </summary>
public partial class County : BaseEntity, ILocalizedEntity
{
/// <summary>
/// Gets or sets the country identifier
/// </summary>
public int CityId { get; set; } /// <summary>
/// Gets or sets the name
/// </summary>
public string Name { get; set; } /// <summary>
/// Gets or sets the abbreviation
/// </summary>
public string Abbreviation { get; set; } /// <summary>
/// Gets or sets a value indicating whether the entity is published
/// </summary>
public bool Published { get; set; } /// <summary>
/// Gets or sets the display order
/// </summary>
public int DisplayOrder { get; set; } /// <summary>
/// Gets or sets the country
/// </summary>
public virtual City City { get; set; }
} }
County.cs
当然,还需要修改StateProvince的Model
using System.Collections.Generic;
using Nop.Core.Domain.Localization; namespace Nop.Core.Domain.Directory
{
/// <summary>
/// Represents a state/province
/// </summary>
public partial class StateProvince : BaseEntity, ILocalizedEntity
{
private ICollection<City> _cities;
/// <summary>
/// Gets or sets the country identifier
/// </summary>
public int CountryId { get; set; } /// <summary>
/// Gets or sets the name
/// </summary>
public string Name { get; set; } /// <summary>
/// Gets or sets the abbreviation
/// </summary>
public string Abbreviation { get; set; } /// <summary>
/// Gets or sets a value indicating whether the entity is published
/// </summary>
public bool Published { get; set; } /// <summary>
/// Gets or sets the display order
/// </summary>
public int DisplayOrder { get; set; } /// <summary>
/// Gets or sets the country
/// </summary>
public virtual Country Country { get; set; }
public virtual ICollection<City> Citys
{
get { return _cities ?? (_cities = new List<City>()); }
protected set { _cities = value; }
}
} }
StateProvince.cs
第二步:去Service层去做Crud,县、市的基本是一样的,我就只列出来一个。另外一个照着写就完了。
先定义接口:
using System.Collections.Generic;
using Nop.Core.Domain.Directory; namespace Nop.Services.Directory
{
public interface ICityService
{
void DeleteCity(City city);
City GetCityById(int cityId);
City GetByAbbreviation(string abbreviation);
IList<City> GetCityByStateProvinceId(int stateProvinceId, bool showHidden = false);
void InsertCity(City city);
void UpdateCity(City city);
}
}
ICityService.cs
去实现接口:
using System;
using System.Collections.Generic;
using System.Linq;
using Nop.Core.Caching;
using Nop.Core.Data;
using Nop.Core.Domain.Directory;
using Nop.Services.Events; namespace Nop.Services.Directory
{
public partial class CityService:ICityService
{
#region Constants /// <summary>
/// Key for caching
/// </summary>
/// <remarks>
/// {1} : country ID
/// </remarks>
private const string CITYS_ALL_KEY = "Nop.city.all-{0}";
/// <summary>
/// Key pattern to clear cache
/// </summary>
private const string CITYS_PATTERN_KEY = "Nop.city."; #endregion #region Fields private readonly IRepository<City> _cityRepository;
private readonly IEventPublisher _eventPublisher;
private readonly ICacheManager _cacheManager; #endregion #region Ctor /// <summary>
/// Ctor
/// </summary>
/// <param name="cacheManager">Cache manager</param>
/// <param name="stateProvinceRepository">State/province repository</param>
/// <param name="eventPublisher">Event published</param>
public CityService(ICacheManager cacheManager,
IRepository<City> cityRepository,
IEventPublisher eventPublisher)
{
_cacheManager = cacheManager;
_cityRepository = cityRepository;
_eventPublisher = eventPublisher;
} #endregion
public void DeleteCity(City city)
{
if(city==null)
throw new ArgumentNullException("city");
_cityRepository.Delete(city);
_cacheManager.RemoveByPattern(CITYS_PATTERN_KEY);
_eventPublisher.EntityDeleted(city);
} public City GetCityById(int cityId)
{
if (cityId == )
{
return null;
}
return _cityRepository.GetById(cityId);
} public City GetByAbbreviation(string abbreviation)
{
var query = from sp in _cityRepository.Table
where sp.Abbreviation == abbreviation
select sp;
var city = query.FirstOrDefault();
return city;
} public IList<City> GetCityByStateProvinceId(int stateProvinceId, bool showHidden = false)
{
string key = string.Format(CITYS_ALL_KEY, stateProvinceId);
return _cacheManager.Get(key, () =>
{
var query= from sp in _cityRepository.Table
orderby sp.DisplayOrder
where sp.StateProvinceId == stateProvinceId &&
(showHidden || sp.Published)
select sp;
var city = query.ToList();
return city;
});
} public void InsertCity(City city)
{
if (city == null)
throw new ArgumentNullException("city"); _cityRepository.Insert(city); _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY); //event notification
_eventPublisher.EntityInserted(city);
} public void UpdateCity(City city)
{
if (city == null)
throw new ArgumentNullException("city"); _cityRepository.Update(city); _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY); //event notification
_eventPublisher.EntityUpdated(city);
}
}
}
CityService.cs
这是市的,县的照着这个写就完了。注意缓存那块也一定要给把那个Key给改了,不然会重名的。
第三步:去Nop.Web.Framework把刚写的这些Service注入。
builder.RegisterType<CityService>().As<ICityService>().SingleInstance();
builder.RegisterType<CountyService>().As<ICountyService>().SingleInstance();
DependencyRegistrar.cs
第三步:修改他转换po和vo的方法,我这个做的是国内的电子商务网站,所以,国家那里我直接就写死了,而且在后续的界面中,我也直接把国家给干掉了。
public static void PrepareModel(this AddressModel model,
Address address, bool excludeProperties,
AddressSettings addressSettings,
ILocalizationService localizationService = null,
IStateProvinceService stateProvinceService = null,
#region yunchen.bai
ICityService cityService=null,
ICountyService countyService=null ,
#endregion
Func<IList<Country>> loadCountries = null,
bool prePopulateWithCustomerFields = false,
Customer customer = null )
{
if (model == null)
throw new ArgumentNullException("model"); if (addressSettings == null)
throw new ArgumentNullException("addressSettings"); if (!excludeProperties && address != null)
{
model.Id = address.Id;
model.FirstName = address.FirstName;
model.LastName = address.LastName;
model.Email = address.Email;
model.Company = address.Company;
model.CountryId = address.CountryId;
model.CountryName = address.Country != null
? address.Country.GetLocalized(x => x.Name)
: null;
model.StateProvinceId = address.StateProvinceId;
model.StateProvinceName = address.StateProvince != null
? address.StateProvince.GetLocalized(x => x.Name)
: null;
model.City = address.City;
model.Address1 = address.Address1;
model.Address2 = address.Address2;
model.ZipPostalCode = address.ZipPostalCode;
model.PhoneNumber = address.PhoneNumber;
model.FaxNumber = address.FaxNumber;
} if (address == null && prePopulateWithCustomerFields)
{
if (customer == null)
throw new Exception("Customer cannot be null when prepopulating an address");
model.Email = customer.Email;
model.FirstName = customer.GetAttribute<string>(SystemCustomerAttributeNames.FirstName);
model.LastName = customer.GetAttribute<string>(SystemCustomerAttributeNames.LastName);
model.Company = customer.GetAttribute<string>(SystemCustomerAttributeNames.Company);
model.Address1 = customer.GetAttribute<string>(SystemCustomerAttributeNames.StreetAddress);
model.Address2 = customer.GetAttribute<string>(SystemCustomerAttributeNames.StreetAddress2);
model.ZipPostalCode = customer.GetAttribute<string>(SystemCustomerAttributeNames.ZipPostalCode);
model.City = customer.GetAttribute<string>(SystemCustomerAttributeNames.City);
//ignore country and state for prepopulation. it can cause some issues when posting pack with errors, etc
//model.CountryId = customer.GetAttribute<int>(SystemCustomerAttributeNames.CountryId);
//model.StateProvinceId = customer.GetAttribute<int>(SystemCustomerAttributeNames.StateProvinceId);
model.PhoneNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.Phone);
model.FaxNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.Fax);
} //countries and states
if (addressSettings.CountryEnabled && loadCountries != null)
{
if (localizationService == null)
throw new ArgumentNullException("localizationService"); model.AvailableCountries.Add(new SelectListItem() { Text = localizationService.GetResource("Address.SelectCountry"), Value = "" });
foreach (var c in loadCountries())
{
model.AvailableCountries.Add(new SelectListItem()
{
Text = c.GetLocalized(x => x.Name),
Value = c.Id.ToString(),
Selected = c.Id == model.CountryId
});
}
model.CountryId = ;
if (address != null)
{
model.CountyId = address.CountyId;
model.CityId = address.CityId;
}
if (addressSettings.StateProvinceEnabled)
{
//states
if (stateProvinceService == null)
throw new ArgumentNullException("stateProvinceService"); var states = stateProvinceService
.GetStateProvincesByCountryId()//这块直接给写死成中国
.ToList();
if (states.Count > )
{
foreach (var s in states)
{
model.AvailableStates.Add(new SelectListItem()
{
Text = s.GetLocalized(x => x.Name),
Value = s.Id.ToString(),
Selected = (s.Id == model.StateProvinceId)
});
}
}
else
{
model.AvailableStates.Add(new SelectListItem()
{
Text = localizationService.GetResource("Address.OtherNonUS"),
Value = ""
});
}
#region yunchen.bai 2014.10.27
if (cityService == null)
throw new ArgumentNullException("cityService");
var firstProvince = stateProvinceService.GetStateProvincesByCountryId().FirstOrDefault() ??
new StateProvince();
var citys =
cityService.GetCityByStateProvinceId(model.StateProvinceId != null
? model.StateProvinceId.Value
: firstProvince.Id).ToList();
var firstCity = cityService.GetCityByStateProvinceId(firstProvince.Id).FirstOrDefault() ??
new City();
if (citys.Count > )
{
foreach (var c in citys)
{
model.AvailableCity.Add(new SelectListItem()
{
Text = c.GetLocalized(x=>x.Name),
Value = c.Id.ToString(),
Selected = (c.Id==model.CityId)
});
}
}
else
{
model.AvailableCity.Add(new SelectListItem()
{
Text = localizationService.GetResource("Address.OtherNonUS"),
Value = ""
});
}
if(countyService==null)
throw new ArgumentNullException("countyService");
var counties = countyService.GetCountyByCityId(model.CityId.HasValue?model.CityId.Value:firstCity.Id);
if (counties.Count > )
{
foreach (var county in counties)
{
model.AvailableCounty.Add(new SelectListItem()
{
Text = county.GetLocalized(x=>x.Name),
Value = county.Id.ToString(),
Selected = (county.Id==model.CityId)
});
}
}
else
{
model.AvailableCity.Add(new SelectListItem()
{
Text = localizationService.GetResource("Address.OtherNonUS"),
Value = ""
});
} #endregion }
}
MappingExtensions.cs
未完待续.....
NopCommerce 3.4省市联动的更多相关文章
- jquery省市联动,根据公司需求而写
//author:guan //2015-05-25 //省市联动 //实用说明,页面引用如下js //<script src="../js/jquery-1.6.3.min.js&q ...
- Json 基于jQuery+JSON的省市联动效果
helloweba.com 作者:月光光 时间:2012-09-12 21:57 标签: jQuery JSON Ajax 省市联动 省市区联动下拉效果在WEB中应用非常广泛,尤其在一些 ...
- AJAX案例四:省市联动
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- Dynamic CRM 2013学习笔记(八)过滤查找控件 (类似省市联动)
我们经常要实现类似省市联动一样的功能,常见的就是二个查找控件,一个选择了省后,另一个市的查找控件就自动过滤了,只显示当前省下的市,而不是所有的市.当然这是最简单的,实际工作中还有更复杂的功能要通过过滤 ...
- [JS]以下是JS省市联动菜单代码
以下是JS省市联动菜单代码: 代码一: <html> <head> <title></title> <script language=" ...
- 通过Javascript数组设计一个省市联动菜单
通过Javascript数组设计一个省市联动菜单 使用Option内置类来完成下拉选项的创建 2.使用定时器实现一个时钟程序 3.使用PHP+JSON完成语音验证码 网址:http://yuyin.b ...
- Ado.Net小练习03(省市联动)
前台界面: 后台代码: namespace _04省市联动 { public partial class Form1 : Form { public ...
- Ajax省市联动
以JQuery为JS,写的Ajax省市联动. 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...
- html + ashx 实现Ajax省市联动
基本思路:1.了解数据库中省和市的表结构及关联主键 2.创建html页面及select标签 3.通过ajax向ashx(一般处理程序)发送后台请求完成联动效果 表结构: 这里,开始创建一个命为demo ...
随机推荐
- logback.xml简单配置
感觉配置的没问题,但是控制台就是不输出日志,后来发现是jar的问题. 依赖包: 注意依赖包,没有其他,只有下面3个,因为Jar包的问题,浪费了很长时间 <dependency> <g ...
- JQuery的一些基础知识
JQuery的核心的一些方法 each(callback) '就像循环$("Element").length; ‘元素的个数,是个属性$("Element"). ...
- 汉诺塔matlab实现
Matlab的递归调用,好久不用matlab了,练练手. global handCount; handCount = 1; huuotsun(1, 2, 3, 3) function hu ...
- 使用dojo.connect()添加事件的注意事项
使用dojo.connect()添加事件处理器是很方便的,不用再考虑跨浏览器的问题了.但要想正确地使用这个方法,仍然要注意几个问题: 1.用dojo.byId()获取的是dom元素,而用 ...
- odps编写UDF的实现
问题 尝试写一个UDF,参数支持输入x,y与一个Polygon,返回结果是(x,y)是否在输入的Geometry之内? 环境 eclipse odps 插件 jts包:jts-1.8.jar 解法 i ...
- ASP.NET常用内置对象之——Server
简介 Server对象是HttpServerUtility的一个实例,也是上下文对象context的一个属性,提供用于处理Web请求的Helper方法. 常用成员 一.Server.MapPath() ...
- 查询SQL Server 版本信息
select SERVERPROPERTY('ProductVersion') as ProductionVersion, SERVERPROPERTY('ProductLevel')as Produ ...
- MVC 接收参数时会自动解码
MVC在接收传递过来的参数时,会自动对参数进行解码,无需手动解码 例: public ActionResult SendMsg2(string name) { return Content(name) ...
- BUG Review:关于getting 'android:xxx' attribute: attribute is not a string value的问题及解决方法
我们在使用Android Studio开发完应用程序后,都要将打好的apk安装包上传到各大应用市场,但是有时候上传时应用市场会出现提交的安装包不能通过应用市场的aapt解析而被打回的情况. 他们使用a ...
- Android MVP 简析
原地址:https://segmentfault.com/a/1190000003927200 在Android中应用MVP模式的原因与方法的简析,写的简单易懂.