This commit is contained in:
2025-12-26 23:57:51 +08:00
parent 43820c6ec2
commit e198ab93ed
8 changed files with 323 additions and 36 deletions

View File

@@ -0,0 +1,11 @@
using Atomx.Common.Entities;
namespace Atomx.Admin.Client.Models
{
public class AreaItem : Area
{
public string CountryName { get; set; } = string.Empty;
public string StateProvinceName { get; set; } = string.Empty;
}
}

View File

@@ -1,8 +1,11 @@
namespace Atomx.Admin.Client.Models using System.Runtime.Serialization;
namespace Atomx.Admin.Client.Models
{ {
public class AreaSearch : BaseSearch public class AreaSearch : BaseSearch
{ {
public long CountryId { get; set; } [IgnoreDataMember]
public long? CountryId { get; set; }
public long StateProvinceId { get; set; } public long StateProvinceId { get; set; }
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
} }

View File

@@ -1,5 +1,199 @@
<h3>AreaEdit</h3> @page "/area/create/{countryId:long}/{stateProvinceId:long}"
@page "/area/edit/{countryId:long}/{stateProvinceId:long}/{id:long}"
@page "/{locale}/area/create/{countryId:long}/{stateProvinceId:long}"
@page "/{locale}/area/create/{countryId:long}/{stateProvinceId:long}/{id:long}"
@inject ILogger<StateProvinceEdit> Logger
@attribute [Authorize]
<PageContainer Title="@(Id > 0 ? "编辑城市地区信息" : "新增城市地区信息")">
<Breadcrumb>
<Breadcrumb>
<BreadcrumbItem Href="/">管理后台</BreadcrumbItem>
<BreadcrumbItem Href="/settings">系统配置</BreadcrumbItem>
<BreadcrumbItem Href="/country/list">国家管理</BreadcrumbItem>
<BreadcrumbItem Href="@($"/stateprovince/list/{CountryId}")">州/省管理</BreadcrumbItem>
</Breadcrumb>
</Breadcrumb>
<ChildContent>
<Spin Spinning="pageLoading">
<Card Title="城市地区信息">
<Form @ref="editform" Model="@model" LabelColSpan="5" WrapperColSpan="14" OnFinish="OnFormFinishAsync">
<FormItem Label="国家">
<Input @bind-Value="@country.Name" Placeholder="国家名称" Disabled />
</FormItem>
<FormItem Label="名称" Required>
<Input @bind-Value="@context.Name" Placeholder="名称" />
</FormItem>
<FormItem Label="首字母">
<Input @bind-Value="@context.Initial" Placeholder="首字母" />
</FormItem>
<FormItem Label="缩写">
<Input @bind-Value="@context.Abbreviation" Placeholder="缩写" />
</FormItem>
<FormItem Label="显示排序">
<Input @bind-Value="@context.DisplayOrder" Placeholder="显示排序" />
</FormItem>
<FormItem Label="状态">
<Checkbox T="bool" Label="启用" @bind-value="model.Enabled" Size="InputSize.Small" Class="ps-0" />
</FormItem>
<FormItem WrapperCol="new ColLayoutParam { Span = 24, Offset = 5 }">
<Button Type="@ButtonType.Primary" HtmlType="submit" Loading="saving">
提交保存
</Button>
</FormItem>
</Form>
</Card>
</Spin>
</ChildContent>
</PageContainer>
@code { @code {
[Parameter]
public string Locale { get; set; } = string.Empty;
[Parameter]
public long CountryId { get; set; }
[Parameter]
public long StateProvinceId { get; set; }
[Parameter]
public long Id { get; set; }
[SupplyParameterFromForm]
StateProvinceModel model { get; set; } = new();
Form<StateProvinceModel> editform = null!;
List<KeyValue> languageList = new();
Country country = new();
List<KeyValue> stateProvinceList = new();
StateProvinceLocalizedModel stateProvince = new();
bool pageLoading = false;
bool saving = false;
protected override void OnInitialized()
{
base.OnInitialized();
}
protected override void OnParametersSet()
{
model.CountryId = CountryId;
_ = LoadLanguage();
_ = LoadCountry();
_ = LoadStateProvince();
if (Id > 0)
{
LoadData();
}
base.OnParametersSet();
}
async Task LoadCountry()
{
var url = $"/api/country/{CountryId}";
var apiResult = await HttpService.Get<ApiResult<Country>>(url);
if (apiResult.Success)
{
if (apiResult.Data != null)
{
country = apiResult.Data;
StateHasChanged();
}
else
{
Navigation.NavigateTo($"/country/list");
}
}
}
async Task LoadStateProvince()
{
var url = $"/api/stateprovince/select/{CountryId}";
var apiResult = await HttpService.Get<ApiResult<List<KeyValue>>>(url);
if (apiResult.Success)
{
if (apiResult.Data != null)
{
stateProvinceList = apiResult.Data;
StateHasChanged();
}
else
{
Navigation.NavigateTo($"/country/list");
}
stateProvinceList.Insert(0, new KeyValue() { Key = "0", Value = "请选择州/省" });
}
}
async Task LoadLanguage()
{
var url = $"/api/language/enabled";
var apiResult = await HttpService.Get<ApiResult<List<KeyValue>>>(url);
if (apiResult.Success)
{
if (apiResult.Data == null)
{
languageList = new List<KeyValue>();
}
else
{
languageList = apiResult.Data;
languageList.Insert(0, new KeyValue() { Key = "0", Value = "标准" });
}
StateHasChanged();
}
}
async void LoadData()
{
pageLoading = true;
var url = $"/api/stateprovince/detail?id={Id}";
var apiResult = await HttpService.Get<ApiResult<StateProvinceLocalizedModel>>(url);
if (apiResult.Success)
{
if (apiResult.Data == null)
{
Navigation.NavigateTo($"/country/list");
}
else
{
stateProvince = apiResult.Data;
model = apiResult.Data.Adapt<StateProvinceModel>();
}
}
else
{
Navigation.NavigateTo($"/country/list");
}
pageLoading = false;
StateHasChanged();
}
async void OnFormFinishAsync()
{
if (editform.Validate())
{
saving = true;
var url = $"api/stateprovince/save";
var result = new ApiResult<string>();
result = await HttpService.Post<ApiResult<string>>(url, model);
if (result.Code == (int)ResultCode.Success)
{
saving = false;
await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" });
Navigation.NavigateTo($"/stateprovince/list/{CountryId}");
}
else
{
saving = false;
await ModalService.ErrorAsync(new ConfirmOptions() { Title = "服务异常", Content = result.Message });
}
}
}
} }

View File

@@ -5,12 +5,13 @@
<PageContainer Title="国家管理"> <PageContainer Title="城市地区管理">
<Breadcrumb> <Breadcrumb>
<Breadcrumb> <Breadcrumb>
<BreadcrumbItem>Home</BreadcrumbItem> <BreadcrumbItem Href="/">管理后台</BreadcrumbItem>
<BreadcrumbItem>系统配置</BreadcrumbItem> <BreadcrumbItem Href="/settings">系统配置</BreadcrumbItem>
<BreadcrumbItem>国家管理</BreadcrumbItem> <BreadcrumbItem Href="/country/list">国家管理</BreadcrumbItem>
<BreadcrumbItem Href="@($"/stateprovince/list/{CountryId}")">州/省管理</BreadcrumbItem>
</Breadcrumb> </Breadcrumb>
</Breadcrumb> </Breadcrumb>
<ChildContent> <ChildContent>
@@ -22,6 +23,8 @@
<FormItem Label="名称"> <FormItem Label="名称">
<Input @bind-Value="search.Name" Placeholder="名称" AllowClear /> <Input @bind-Value="search.Name" Placeholder="名称" AllowClear />
</FormItem> </FormItem>
</Col>
<Col>
<div class="ant-form-item"> <div class="ant-form-item">
<Button Type="ButtonType.Primary" HtmlType="submit">查询</Button> <Button Type="ButtonType.Primary" HtmlType="submit">查询</Button>
<Button Style="margin: 0 8px;" OnClick="OnSearchReset">重置</Button> <Button Style="margin: 0 8px;" OnClick="OnSearchReset">重置</Button>
@@ -30,33 +33,35 @@
</Row> </Row>
</Form> </Form>
</Card> </Card>
<br />
<Card Title="" Class="hideborder"> <Card Title="" Class="hideborder">
<Extra> <Extra>
<div class="extraContent"> <div class="extraContent">
<Button Type="ButtonType.Primary" HtmlType="submit" OnClick="HandleAddNew">新增国家</Button> <Button Type="ButtonType.Primary" HtmlType="submit" OnClick="HandleAddNew">新增地区</Button>
</div> </div>
</Extra> </Extra>
<ChildContent> <ChildContent>
<Table DataSource="PagingList.Items" PageSize="100" HidePagination="true"> <Table DataSource="PagingList.Items" PageSize="100" HidePagination="true">
<Selection CheckStrictly /> <Selection CheckStrictly />
<PropertyColumn Property="c => c.Name" Title="名称" /> <PropertyColumn Property="c => c.Name" Title="名称" />
<PropertyColumn Property="c => c.StateProvinceName" Title="州/省" />
<PropertyColumn Property="c => c.Initial" Title="首字母" /> <PropertyColumn Property="c => c.Initial" Title="首字母" />
<PropertyColumn Property="c => c.NumericISOCode" Title="ISO代码" />
<PropertyColumn Property="c => c.Enabled" Title="状态"> <PropertyColumn Property="c => c.Enabled" Title="状态">
@if (context.Enabled) @if (context.Enabled)
{ {
<Text>已激活</text> <AntDesign.Text Type="TextElementType.Success"><Icon Type="check" Theme=" IconThemeType.Outline" Width="1.3em" Height="1.3em" /></AntDesign.Text>
} }
else else
{ {
<Text>未激活</text> <Icon Type="close" Theme="IconThemeType.Outline" Width="1.3em" Height="1.3em" />
} }
</PropertyColumn> </PropertyColumn>
<PropertyColumn Property="c => c.DisplayOrder" Title="排序" /> <PropertyColumn Property="c => c.DisplayOrder" Title="排序" />
<ActionColumn Title="操作" Align="ColumnAlign.Right"> <ActionColumn Title="操作" Align="ColumnAlign.Right">
<Space> <Space>
<SpaceItem> <SpaceItem>
<a @onclick="(e)=>HandleEdit(context)">编辑</a> <a @onclick="(e) => HandleEdit(context)">编辑</a>
</SpaceItem> </SpaceItem>
@*<SpaceItem> @*<SpaceItem>
<Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")" <Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")"
@@ -96,10 +101,10 @@
bool pageLoading = false; bool pageLoading = false;
Form<CountrySearch> searchForm = new(); Form<AreaSearch> searchForm = new();
CountrySearch search = new(); AreaSearch search = new();
PagingList<Country> PagingList = new() { Size = 20 }; PagingList<AreaItem> PagingList = new() { Size = 20 };
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
@@ -119,6 +124,8 @@
var uri = new Uri(Navigation.Uri); var uri = new Uri(Navigation.Uri);
var query = uri.Query; var query = uri.Query;
search.Name = query.GetQueryString("Name"); search.Name = query.GetQueryString("Name");
search.StateProvinceId = query.GetQueryString("StateProvinceId").ToLong();
search.CountryId = CountryId;
} }
async Task LoadListAsync() async Task LoadListAsync()
@@ -126,8 +133,8 @@
try try
{ {
pageLoading = true; pageLoading = true;
var url = "/api/country/search"; var url = "/api/area/search";
var apiResult = await HttpService.GetPagingList<Country>(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20)); var apiResult = await HttpService.GetPagingList<AreaItem>(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20));
if (apiResult.Success) if (apiResult.Success)
{ {
if (apiResult.Data != null) if (apiResult.Data != null)
@@ -150,7 +157,7 @@
void OnSearchReset() void OnSearchReset()
{ {
search = new CountrySearch(); search = new();
searchForm?.Reset(); searchForm?.Reset();
} }
@@ -161,22 +168,22 @@
{ {
if (page > 1) if (page > 1)
{ {
Navigation.NavigateTo($"/country/list?page={page}"); Navigation.NavigateTo($"/area/list/{CountryId}?page={page}");
} }
else else
{ {
Navigation.NavigateTo($"/country/list"); Navigation.NavigateTo($"/area/list/{CountryId}");
} }
} }
else else
{ {
if (page > 1) if (page > 1)
{ {
Navigation.NavigateTo($"/country/list?page={page}&{queryString}"); Navigation.NavigateTo($"/area/list/{CountryId}?page={page}&{queryString}");
} }
else else
{ {
Navigation.NavigateTo($"/country/list?{queryString}"); Navigation.NavigateTo($"/area/list/{CountryId}?{queryString}");
} }
} }
} }
@@ -195,13 +202,13 @@
void HandleAddNew() void HandleAddNew()
{ {
Navigation.NavigateTo($"/country/create"); Navigation.NavigateTo($"/area/create/{CountryId}");
} }
void HandleEdit(Country model) void HandleEdit(Area model)
{ {
Navigation.NavigateTo($"/country/edit/{model.Id}"); Navigation.NavigateTo($"/area/edit/{model.Id}");
} }
} }

View File

@@ -85,7 +85,7 @@
async Task LoadCountry() async Task LoadCountry()
{ {
var url = $"/api/country?id={CountryId}"; var url = $"/api/country/{CountryId}";
var apiResult = await HttpService.Get<ApiResult<Country>>(url); var apiResult = await HttpService.Get<ApiResult<Country>>(url);
if (apiResult.Success) if (apiResult.Success)
{ {

View File

@@ -5,13 +5,13 @@
<PageContainer Title="州省管理"> <PageContainer Title="州/省管理">
<Breadcrumb> <Breadcrumb>
<Breadcrumb> <Breadcrumb>
<BreadcrumbItem Href="/">管理后台</BreadcrumbItem> <BreadcrumbItem Href="/">管理后台</BreadcrumbItem>
<BreadcrumbItem Href="/settings">系统配置</BreadcrumbItem> <BreadcrumbItem Href="/settings">系统配置</BreadcrumbItem>
<BreadcrumbItem Href="/country/list">国家管理</BreadcrumbItem> <BreadcrumbItem Href="/country/list">国家管理</BreadcrumbItem>
<BreadcrumbItem>州省管理</BreadcrumbItem> <BreadcrumbItem>州/省管理</BreadcrumbItem>
</Breadcrumb> </Breadcrumb>
</Breadcrumb> </Breadcrumb>
<ChildContent> <ChildContent>
@@ -60,6 +60,9 @@
<PropertyColumn Property="c => c.DisplayOrder" Title="排序" /> <PropertyColumn Property="c => c.DisplayOrder" Title="排序" />
<ActionColumn Title="操作" Align="ColumnAlign.Right"> <ActionColumn Title="操作" Align="ColumnAlign.Right">
<Space> <Space>
<SpaceItem>
<a @onclick="(e) => GotoArea(context)">城市管理</a>
</SpaceItem>
<SpaceItem> <SpaceItem>
<a @onclick="(e) => HandleEdit(context)">编辑</a> <a @onclick="(e) => HandleEdit(context)">编辑</a>
</SpaceItem> </SpaceItem>
@@ -132,7 +135,6 @@
{ {
try try
{ {
Console.WriteLine(search.ToJson());
pageLoading = true; pageLoading = true;
var url = "/api/stateprovince/search"; var url = "/api/stateprovince/search";
var apiResult = await HttpService.GetPagingList<StateProvince>(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20)); var apiResult = await HttpService.GetPagingList<StateProvince>(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20));
@@ -212,4 +214,9 @@
Navigation.NavigateTo($"/stateprovince/{CountryId}/edit/{model.Id}"); Navigation.NavigateTo($"/stateprovince/{CountryId}/edit/{model.Id}");
} }
void GotoArea(StateProvince model)
{
Navigation.NavigateTo($"/area/list/{CountryId}");
}
} }

View File

@@ -69,8 +69,11 @@ namespace Atomx.Admin.Controllers
{ {
page = 1; page = 1;
} }
var result = new ApiResult<PagingList<Area>>(); var result = new ApiResult<PagingList<AreaItem>>();
var list = new PagingList<Area>() { Index = page, Size = size }; var list = new PagingList<AreaItem>() { Index = page, Size = size };
var countries = new List<Country>();
var stateProvices = new List<StateProvince>();
var query = from p in _dbContext.Areas var query = from p in _dbContext.Areas
select p; select p;
@@ -94,7 +97,51 @@ namespace Atomx.Admin.Controllers
select p; select p;
} }
list.Count = query.Count(); list.Count = query.Count();
list.Items = query.OrderByDescending(p => p.DisplayOrder).Skip((page - 1) * size).Take(size).ToList(); var data = query.OrderByDescending(p => p.DisplayOrder).Skip((page - 1) * size).Take(size).ToList();
if (search.CountryId > 0)
{
var country = _dbContext.Countries.SingleOrDefault(p => p.Id == search.CountryId);
if (country != null)
{
countries.Add(country);
}
}
else
{
var countryIds = data.Select(p => p.CountryId).Distinct().ToList();
countries = _dbContext.Countries.Where(p => countryIds.Contains(p.Id)).ToList();
}
if(search.StateProvinceId > 0)
{
var state = _dbContext.StateProvinces.SingleOrDefault(p => p.Id == search.StateProvinceId);
if (state != null)
{
stateProvices.Add(state);
}
}
else
{
var stateIds = data.Select(p => p.StateProvinceId).Distinct().ToList();
stateProvices = _dbContext.StateProvinces.Where(p => stateIds.Contains(p.Id)).ToList();
}
foreach (var item in data)
{
var model = _mapper.Map<AreaItem>(item);
var country = countries.SingleOrDefault(p => p.Id == item.CountryId);
if (country != null)
{
model.CountryName = country.Name;
}
var state = stateProvices.SingleOrDefault(p => p.Id == item.StateProvinceId);
if (state != null)
{
model.StateProvinceName = state.Name;
}
list.Items.Add(model);
}
result = result.IsSuccess(list); result = result.IsSuccess(list);

View File

@@ -50,6 +50,25 @@ namespace Atomx.Admin.Controllers
_localizer = localizer; _localizer = localizer;
} }
/// <summary>
/// 数据查询
/// </summary>
/// <param name="search"></param>
/// <param name="page"></param>
/// <param name="size"></param>
/// <returns></returns>
[HttpGet("select/{countryId:long}")]
public IActionResult AddressList(long countryId, int page, int size = 20)
{
var list = new List<KeyValue>();
var query = from p in _dbContext.StateProvinces
where p.CountryId == countryId && p.Enabled
select p;
list = query.OrderByDescending(p => p.DisplayOrder).Select(p => new KeyValue() { Key = p.Id.ToString(), Value = p.Name }).ToList();
return new JsonResult(new ApiResult<List<KeyValue>>().IsSuccess(list));
}
/// <summary> /// <summary>
/// 数据查询 /// 数据查询
/// </summary> /// </summary>
@@ -58,7 +77,6 @@ namespace Atomx.Admin.Controllers
/// <param name="size"></param> /// <param name="size"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("search")] [HttpPost("search")]
[Authorize(Policy = Permissions.User.View)]
public IActionResult AddressList(StateProvinceSearch search, int page, int size = 20) public IActionResult AddressList(StateProvinceSearch search, int page, int size = 20)
{ {
if (page < 1) if (page < 1)