你的位置:首页 > ASP.net教程

[ASP.net教程]NopCommerce定制系列(3)


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里,其实很多地方都是值得参考的,比如使用缓存、计划任务等,都是可以照葫芦画瓢的。

谢谢支持!!!