Nop版本3.7。
Nop里的地址为 国家-> 省份。现在需要修改为 省份-> 城市-> 地区-> 街道。
关于直辖市的话,由于只有三级,参考淘宝,即 北京 -> 北京 -> 地区 ->街道。
一:添加表
添加城市(City)、地区(District)、街道(Street)表。
City 表结构如下,地区、街道表与 City 基本一致。可以参考 国家、省份 做法。
using System.Collections.Generic;using Nop.Core.Domain.Localization;namespace Nop.Core.Domain.Directory{ /// <summary> /// Represents a city /// </summary> public partial class City : BaseEntity, ILocalizedEntity { private ICollection<District> _districts; /// <summary> /// Gets or sets the StateProvince 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 the zip /// </summary> public int Zip { 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 StateProvince /// </summary> public virtual StateProvince StateProvince { get; set; } /// <summary> /// Gets or sets the district /// </summary> public virtual ICollection<District> Districts { get { return _districts ?? (_districts = new List<District>()); } protected set { _districts = value; } } }}
实现创建完毕后,需要在Address表中添加县区、街道的关联字段。
在原Address表中,City是一个nvarchar类型字段,需删除。新增3个int类型字段,CityID,DistrictId,StreetId。
这个时候编译,会发现很多错误,是由于City字段删除的缘故,需更改的地方太多,就不贴代码了,在修改时候,正好加上 City、District、Street相应代码,这一步很花时间,耐心修改。当然,如果图省事,也可以直接用City。
关于添加一个实体的方法,请参考链接 http://www.nopchina.net/post/nopcommerce-add-table.html
控制器、实体、视图 参考 国家省份即可。
PS:我是一只光荣的面向Copy编程者。
二:添加配置
在 商城配置-> 设置管理-> 客户设置 中,客户表单字段 以及 地址表单字段,添加相对应设置。
联动还是需要的。
在 Libraries\Nop.Core\Domain\Common\AddressSetting.cs 中,添加设置字段。
/// <summary> /// Gets or sets a value indicating whether 'City' is enabled /// </summary> public bool CityEnabled { get; set; } /// <summary> /// Gets or sets a value indicating whether 'District' is enabled /// </summary> public bool DistrictEnabled { get; set; } /// <summary> /// Gets or sets a value indicating whether 'Street' is enabled /// </summary> public bool StreetEnabled { get; set; }
重装即可。
在 控制器、实体、视图 中添加相应代码。依旧参考。
三:使用
后台为例,在 Nop.Admin\Views\Shared\EditorTemplates\Address.cshtml 中
@model AddressModel@if (Model.CountryEnabled && Model.StateProvinceEnabled){ <script type="text/javascript"> $(document).ready(function() { $("#@Html.FieldIdFor(model => model.CountryId)").change(function() { CountryIsChange(); }); }); function CountryIsChange() { var selectedItem = $("#@Html.FieldIdFor(model => model.CountryId)").val(); var ddlStates = $("#@Html.FieldIdFor(model => model.StateProvinceId)"); $.ajax({ async: false, cache: false, type: "GET", url: "@(Url.Action("GetStatesByCountryId", "Country"))", data: { "countryId": selectedItem, "addSelectStateItem": "true" }, success: function(data) { ddlStates.html(''); $.each(data, function(id, option) { ddlStates.append($('<option></option>').val(option.id).html(option.name)); }); }, error: function(xhr, ajaxOptions, thrownError) { alert('Failed to retrieve states.'); } }); } </script>}@if (Model.CountryEnabled && Model.StateProvinceEnabled && Model.CityEnabled){ <script type="text/javascript"> $(document).ready(function () { $("#@Html.FieldIdFor(model => model.StateProvinceId)").change(function() { StateProvinceIsChange(); CityIsChange(); DistrictIsChange(); }); }); function StateProvinceIsChange() { var selectedItem = $("#@Html.FieldIdFor(model => model.StateProvinceId)").val(); var ddlCitys = $("#@Html.FieldIdFor(model => model.CityId)"); $.ajax({ async: false, cache: false, type: "GET", url: "@(Url.Action("GetCitysByStateProvinceId", "Country"))", data: { "stateProvinceId": selectedItem, "addSelectCityItem": "true" }, success: function(data) { ddlCitys.html(''); $.each(data, function(id, option) { ddlCitys.append($('<option></option>').val(option.id).html(option.name)); }); }, error: function(xhr, ajaxOptions, thrownError) { alert('Failed to retrieve citys.'); } }); } </script>}@if (Model.CountryEnabled && Model.StateProvinceEnabled && Model.CityEnabled && Model.DistrictEnabled){ <script type="text/javascript"> $(document).ready(function () { $("#@Html.FieldIdFor(model => model.CityId)").change(function () { CityIsChange(); DistrictIsChange(); }); }); function CityIsChange() { var selectedItem = $("#@Html.FieldIdFor(model => model.CityId)").val(); var ddlDistricts = $("#@Html.FieldIdFor(model => model.DistrictId)"); $.ajax({ async: false, cache: false, type: "GET", url: "@(Url.Action("GetDistrictsByCityId", "Country"))", data: { "cityId": selectedItem, "addSelectDistrictItem": "true" }, success: function(data) { ddlDistricts.html(''); $.each(data, function(id, option) { ddlDistricts.append($('<option></option>').val(option.id).html(option.name)); }); }, error: function(xhr, ajaxOptions, thrownError) { alert('Failed to retrieve district.'); } }); } </script>}@if (Model.CountryEnabled && Model.StateProvinceEnabled && Model.CityEnabled && Model.DistrictEnabled && Model.StreetEnabled){ <script type="text/javascript"> $(document).ready(function () { $("#@Html.FieldIdFor(model => model.DistrictId)").change(function() { DistrictIsChange(); }); }); function DistrictIsChange() { var selectedItem = $("#@Html.FieldIdFor(model => model.DistrictId)").val(); var ddlStreets = $("#@Html.FieldIdFor(model => model.StreetId)"); $.ajax({ async: false, cache: false, type: "GET", url: "@(Url.Action("GetStreetsByDistrictId", "Country"))", data: { "districtId": selectedItem, "addSelectStreetItem": "true" }, success: function(data) { ddlStreets.html(''); $.each(data, function(id, option) { ddlStreets.append($('<option></option>').val(option.id).html(option.name)); }); }, error: function(xhr, ajaxOptions, thrownError) { alert('Failed to retrieve street.'); } }); } </script>}@Html.HiddenFor(model => model.Id)@Html.HiddenFor(model => model.FirstNameEnabled)@Html.HiddenFor(model => model.FirstNameRequired)@Html.HiddenFor(model => model.LastNameEnabled)@Html.HiddenFor(model => model.LastNameRequired)@Html.HiddenFor(model => model.EmailEnabled)@Html.HiddenFor(model => model.EmailRequired)@Html.HiddenFor(model => model.CompanyEnabled)@Html.HiddenFor(model => model.CompanyRequired)@Html.HiddenFor(model => model.CountryEnabled)@Html.HiddenFor(model => model.StateProvinceEnabled)@Html.HiddenFor(model => model.CityEnabled)@Html.HiddenFor(model => model.CityRequired)@Html.HiddenFor(model => model.DistrictEnabled)@Html.HiddenFor(model => model.StreetEnabled)@Html.HiddenFor(model => model.StreetAddressEnabled)@Html.HiddenFor(model => model.StreetAddressRequired)@Html.HiddenFor(model => model.StreetAddress2Enabled)@Html.HiddenFor(model => model.StreetAddress2Required)@Html.HiddenFor(model => model.ZipPostalCodeEnabled)@Html.HiddenFor(model => model.ZipPostalCodeRequired)@Html.HiddenFor(model => model.PhoneEnabled)@Html.HiddenFor(model => model.PhoneRequired)@Html.HiddenFor(model => model.FaxEnabled)@Html.HiddenFor(model => model.FaxRequired)<table class="address-block"> @if (Model.FirstNameEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.FirstName): </td> <td class="adminData"> @Html.EditorFor(model => model.FirstName) @Html.ValidationMessageFor(model => model.FirstName) </td> </tr> } @*@if (Model.LastNameEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.LastName): </td> <td class="adminData"> @Html.EditorFor(model => model.LastName) @Html.ValidationMessageFor(model => model.LastName) </td> </tr> }*@ @if (Model.EmailEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.Email): </td> <td class="adminData"> @Html.EditorFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email) </td> </tr> } @if (Model.CompanyEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.Company): </td> <td class="adminData"> @Html.EditorFor(model => model.Company) @Html.ValidationMessageFor(model => model.Company) </td> </tr> } @if (Model.CountryEnabled) { <tr style="display:none;"> <td class="adminTitle"> @Html.NopLabelFor(model => model.CountryId): </td> <td class="adminData"> @Html.DropDownListFor(model => model.CountryId, Model.AvailableCountries) @Html.ValidationMessageFor(model => model.CountryId) </td> </tr> } @if (Model.CountryEnabled && Model.StateProvinceEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.StateProvinceId): </td> <td class="adminData"> @Html.DropDownListFor(model => model.StateProvinceId, Model.AvailableStates) @Html.ValidationMessageFor(model => model.StateProvinceId) </td> </tr> } @if (Model.CountryEnabled && Model.StateProvinceEnabled && Model.CityEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.CityId): </td> <td class="adminData"> @Html.DropDownListFor(model => model.CityId, Model.AvailableCitys) @Html.ValidationMessageFor(model => model.CityId) </td> </tr> } @if (Model.CountryEnabled && Model.StateProvinceEnabled && Model.CityEnabled && Model.DistrictEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.DistrictId): </td> <td class="adminData"> @Html.DropDownListFor(model => model.DistrictId, Model.AvailableDistricts) @Html.ValidationMessageFor(model => model.DistrictId) </td> </tr> } @if (Model.CountryEnabled && Model.StateProvinceEnabled && Model.CityEnabled && Model.DistrictEnabled && Model.StreetEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.StreetId): </td> <td class="adminData"> @Html.DropDownListFor(model => model.StreetId, Model.AvailableStreets) @Html.ValidationMessageFor(model => model.StreetId) </td> </tr> } @if (Model.StreetAddressEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.Address1): </td> <td class="adminData"> @Html.EditorFor(model => model.Address1) @Html.ValidationMessageFor(model => model.Address1) </td> </tr> } @if (Model.StreetAddress2Enabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.Address2): </td> <td class="adminData"> @Html.EditorFor(model => model.Address2) @Html.ValidationMessageFor(model => model.Address2) </td> </tr> } @if (Model.ZipPostalCodeEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.ZipPostalCode): </td> <td class="adminData"> @Html.EditorFor(model => model.ZipPostalCode) @Html.ValidationMessageFor(model => model.ZipPostalCode) </td> </tr> } @if (Model.PhoneEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.PhoneNumber): </td> <td class="adminData"> @Html.EditorFor(model => model.PhoneNumber) @Html.ValidationMessageFor(model => model.PhoneNumber) </td> </tr> } @if (Model.FaxEnabled) { <tr> <td class="adminTitle"> @Html.NopLabelFor(model => model.FaxNumber): </td> <td class="adminData"> @Html.EditorFor(model => model.FaxNumber) @Html.ValidationMessageFor(model => model.FaxNumber) </td> </tr> } @if (Model.CustomAddressAttributes.Count > 0) { @Html.Partial("_AddressAttributes", Model.CustomAddressAttributes) }</table>@if (Model.CountryId == null){ <script type="text/javascript"> $(function () { $("#@Html.FieldIdFor(model => model.CountryId) option").each(function () { if ($(this).text() == "中国") { $(this).attr('selected', true); } }); $("#@Html.FieldIdFor(model => model.CountryId)").trigger("change"); }) </script>}
四:数据
东西都做好了,数据哪来呢? 当然是中国官方网站里找喏。http://www.mca.gov.cn/article/sj/tjbz/a/2016/201603/201604281751.html
不想自己折腾的话,就直接 下载
数据只有 省份、城市、县区 ,街道的话,淘宝有接口,可以去看看。
这里我只是简单的介绍了下怎么去修改。我自己去做的时候,有 国家 省份 参考,并没有太多难点,主要是修改的地方有点多,需要耐心的,一点点的去改动,所以我并没有写太多具体改动的地方,在不熟悉的情况下,参考是很重要的,虽然不能保证很完美,至少保证跟以前一样,不会很烂。在Nop里,其实很多地方都是值得参考的,比如使用缓存、计划任务等,都是可以照葫芦画瓢的。
谢谢支持!!!
原标题:NopCommerce定制系列(3)
关键词: