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 ...
随机推荐
- 百度富文本Ueditor将图片存在项目外路径并回显
我的毕设中需要一个类似新闻发布的功能,使用到百度富文本编辑器,不过百度富文本编辑器有点坑(只是我太菜了),粘贴图片和回显这个坑坑了我两天时间.效果是这样的: 就是可以在文本中粘贴图片并显示出来,直接说 ...
- javaweb之jsp的九个隐含对象与基本语法
1.在页面上可以不用声明直接使用的对象称为jsp页面的隐含对象.使用<% %>编写的java代码在_jspService方法中,如下: public void _jspService(fi ...
- 域名解析成功后,怎样访问服务器上Eclipse中的Web工程
右击工程选择Export-->选择Web文件夹下的WAR file-->Destination下选择文件存放的地址-->Finish就可以获得WAR文件了然后将WAR文件放到tomc ...
- java 单例的实现及多线程下的安全
package com.demo01; public class Single { /** * 设计模式:单例设计模式 * 解决一个类中只允许存在一个对象这种情况: * 不允许通过类,无限制的创建该类 ...
- 谈谈HTML5中的history.pushSate方法,弥补ajax导致浏览器前进后退无效的问题
移动端为了减少页面请求,有时候需要通过单页面做成多页面的效果,最近有这么个需求,表单填完后执行第一步,然后执行第二步,第二步执行完后再执行第三步,每一步都要保留之前的数据.这种情况用单页面实现再合适不 ...
- 原生js模拟jquery写法
function $_custom(fun) { document.onreadystatechange = function() { if (document.readyState == " ...
- BZOJ4773: 负环(倍增Floyd)
题意 题目链接 Sol 倍增Floyd,妙妙喵 一个很显然的思路(然而我想不到是用\(f[k][i][j]\)表示从\(i\)号点出发,走\(k\)步到\(j\)的最小值 但是这样复杂度是\(O(n^ ...
- 原生js、jQuery实现选项卡功能
在大家在网上平常浏览网页的时候,想必各位都会看到选项卡功能,在这里给大家详解一下用原生js.jQuery如何来写一些基本的选项卡 话不多说,先给各位看一下功能图: 好了,下边 ...
- SpringCloud+Git+Maven+Docker+Jenkins自动化构建
1.JDK安装-OpenJDK安装 yum list java-1.8* yum install -y java-1.8.0-openjdk-devel.x86_64 PS: JDK安装有两种方法:一 ...
- Python3.5 使用Sqlite3
-------------------- 修雨轩陈@cnblog Python3.5 使用Sqlite3 python3.5 安装的时候会有很多可选参数,这些参数是默认不提供的,可是当我们想通过pip ...