fix 省市地区管理

This commit is contained in:
yxw
2026-01-05 19:09:54 +08:00
parent ea541fb6e4
commit 4eb09a79fc
12 changed files with 1704 additions and 36 deletions

View File

@@ -6,6 +6,8 @@ namespace Atomx.Admin.Client.Models
{
[IgnoreDataMember]
public long? CountryId { get; set; }
[IgnoreDataMember]
public long StateProvinceId { get; set; }
public string Name { get; set; } = string.Empty;
}

View File

@@ -27,7 +27,7 @@
<Input @bind-Value="@country.Name" Placeholder="国家名称" Disabled />
</FormItem>
<FormItem Label="州/省/城市">
<Cascader Options="@stateProvinceTrees" @bind-Value="cities" SelectedNodesChanged="OnCitiesChange"></Cascader>
<Cascader Options="@stateProvinceTrees" @bind-Value="cities" ChangeOnSelect="true" SelectedNodesChanged="OnCitiesChange"></Cascader>
</FormItem>
<FormItem Label="名称" Required>
<Input @bind-Value="@context.Name" Placeholder="名称" />
@@ -81,9 +81,10 @@
{
model.CountryId = CountryId;
_ = LoadStateProvinceAndCities();
_ = LoadLanguage();
_ = LoadCountry();
_ = LoadStateProvinceAndCities();
if (Id > 0)
{
LoadData();
@@ -164,14 +165,14 @@
{
area = apiResult.Data;
model = apiResult.Data.Adapt<AreaModel>();
// if (model.ParentId > 0)
// {
// cities = $"{model.StateProvinceId},{model.ParentId}";
// }
// else if (model.StateProvinceId > 0)
// {
// cities = $"{model.StateProvinceId}";
// }
if (model.ParentId > 0)
{
cities = $"{model.ParentId}";
}
else if (model.StateProvinceId > 0)
{
cities = $"{model.StateProvinceId}";
}
}
}
else
@@ -203,7 +204,7 @@
{
saving = false;
await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" });
Navigation.NavigateTo($"/area/list/{CountryId}");
Navigation.NavigateTo($"/area/list/{CountryId}/{StateProvinceId}");
}
else
{

View File

@@ -48,6 +48,7 @@
<PropertyColumn Property="c => c.Name" Title="名称" />
<PropertyColumn Property="c => c.StateProvinceName" Title="州/省" />
<PropertyColumn Property="c => c.Initial" Title="首字母" />
<PropertyColumn Property="c => c.Count" Title="地区数量" />
<PropertyColumn Property="c => c.Enabled" Title="状态">
@if (context.Enabled)
{
@@ -172,22 +173,52 @@
{
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
{
Navigation.NavigateTo($"/area/list/{CountryId}");
if (StateProvinceId > 0)
{
Navigation.NavigateTo($"/area/list/{CountryId}/{StateProvinceId}");
}
else
{
Navigation.NavigateTo($"/area/list/{CountryId}");
}
}
}
else
{
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
{
Navigation.NavigateTo($"/area/list/{CountryId}?{queryString}");
if (StateProvinceId > 0)
{
Navigation.NavigateTo($"/area/list/{CountryId}/{StateProvinceId}?{queryString}");
}
else
{
Navigation.NavigateTo($"/area/list/{CountryId}?{queryString}");
}
}
}
}

View File

@@ -47,6 +47,7 @@
<PropertyColumn Property="c => c.Name" Title="名称" />
<PropertyColumn Property="c => c.Initial" Title="首字母" />
<PropertyColumn Property="c => c.Abbreviation" Title="缩写" />
<PropertyColumn Property="c => c.Count" Title="城市数量" />
<PropertyColumn Property="c => c.Enabled" Title="状态">
@if (context.Enabled)
{

View File

@@ -32,7 +32,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<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.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0" />

View File

@@ -188,7 +188,7 @@ namespace Atomx.Admin.Controllers
if (search.StateProvinceId > 0)
{
query = from p in query
where p.ParentId == search.StateProvinceId
where p.StateProvinceId == search.StateProvinceId
select p;
}
list.Count = query.Count();
@@ -299,32 +299,79 @@ namespace Atomx.Admin.Controllers
{
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);
var parent = _dbContext.Areas.Where(p => p.Id == model.ParentId).SingleOrDefault();
if (parent == null)
if (stateProvinceChanged || parentChanged)
{
data.Depth = 0;
data.Path = model.Id.ToString();
}
else
{
if (parent.StateProvinceId == 0)
var parent = _dbContext.Areas.Where(p => p.Id == model.ParentId).SingleOrDefault();
if (parent == null)
{
data.StateProvinceId = parent.Id;
data.Depth = 0;
data.Path = model.Id.ToString();
}
else
{
data.StateProvinceId = parent.StateProvinceId;
}
if (parent.StateProvinceId == 0)
{
data.StateProvinceId = parent.Id;
}
else
{
data.StateProvinceId = parent.StateProvinceId;
}
data.Depth = parent.Depth + 1;
data.Path = $"{parent.Path},{data.Id}";
data.Depth = parent.Depth + 1;
data.Path = $"{parent.Path},{data.Id}";
}
}
_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
{
@@ -346,6 +393,7 @@ namespace Atomx.Admin.Controllers
else
{
data.StateProvinceId = parent.StateProvinceId;
}
data.Depth = parent.Depth + 1;
data.Path = $"{parent.Path},{data.Id}";
@@ -353,6 +401,26 @@ namespace Atomx.Admin.Controllers
_dbContext.Areas.Add(data);
_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);

View File

@@ -50,6 +50,11 @@ namespace Atomx.Common.Entities
[Column(TypeName = "varchar(32)")]
public string Abbreviation { get; set; } = string.Empty;
/// <summary>
/// 下级地区数量
/// </summary>
public int Count { get; set; }
/// <summary>
/// 地区深度
/// </summary>

View File

@@ -4,6 +4,6 @@
{
public string Label { 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>();
}
}

View File

@@ -91,13 +91,13 @@ namespace Atomx.Data.CacheServices
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)
{
var cityItem = new KeyValueTree
{
Label = state.Name,
Value = state.Id.ToString()
Label = city.Name,
Value = city.Id.ToString()
};
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)
{
var data = areas.Where(p => p.ParentId == parentId).ToList();
foreach (var area in areas)
foreach (var area in data)
{
var item = new KeyValueTree
{
@@ -261,7 +261,7 @@ namespace Atomx.Data.CacheServices
if (childs.Count > 0)
{
var childrenTrees = BuildAreaTree(area.Id, areas, result);
item.Children.AddRange(childrenTrees);
item.Children = childrenTrees;
}
result.Add(item);
}

File diff suppressed because it is too large Load Diff

View 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");
}
}
}

View File

@@ -243,6 +243,9 @@ namespace Atomx.Data.Migrations
b.Property<bool>("AllowShipping")
.HasColumnType("boolean");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<long>("CountryId")
.HasColumnType("bigint");