This commit is contained in:
yxw
2026-01-06 18:46:52 +08:00
parent 4eb09a79fc
commit b098b3f815
10 changed files with 225 additions and 18 deletions

View File

@@ -6,6 +6,6 @@ namespace Atomx.Admin.Client.Models
{
public string CountryName { get; set; } = string.Empty;
public string StateProvinceName { get; set; } = string.Empty;
public string ParentName { get; set; } = string.Empty;
}
}

View File

@@ -66,14 +66,14 @@
<SpaceItem>
<a @onclick="(e) => HandleEdit(context)">编辑</a>
</SpaceItem>
@*<SpaceItem>
<SpaceItem>
<Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")"
OnConfirm="@(e=>HandleDeleteConfirmAsync(e,context.Id))"
OkText="确定"
CancelText="取消">
<a>删除</a>
</Popconfirm>
</SpaceItem>*@
</SpaceItem>
</Space>
</ActionColumn>
</Table>
@@ -218,7 +218,7 @@
{
Navigation.NavigateTo($"/area/list/{CountryId}?{queryString}");
}
}
}
}
@@ -245,7 +245,7 @@
{
Navigation.NavigateTo($"/area/create/{CountryId}");
}
}
@@ -254,4 +254,18 @@
Navigation.NavigateTo($"/area/edit/{model.CountryId}/{model.StateProvinceId}/{model.Id}");
}
async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id)
{
var url = $"/api/area/delete/{id}";
var apiResult = await HttpService.Post<ApiResult<string>>(url, new());
if (apiResult.Success)
{
await LoadListAsync();
await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" });
}
else
{
await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" });
}
}
}

View File

@@ -60,22 +60,22 @@
<ActionColumn Title="操作" Align="ColumnAlign.Right">
<Space>
<SpaceItem>
<a @onclick="(e) => GotoStateProvince(context)">州省管理</a>
<a @onclick="(e) => GotoStateProvince(context)">查看州/省</a>
</SpaceItem>
<SpaceItem>
<a @onclick="(e) => GotoArea(context)">城市管理</a>
<a @onclick="(e) => GotoArea(context)">查看城市</a>
</SpaceItem>
<SpaceItem>
<a @onclick="(e)=>HandleEdit(context)">编辑</a>
</SpaceItem>
@*<SpaceItem>
<SpaceItem>
<Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")"
OnConfirm="@(e=>HandleDeleteConfirmAsync(e,context.Id))"
OkText="确定"
CancelText="取消">
<a>删除</a>
</Popconfirm>
</SpaceItem>*@
</SpaceItem>
</Space>
</ActionColumn>
</Table>
@@ -221,4 +221,19 @@
{
Navigation.NavigateTo($"/area/list/{model.Id}");
}
async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id)
{
var url = $"/api/country/delete/{id}";
var apiResult = await HttpService.Post<ApiResult<string>>(url, new());
if (apiResult.Success)
{
await LoadListAsync();
await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" });
}
else
{
await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" });
}
}
}

View File

@@ -62,19 +62,19 @@
<ActionColumn Title="操作" Align="ColumnAlign.Right">
<Space>
<SpaceItem>
<a @onclick="(e) => GotoArea(context)">城市管理</a>
<a @onclick="(e) => GotoArea(context)">查看城市</a>
</SpaceItem>
<SpaceItem>
<a @onclick="(e) => HandleEdit(context)">编辑</a>
</SpaceItem>
@*<SpaceItem>
<SpaceItem>
<Popconfirm Placement="@Placement.Left" Title="@("删除这条数据无法恢复,您确定要删除吗?")"
OnConfirm="@(e=>HandleDeleteConfirmAsync(e,context.Id))"
OkText="确定"
CancelText="取消">
<a>删除</a>
</Popconfirm>
</SpaceItem>*@
</SpaceItem>
</Space>
</ActionColumn>
</Table>
@@ -220,4 +220,18 @@
Navigation.NavigateTo($"/area/list/{CountryId}/{model.Id}");
}
async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id)
{
var url = $"/api/area/delete/{id}";
var apiResult = await HttpService.Post<ApiResult<string>>(url, new());
if (apiResult.Success)
{
await LoadListAsync();
await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" });
}
else
{
await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" });
}
}
}

View File

@@ -216,11 +216,17 @@ namespace Atomx.Admin.Controllers
{
model.CountryName = country.Name;
}
var state = await _cacheService.GetStateProvince(item.CountryId, item.ParentId);
var state = await _cacheService.GetStateProvince(item.CountryId, item.StateProvinceId);
if (state != null)
{
model.StateProvinceName = state.Name;
}
var parent = await _cacheService.GetArea(item.CountryId, item.ParentId);
if (parent != null)
{
model.ParentName = parent.Name;
}
list.Items.Add(model);
}
@@ -435,14 +441,18 @@ namespace Atomx.Admin.Controllers
/// <param name="model"></param>
/// <returns></returns>
[HttpPost("delete")]
[HttpPost("delete/{id:long}")]
public async Task<IActionResult> DeleteAsync(long id)
{
var result = new ApiResult<string>();
try
{
Console.WriteLine($"{id} deleted");
var count = _dbContext.Areas.Where(p => p.Id == id).ExecuteDelete();
var count = _dbContext.Areas.Count(p => p.ParentId == id || p.StateProvinceId == id);
if (count > 0)
{
return new JsonResult(new ApiResult<string>().IsFail("请先删除下级数据", null));
}
count = _dbContext.Areas.Where(p => p.Id == id).ExecuteDelete();
result = result.IsSuccess(count.ToString());
}
catch (Exception ex)

View File

@@ -259,14 +259,19 @@ namespace Atomx.Admin.Controllers
/// <param name="model"></param>
/// <returns></returns>
[HttpPost("delete")]
[HttpPost("delete/{id:long}")]
public async Task<IActionResult> Delete(long id)
{
var result = new ApiResult<string>();
try
{
var count = _dbContext.Areas.Count(p => p.CountryId == id);
if (count > 0)
{
return new JsonResult(new ApiResult<string>().IsFail("当前数据存在城市关联数据,不能删除", null));
}
Console.WriteLine($"{id} deleted");
var count = _dbContext.Countries.Where(p => p.Id == id).ExecuteDelete();
count = _dbContext.Countries.Where(p => p.Id == id).ExecuteDelete();
result = result.IsSuccess(count.ToString());
}
catch (Exception ex)

View File

@@ -0,0 +1,60 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Atomx.Common.Entities
{
/// <summary>
/// 设备访问控制表
/// </summary>
[Table("DeviceAccessControls")]
public class DeviceAccessControl
{
/// <summary>
/// 数据ID
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public long Id { get; set; }
/// <summary>
/// 限制类型1黑名单2白名单
/// </summary>
public int Type { get; set; }
/// <summary>
/// 设备ID
/// </summary>
[Column(TypeName = "varchar(256)")]
public string DeviceId { get; set; } = string.Empty;
/// <summary>
/// 设备哈希值,用于唯一标识设备
/// </summary>
[Column(TypeName = "varchar(64)")]
public string DeviceHash { get; set; } = string.Empty;
/// <summary>
/// 设备平台
/// </summary>
[Column(TypeName = "varchar(64)")]
public string Platform { get; set; } = string.Empty;
/// <summary>
/// 浏览器
/// </summary>
[Column(TypeName = "varchar(64)")]
public string Browser { get; set; } = string.Empty;
/// <summary>
/// 建立时间
/// </summary>
[Column(TypeName = "timestamptz")]
public DateTime CreateTime { get; set; }
/// <summary>
/// 最后更新时间
/// </summary>
[Column(TypeName = "timestamptz")]
public DateTime? UpdateTime { get; set; }
}
}

View File

@@ -0,0 +1,49 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Atomx.Common.Entities
{
/// <summary>
/// IP访问控制
/// </summary>
[Table("IpAccessControls")]
public class IpAccessControl
{
/// <summary>
/// 数据ID
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public long Id { get; set; }
/// <summary>
/// 限制类型1黑名单2白名单
/// </summary>
public int Type { get; set; }
/// <summary>
/// 开始IP
/// </summary>
[Column(TypeName = "varchar(64)")]
public string StartIp { get; set; } = string.Empty;
/// <summary>
/// 结束IP
/// </summary>
[Column(TypeName = "varchar(64)")]
public string EndIp { get; set; } = string.Empty;
/// <summary>
/// 建立时间
/// </summary>
[Column(TypeName = "timestamptz")]
public DateTime CreateTime { get; set; }
/// <summary>
/// 最后更新时间
/// </summary>
[Column(TypeName = "timestamptz")]
public DateTime? UpdateTime { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Atomx.Common.Entities
{
/// <summary>
/// 用户访问控制表
/// </summary>
[Table("UserAccessControls")]
public class UserAccessControl
{
/// <summary>
/// 数据ID
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public long Id { get; set; }
}
}

View File

@@ -42,6 +42,14 @@ namespace Atomx.Data.CacheServices
/// <returns></returns>
Task<List<Area>> GetAreas(long countryId, bool? reload = false);
/// <summary>
/// 获取城市地区数据
/// </summary>
/// <param name="countryId"></param>
/// <param name="areaId"></param>
/// <returns></returns>
Task<Area> GetArea(long countryId, long areaId);
/// <summary>
/// 更新调整缓存数据
/// </summary>
@@ -199,6 +207,19 @@ namespace Atomx.Data.CacheServices
return cacheData;
}
/// <summary>
/// 获取城市地区数据
/// </summary>
/// <param name="countryId"></param>
/// <param name="areaId"></param>
/// <returns></returns>
public async Task<Area> GetArea(long countryId, long areaId)
{
var cacheData = await GetAreas(countryId);
var data = cacheData.SingleOrDefault(p => p.Id == areaId);
return data;
}
public async Task UpdateArea(Area area)
{
var cacheData = await GetAreas(area.CountryId);