diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/AreaItem.cs b/Atomx.Admin/Atomx.Admin.Client/Models/AreaItem.cs
index 3b535dd..a064bb8 100644
--- a/Atomx.Admin/Atomx.Admin.Client/Models/AreaItem.cs
+++ b/Atomx.Admin/Atomx.Admin.Client/Models/AreaItem.cs
@@ -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;
}
}
diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/AreaList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/AreaList.razor
index a1f23f6..6065441 100644
--- a/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/AreaList.razor
+++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/AreaList.razor
@@ -66,14 +66,14 @@
HandleEdit(context)">编辑
- @*
+
删除
- *@
+
@@ -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>(url, new());
+ if (apiResult.Success)
+ {
+ await LoadListAsync();
+ await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" });
+ }
+ else
+ {
+ await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" });
+ }
+ }
}
diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/CountryList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/CountryList.razor
index a0497cf..91d514f 100644
--- a/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/CountryList.razor
+++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/CountryList.razor
@@ -60,22 +60,22 @@
- GotoStateProvince(context)">州省管理
+ GotoStateProvince(context)">查看州/省
- GotoArea(context)">城市管理
+ GotoArea(context)">查看城市
HandleEdit(context)">编辑
- @*
+
删除
- *@
+
@@ -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>(url, new());
+ if (apiResult.Success)
+ {
+ await LoadListAsync();
+ await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" });
+ }
+ else
+ {
+ await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" });
+ }
+ }
}
diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/StateProvinceList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/StateProvinceList.razor
index 124ba95..f62968c 100644
--- a/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/StateProvinceList.razor
+++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/StateProvinceList.razor
@@ -62,19 +62,19 @@
- GotoArea(context)">城市管理
+ GotoArea(context)">查看城市
HandleEdit(context)">编辑
- @*
+
删除
- *@
+
@@ -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>(url, new());
+ if (apiResult.Success)
+ {
+ await LoadListAsync();
+ await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" });
+ }
+ else
+ {
+ await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" });
+ }
+ }
}
\ No newline at end of file
diff --git a/Atomx.Admin/Atomx.Admin/Controllers/AreaController.cs b/Atomx.Admin/Atomx.Admin/Controllers/AreaController.cs
index 0a7edd1..d25564d 100644
--- a/Atomx.Admin/Atomx.Admin/Controllers/AreaController.cs
+++ b/Atomx.Admin/Atomx.Admin/Controllers/AreaController.cs
@@ -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
///
///
- [HttpPost("delete")]
+ [HttpPost("delete/{id:long}")]
public async Task DeleteAsync(long id)
{
var result = new ApiResult();
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().IsFail("请先删除下级数据", null));
+ }
+ count = _dbContext.Areas.Where(p => p.Id == id).ExecuteDelete();
result = result.IsSuccess(count.ToString());
}
catch (Exception ex)
diff --git a/Atomx.Admin/Atomx.Admin/Controllers/CountryController.cs b/Atomx.Admin/Atomx.Admin/Controllers/CountryController.cs
index f2f9e96..264eec3 100644
--- a/Atomx.Admin/Atomx.Admin/Controllers/CountryController.cs
+++ b/Atomx.Admin/Atomx.Admin/Controllers/CountryController.cs
@@ -259,14 +259,19 @@ namespace Atomx.Admin.Controllers
///
///
- [HttpPost("delete")]
+ [HttpPost("delete/{id:long}")]
public async Task Delete(long id)
{
var result = new ApiResult();
try
{
+ var count = _dbContext.Areas.Count(p => p.CountryId == id);
+ if (count > 0)
+ {
+ return new JsonResult(new ApiResult().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)
diff --git a/Atomx.Common/Entities/DeviceAccessControl.cs b/Atomx.Common/Entities/DeviceAccessControl.cs
new file mode 100644
index 0000000..af8d52a
--- /dev/null
+++ b/Atomx.Common/Entities/DeviceAccessControl.cs
@@ -0,0 +1,60 @@
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace Atomx.Common.Entities
+{
+ ///
+ /// 设备访问控制表
+ ///
+ [Table("DeviceAccessControls")]
+ public class DeviceAccessControl
+ {
+ ///
+ /// 数据ID
+ ///
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ [Key]
+ public long Id { get; set; }
+
+ ///
+ /// 限制类型,1黑名单,2白名单
+ ///
+ public int Type { get; set; }
+
+ ///
+ /// 设备ID
+ ///
+ [Column(TypeName = "varchar(256)")]
+ public string DeviceId { get; set; } = string.Empty;
+
+ ///
+ /// 设备哈希值,用于唯一标识设备
+ ///
+ [Column(TypeName = "varchar(64)")]
+ public string DeviceHash { get; set; } = string.Empty;
+
+ ///
+ /// 设备平台
+ ///
+ [Column(TypeName = "varchar(64)")]
+ public string Platform { get; set; } = string.Empty;
+
+ ///
+ /// 浏览器
+ ///
+ [Column(TypeName = "varchar(64)")]
+ public string Browser { get; set; } = string.Empty;
+
+ ///
+ /// 建立时间
+ ///
+ [Column(TypeName = "timestamptz")]
+ public DateTime CreateTime { get; set; }
+
+ ///
+ /// 最后更新时间
+ ///
+ [Column(TypeName = "timestamptz")]
+ public DateTime? UpdateTime { get; set; }
+ }
+}
diff --git a/Atomx.Common/Entities/IpAccessControl.cs b/Atomx.Common/Entities/IpAccessControl.cs
new file mode 100644
index 0000000..e9f3304
--- /dev/null
+++ b/Atomx.Common/Entities/IpAccessControl.cs
@@ -0,0 +1,49 @@
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace Atomx.Common.Entities
+{
+ ///
+ /// IP访问控制
+ ///
+ [Table("IpAccessControls")]
+ public class IpAccessControl
+ {
+ ///
+ /// 数据ID
+ ///
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ [Key]
+ public long Id { get; set; }
+
+ ///
+ /// 限制类型,1黑名单,2白名单
+ ///
+ public int Type { get; set; }
+
+ ///
+ /// 开始IP
+ ///
+ [Column(TypeName = "varchar(64)")]
+ public string StartIp { get; set; } = string.Empty;
+
+ ///
+ /// 结束IP
+ ///
+ [Column(TypeName = "varchar(64)")]
+ public string EndIp { get; set; } = string.Empty;
+
+ ///
+ /// 建立时间
+ ///
+ [Column(TypeName = "timestamptz")]
+ public DateTime CreateTime { get; set; }
+
+ ///
+ /// 最后更新时间
+ ///
+ [Column(TypeName = "timestamptz")]
+ public DateTime? UpdateTime { get; set; }
+
+ }
+}
diff --git a/Atomx.Common/Entities/UserAccessControl.cs b/Atomx.Common/Entities/UserAccessControl.cs
new file mode 100644
index 0000000..0d3e394
--- /dev/null
+++ b/Atomx.Common/Entities/UserAccessControl.cs
@@ -0,0 +1,19 @@
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace Atomx.Common.Entities
+{
+ ///
+ /// 用户访问控制表
+ ///
+ [Table("UserAccessControls")]
+ public class UserAccessControl
+ {
+ ///
+ /// 数据ID
+ ///
+ [DatabaseGenerated(DatabaseGeneratedOption.None)]
+ [Key]
+ public long Id { get; set; }
+ }
+}
diff --git a/Atomx.Data/CacheServices/AreaCacheService.cs b/Atomx.Data/CacheServices/AreaCacheService.cs
index 94d8743..b392196 100644
--- a/Atomx.Data/CacheServices/AreaCacheService.cs
+++ b/Atomx.Data/CacheServices/AreaCacheService.cs
@@ -42,6 +42,14 @@ namespace Atomx.Data.CacheServices
///
Task> GetAreas(long countryId, bool? reload = false);
+ ///
+ /// 获取城市地区数据
+ ///
+ ///
+ ///
+ ///
+ Task GetArea(long countryId, long areaId);
+
///
/// 更新调整缓存数据
///
@@ -199,6 +207,19 @@ namespace Atomx.Data.CacheServices
return cacheData;
}
+ ///
+ /// 获取城市地区数据
+ ///
+ ///
+ ///
+ ///
+ public async Task 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);