fix 省市地区管理
This commit is contained in:
@@ -6,6 +6,8 @@ namespace Atomx.Admin.Client.Models
|
|||||||
{
|
{
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public long? CountryId { get; set; }
|
public long? CountryId { get; set; }
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
public long StateProvinceId { get; set; }
|
public long StateProvinceId { get; set; }
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
<Input @bind-Value="@country.Name" Placeholder="国家名称" Disabled />
|
<Input @bind-Value="@country.Name" Placeholder="国家名称" Disabled />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem Label="州/省/城市">
|
<FormItem Label="州/省/城市">
|
||||||
<Cascader Options="@stateProvinceTrees" @bind-Value="cities" SelectedNodesChanged="OnCitiesChange"></Cascader>
|
<Cascader Options="@stateProvinceTrees" @bind-Value="cities" ChangeOnSelect="true" SelectedNodesChanged="OnCitiesChange"></Cascader>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem Label="名称" Required>
|
<FormItem Label="名称" Required>
|
||||||
<Input @bind-Value="@context.Name" Placeholder="名称" />
|
<Input @bind-Value="@context.Name" Placeholder="名称" />
|
||||||
@@ -81,9 +81,10 @@
|
|||||||
{
|
{
|
||||||
model.CountryId = CountryId;
|
model.CountryId = CountryId;
|
||||||
|
|
||||||
|
_ = LoadStateProvinceAndCities();
|
||||||
_ = LoadLanguage();
|
_ = LoadLanguage();
|
||||||
_ = LoadCountry();
|
_ = LoadCountry();
|
||||||
_ = LoadStateProvinceAndCities();
|
|
||||||
if (Id > 0)
|
if (Id > 0)
|
||||||
{
|
{
|
||||||
LoadData();
|
LoadData();
|
||||||
@@ -164,14 +165,14 @@
|
|||||||
{
|
{
|
||||||
area = apiResult.Data;
|
area = apiResult.Data;
|
||||||
model = apiResult.Data.Adapt<AreaModel>();
|
model = apiResult.Data.Adapt<AreaModel>();
|
||||||
// if (model.ParentId > 0)
|
if (model.ParentId > 0)
|
||||||
// {
|
{
|
||||||
// cities = $"{model.StateProvinceId},{model.ParentId}";
|
cities = $"{model.ParentId}";
|
||||||
// }
|
}
|
||||||
// else if (model.StateProvinceId > 0)
|
else if (model.StateProvinceId > 0)
|
||||||
// {
|
{
|
||||||
// cities = $"{model.StateProvinceId}";
|
cities = $"{model.StateProvinceId}";
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -203,7 +204,7 @@
|
|||||||
{
|
{
|
||||||
saving = false;
|
saving = false;
|
||||||
await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" });
|
await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" });
|
||||||
Navigation.NavigateTo($"/area/list/{CountryId}");
|
Navigation.NavigateTo($"/area/list/{CountryId}/{StateProvinceId}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
<PropertyColumn Property="c => c.Name" Title="名称" />
|
<PropertyColumn Property="c => c.Name" Title="名称" />
|
||||||
<PropertyColumn Property="c => c.StateProvinceName" Title="州/省" />
|
<PropertyColumn Property="c => c.StateProvinceName" Title="州/省" />
|
||||||
<PropertyColumn Property="c => c.Initial" Title="首字母" />
|
<PropertyColumn Property="c => c.Initial" Title="首字母" />
|
||||||
|
<PropertyColumn Property="c => c.Count" Title="地区数量" />
|
||||||
<PropertyColumn Property="c => c.Enabled" Title="状态">
|
<PropertyColumn Property="c => c.Enabled" Title="状态">
|
||||||
@if (context.Enabled)
|
@if (context.Enabled)
|
||||||
{
|
{
|
||||||
@@ -172,22 +173,52 @@
|
|||||||
{
|
{
|
||||||
if (page > 1)
|
if (page > 1)
|
||||||
{
|
{
|
||||||
Navigation.NavigateTo($"/area/list/{CountryId}?page={page}");
|
if (StateProvinceId > 0)
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo($"/area/list/{CountryId}/{StateProvinceId}?page={page}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo($"/area/list/{CountryId}?page={page}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Navigation.NavigateTo($"/area/list/{CountryId}");
|
if (StateProvinceId > 0)
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo($"/area/list/{CountryId}/{StateProvinceId}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo($"/area/list/{CountryId}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (page > 1)
|
if (page > 1)
|
||||||
{
|
{
|
||||||
Navigation.NavigateTo($"/area/list/{CountryId}?page={page}&{queryString}");
|
if (StateProvinceId > 0)
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo($"/area/list/{CountryId}/{StateProvinceId}?page={page}&{queryString}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo($"/area/list/{CountryId}?page={page}&{queryString}");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Navigation.NavigateTo($"/area/list/{CountryId}?{queryString}");
|
if (StateProvinceId > 0)
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo($"/area/list/{CountryId}/{StateProvinceId}?{queryString}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Navigation.NavigateTo($"/area/list/{CountryId}?{queryString}");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
<PropertyColumn Property="c => c.Name" Title="名称" />
|
<PropertyColumn Property="c => c.Name" Title="名称" />
|
||||||
<PropertyColumn Property="c => c.Initial" Title="首字母" />
|
<PropertyColumn Property="c => c.Initial" Title="首字母" />
|
||||||
<PropertyColumn Property="c => c.Abbreviation" Title="缩写" />
|
<PropertyColumn Property="c => c.Abbreviation" Title="缩写" />
|
||||||
|
<PropertyColumn Property="c => c.Count" Title="城市数量" />
|
||||||
<PropertyColumn Property="c => c.Enabled" Title="状态">
|
<PropertyColumn Property="c => c.Enabled" Title="状态">
|
||||||
@if (context.Enabled)
|
@if (context.Enabled)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.1" />
|
||||||
<PackageReference Include="Scalar.AspNetCore" Version="2.11.7" />
|
<PackageReference Include="Scalar.AspNetCore" Version="2.11.10" />
|
||||||
<PackageReference Include="Serilog.Settings.Configuration" Version="10.0.0" />
|
<PackageReference Include="Serilog.Settings.Configuration" Version="10.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0" />
|
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0" />
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ namespace Atomx.Admin.Controllers
|
|||||||
if (search.StateProvinceId > 0)
|
if (search.StateProvinceId > 0)
|
||||||
{
|
{
|
||||||
query = from p in query
|
query = from p in query
|
||||||
where p.ParentId == search.StateProvinceId
|
where p.StateProvinceId == search.StateProvinceId
|
||||||
select p;
|
select p;
|
||||||
}
|
}
|
||||||
list.Count = query.Count();
|
list.Count = query.Count();
|
||||||
@@ -299,32 +299,79 @@ namespace Atomx.Admin.Controllers
|
|||||||
{
|
{
|
||||||
return new JsonResult(new ApiResult<string>().IsFail("数据不存在", null));
|
return new JsonResult(new ApiResult<string>().IsFail("数据不存在", null));
|
||||||
}
|
}
|
||||||
|
bool stateProvinceChanged = data.StateProvinceId != model.StateProvinceId;
|
||||||
|
bool parentChanged = data.ParentId != model.ParentId;
|
||||||
|
long oldStateProvinceId = data.StateProvinceId;
|
||||||
|
long oldParentId = data.ParentId;
|
||||||
|
|
||||||
data = _mapper.Map(model, data);
|
data = _mapper.Map(model, data);
|
||||||
|
|
||||||
var parent = _dbContext.Areas.Where(p => p.Id == model.ParentId).SingleOrDefault();
|
if (stateProvinceChanged || parentChanged)
|
||||||
if (parent == null)
|
|
||||||
{
|
{
|
||||||
data.Depth = 0;
|
var parent = _dbContext.Areas.Where(p => p.Id == model.ParentId).SingleOrDefault();
|
||||||
data.Path = model.Id.ToString();
|
if (parent == null)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (parent.StateProvinceId == 0)
|
|
||||||
{
|
{
|
||||||
data.StateProvinceId = parent.Id;
|
data.Depth = 0;
|
||||||
|
data.Path = model.Id.ToString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data.StateProvinceId = parent.StateProvinceId;
|
if (parent.StateProvinceId == 0)
|
||||||
}
|
{
|
||||||
|
data.StateProvinceId = parent.Id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.StateProvinceId = parent.StateProvinceId;
|
||||||
|
}
|
||||||
|
|
||||||
data.Depth = parent.Depth + 1;
|
data.Depth = parent.Depth + 1;
|
||||||
data.Path = $"{parent.Path},{data.Id}";
|
data.Path = $"{parent.Path},{data.Id}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_dbContext.SaveChanges();
|
_dbContext.SaveChanges();
|
||||||
|
|
||||||
|
if (stateProvinceChanged || parentChanged)
|
||||||
|
{
|
||||||
|
//更新数量
|
||||||
|
if (parentChanged)
|
||||||
|
{
|
||||||
|
if (oldParentId > 0)
|
||||||
|
{
|
||||||
|
var oldParent = _dbContext.Areas.SingleOrDefault(p => p.Id == oldParentId);
|
||||||
|
if (oldParent != null)
|
||||||
|
{
|
||||||
|
oldParent.Count = _dbContext.Areas.Count(p => p.ParentId == oldParent.Id);
|
||||||
|
_dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var Parent = _dbContext.Areas.SingleOrDefault(p => p.Id == data.ParentId);
|
||||||
|
if (Parent != null)
|
||||||
|
{
|
||||||
|
Parent.Count = _dbContext.Areas.Count(p => p.ParentId == Parent.Id);
|
||||||
|
_dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stateProvinceChanged)
|
||||||
|
{
|
||||||
|
if (oldStateProvinceId > 0)
|
||||||
|
{
|
||||||
|
var oldState = _dbContext.Areas.SingleOrDefault(p => p.Id == oldStateProvinceId);
|
||||||
|
if (oldState != null)
|
||||||
|
{
|
||||||
|
oldState.Count = _dbContext.Areas.Count(p => p.StateProvinceId == oldState.Id);
|
||||||
|
_dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var state = _dbContext.Areas.SingleOrDefault(p => p.Id == data.StateProvinceId);
|
||||||
|
if (state != null)
|
||||||
|
{
|
||||||
|
state.Count = _dbContext.Areas.Count(p => p.StateProvinceId == state.Id);
|
||||||
|
_dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -346,6 +393,7 @@ namespace Atomx.Admin.Controllers
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
data.StateProvinceId = parent.StateProvinceId;
|
data.StateProvinceId = parent.StateProvinceId;
|
||||||
|
|
||||||
}
|
}
|
||||||
data.Depth = parent.Depth + 1;
|
data.Depth = parent.Depth + 1;
|
||||||
data.Path = $"{parent.Path},{data.Id}";
|
data.Path = $"{parent.Path},{data.Id}";
|
||||||
@@ -353,6 +401,26 @@ namespace Atomx.Admin.Controllers
|
|||||||
|
|
||||||
_dbContext.Areas.Add(data);
|
_dbContext.Areas.Add(data);
|
||||||
_dbContext.SaveChanges();
|
_dbContext.SaveChanges();
|
||||||
|
|
||||||
|
if (data.ParentId > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
//更新省份的数量
|
||||||
|
var state = _dbContext.Areas.SingleOrDefault(p => p.Id == data.StateProvinceId);
|
||||||
|
if (state != null)
|
||||||
|
{
|
||||||
|
state.Count = _dbContext.Areas.Count(p => p.StateProvinceId == state.Id);
|
||||||
|
_dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新城市的数量
|
||||||
|
var city = _dbContext.Areas.SingleOrDefault(p => p.Id == data.ParentId);
|
||||||
|
if (city != null)
|
||||||
|
{
|
||||||
|
city.Count = _dbContext.Areas.Count(p => p.ParentId == city.Id);
|
||||||
|
_dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_backgroundService.ResetStateProvinceAndAreaTree(model.CountryId);
|
_backgroundService.ResetStateProvinceAndAreaTree(model.CountryId);
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ namespace Atomx.Common.Entities
|
|||||||
[Column(TypeName = "varchar(32)")]
|
[Column(TypeName = "varchar(32)")]
|
||||||
public string Abbreviation { get; set; } = string.Empty;
|
public string Abbreviation { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下级地区数量
|
||||||
|
/// </summary>
|
||||||
|
public int Count { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 地区深度
|
/// 地区深度
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
{
|
{
|
||||||
public string Label { get; set; } = string.Empty;
|
public string Label { get; set; } = string.Empty;
|
||||||
public string Value { get; set; } = string.Empty;
|
public string Value { get; set; } = string.Empty;
|
||||||
public List<KeyValueTree> Children { get; set; } = new List<KeyValueTree>();
|
public IList<KeyValueTree> Children { get; set; } = new List<KeyValueTree>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,13 +91,13 @@ namespace Atomx.Data.CacheServices
|
|||||||
Value = state.Id.ToString()
|
Value = state.Id.ToString()
|
||||||
};
|
};
|
||||||
|
|
||||||
var citysInState = cities.Where(p => p.StateProvinceId == state.Id).ToList();
|
var citysInState = cities.Where(p => p.ParentId == state.Id).ToList();
|
||||||
foreach (var city in citysInState)
|
foreach (var city in citysInState)
|
||||||
{
|
{
|
||||||
var cityItem = new KeyValueTree
|
var cityItem = new KeyValueTree
|
||||||
{
|
{
|
||||||
Label = state.Name,
|
Label = city.Name,
|
||||||
Value = state.Id.ToString()
|
Value = city.Id.ToString()
|
||||||
};
|
};
|
||||||
|
|
||||||
cityItem.Children = BuildAreaTree(city.Id, cities, new List<KeyValueTree>());
|
cityItem.Children = BuildAreaTree(city.Id, cities, new List<KeyValueTree>());
|
||||||
@@ -250,7 +250,7 @@ namespace Atomx.Data.CacheServices
|
|||||||
private List<KeyValueTree> BuildAreaTree(long parentId, List<Area> areas, List<KeyValueTree> result)
|
private List<KeyValueTree> BuildAreaTree(long parentId, List<Area> areas, List<KeyValueTree> result)
|
||||||
{
|
{
|
||||||
var data = areas.Where(p => p.ParentId == parentId).ToList();
|
var data = areas.Where(p => p.ParentId == parentId).ToList();
|
||||||
foreach (var area in areas)
|
foreach (var area in data)
|
||||||
{
|
{
|
||||||
var item = new KeyValueTree
|
var item = new KeyValueTree
|
||||||
{
|
{
|
||||||
@@ -261,7 +261,7 @@ namespace Atomx.Data.CacheServices
|
|||||||
if (childs.Count > 0)
|
if (childs.Count > 0)
|
||||||
{
|
{
|
||||||
var childrenTrees = BuildAreaTree(area.Id, areas, result);
|
var childrenTrees = BuildAreaTree(area.Id, areas, result);
|
||||||
item.Children.AddRange(childrenTrees);
|
item.Children = childrenTrees;
|
||||||
}
|
}
|
||||||
result.Add(item);
|
result.Add(item);
|
||||||
}
|
}
|
||||||
|
|||||||
1528
Atomx.Data/Migrations/20260105102643_0.2.Designer.cs
generated
Normal file
1528
Atomx.Data/Migrations/20260105102643_0.2.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
Atomx.Data/Migrations/20260105102643_0.2.cs
Normal file
29
Atomx.Data/Migrations/20260105102643_0.2.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Atomx.Data.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class _02 : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "Count",
|
||||||
|
table: "Areas",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Count",
|
||||||
|
table: "Areas");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -243,6 +243,9 @@ namespace Atomx.Data.Migrations
|
|||||||
b.Property<bool>("AllowShipping")
|
b.Property<bool>("AllowShipping")
|
||||||
.HasColumnType("boolean");
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<int>("Count")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("CountryId")
|
b.Property<long>("CountryId")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user