调整地区数据缓存
This commit is contained in:
@@ -54,22 +54,6 @@ namespace Atomx.Admin.Controllers
|
|||||||
_localizer = localizer;
|
_localizer = localizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("select/{id}")]
|
|
||||||
public IActionResult Select(long id)
|
|
||||||
{
|
|
||||||
var list = new List<KeyValue>();
|
|
||||||
var query = from p in _dbContext.Areas
|
|
||||||
where p.ParentId == id && 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>
|
||||||
@@ -78,7 +62,7 @@ namespace Atomx.Admin.Controllers
|
|||||||
/// <param name="size"></param>
|
/// <param name="size"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("search")]
|
[HttpPost("search")]
|
||||||
public IActionResult AddressList(AreaSearch search, int page, int size = 20)
|
public IActionResult Search(AreaSearch search, int page, int size = 20)
|
||||||
{
|
{
|
||||||
if (page < 1)
|
if (page < 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Atomx.Admin.Client.Models;
|
using Atomx.Admin.Client.Models;
|
||||||
using Atomx.Admin.Services;
|
using Atomx.Admin.Services;
|
||||||
using Atomx.Common.Constants;
|
|
||||||
using Atomx.Common.Entities;
|
using Atomx.Common.Entities;
|
||||||
using Atomx.Common.Enums;
|
using Atomx.Common.Enums;
|
||||||
using Atomx.Common.Models;
|
using Atomx.Common.Models;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Atomx.Admin.Controllers
|
namespace Atomx.Admin.Controllers
|
||||||
{
|
{
|
||||||
@@ -50,6 +51,21 @@ 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("tree/{countryId:long}")]
|
||||||
|
public async Task<IActionResult> GetTree(long countryId, int page, int size = 20)
|
||||||
|
{
|
||||||
|
var list = await _cacheService.GetAreaTree(countryId);
|
||||||
|
|
||||||
|
return new JsonResult(new ApiResult<List<KeyValueTree>>().IsSuccess(list));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据查询
|
/// 数据查询
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -58,7 +74,7 @@ namespace Atomx.Admin.Controllers
|
|||||||
/// <param name="size"></param>
|
/// <param name="size"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("select/{countryId:long}")]
|
[HttpGet("select/{countryId:long}")]
|
||||||
public IActionResult AddressList(long countryId, int page, int size = 20)
|
public IActionResult Select(long countryId, int page, int size = 20)
|
||||||
{
|
{
|
||||||
var list = new List<KeyValue>();
|
var list = new List<KeyValue>();
|
||||||
var query = from p in _dbContext.StateProvinces
|
var query = from p in _dbContext.StateProvinces
|
||||||
@@ -77,7 +93,7 @@ namespace Atomx.Admin.Controllers
|
|||||||
/// <param name="size"></param>
|
/// <param name="size"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("search")]
|
[HttpPost("search")]
|
||||||
public IActionResult AddressList(StateProvinceSearch search, int page, int size = 20)
|
public IActionResult Search(StateProvinceSearch search, int page, int size = 20)
|
||||||
{
|
{
|
||||||
if (page < 1)
|
if (page < 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 省州数据缓存
|
/// 省州数据缓存
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string Province = "Area.Province";
|
public const string StateProvince = "Area.Province.";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 城市数据缓存
|
/// 城市数据缓存
|
||||||
|
|||||||
@@ -10,21 +10,37 @@ namespace Atomx.Data.CacheServices
|
|||||||
/// 获取国家数据
|
/// 获取国家数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<List<Area>> GetCountry(bool? reload = false);
|
Task<List<Country>> GetCountries(bool? reload = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 通过ID获取国家名称
|
/// 通过ID获取国家
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="countryId"></param>
|
/// <param name="countryId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<string> GetCountryName(long countryId);
|
Task<Country> GetCountry(long countryId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据上级ID获取下级数据
|
/// 获取区域数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="parentId"></param>
|
/// <param name="parentId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<List<Area>> GetAreas(long parentId, bool? reload = false);
|
Task<List<StateProvince>> GetStateProvinces(long countryId, bool? reload = false);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取州省数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="countryId"></param>
|
||||||
|
/// <param name="stateProvinceId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<StateProvince> GetStateProvince(long countryId, long stateProvinceId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取地区数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="countryId"></param>
|
||||||
|
/// <param name="reload"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<List<Area>> GetAreas(long countryId, bool? reload = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新调整缓存数据
|
/// 更新调整缓存数据
|
||||||
@@ -33,51 +49,67 @@ namespace Atomx.Data.CacheServices
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task ResetArea(Area area);
|
Task ResetArea(Area area);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新调整州省缓存数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stateProvince"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task ResetStateProvince(StateProvince stateProvince);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新调整国家缓存数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="country"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task ResetCountry(Country country);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取国家-省份-城市树形数据
|
/// 获取国家-省份-城市树形数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="countryId"></param>
|
/// <param name="countryId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<KeyValueTree> GetAreaTreeAsync(long countryId);
|
Task<List<KeyValueTree>> GetAreaTree(long countryId, bool? reload = false);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public partial class CacheService : ICacheService
|
public partial class CacheService : ICacheService
|
||||||
{
|
{
|
||||||
public async Task<List<KeyValueTree>> GetAreaTreeAsync(long countryId, bool? reload = false)
|
public async Task<List<KeyValueTree>> GetAreaTree(long countryId, bool? reload = false)
|
||||||
{
|
{
|
||||||
|
bool reloadData = reload.HasValue ? reload.Value : false;
|
||||||
var cacheData = await GetCacheAsync<List<KeyValueTree>>($"{CacheKeys.CountryTree}{countryId}");
|
var cacheData = await GetCacheAsync<List<KeyValueTree>>($"{CacheKeys.CountryTree}{countryId}");
|
||||||
if (cacheData == null || reload.HasValue && reload.Value)
|
if (cacheData == null || reloadData)
|
||||||
{
|
{
|
||||||
var state = _dbContext.StateProvinces.Where(p => p.CountryId == countryId).ToList();
|
var states = await GetStateProvinces(countryId);
|
||||||
var cities = _dbContext.Areas.Where(p => p.CountryId == countryId).ToList();
|
var cities = await GetAreas(countryId);
|
||||||
cacheData = (from s in state
|
|
||||||
select new KeyValueTree
|
var tree = new List<KeyValueTree>();
|
||||||
|
|
||||||
|
foreach (var state in states)
|
||||||
{
|
{
|
||||||
Key = s.Id.ToString(),
|
var item = new KeyValueTree
|
||||||
Value = s.Name,
|
|
||||||
Children = (from c in cities
|
|
||||||
where c.ParentId == s.Id
|
|
||||||
select new KeyValueTree
|
|
||||||
{
|
{
|
||||||
Key = c.Id.ToString(),
|
Key = state.Id.ToString(),
|
||||||
Value = c.Name
|
Value = state.Name,
|
||||||
}).ToList()
|
Children = new List<KeyValueTree>()
|
||||||
}).ToList();
|
};
|
||||||
await SetCacheAsync(CacheKeys.Country, cacheData);
|
|
||||||
|
item.Children = BuildAreaTree(state.Id, cities, new List<KeyValueTree>());
|
||||||
|
tree.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
await SetCacheAsync($"{CacheKeys.CountryTree}{countryId}", tree);
|
||||||
}
|
}
|
||||||
return cacheData;
|
return cacheData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Area>> GetCountry(bool? reload = false)
|
public async Task<List<Country>> GetCountries(bool? reload = false)
|
||||||
{
|
{
|
||||||
bool reloadData = reload.HasValue ? reload.Value : false;
|
bool reloadData = reload.HasValue ? reload.Value : false;
|
||||||
|
|
||||||
var cacheData = await GetCacheAsync<List<Area>>(CacheKeys.Country);
|
var cacheData = await GetCacheAsync<List<Country>>(CacheKeys.Country);
|
||||||
if (cacheData == null || reloadData)
|
if (cacheData == null || reloadData)
|
||||||
{
|
{
|
||||||
var countries = (from p in _dbContext.Areas
|
var countries = (from p in _dbContext.Countries
|
||||||
where p.ParentId == 0
|
where p.Enabled
|
||||||
select p).ToList();
|
select p).ToList();
|
||||||
await SetCacheAsync(CacheKeys.Country, countries);
|
await SetCacheAsync(CacheKeys.Country, countries);
|
||||||
return countries;
|
return countries;
|
||||||
@@ -86,47 +118,144 @@ namespace Atomx.Data.CacheServices
|
|||||||
return cacheData;
|
return cacheData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetCountryName(long countryId)
|
public async Task<Country> GetCountry(long countryId)
|
||||||
{
|
{
|
||||||
var cacheData = await GetCountry();
|
var cacheData = await GetCountries();
|
||||||
var data = cacheData.SingleOrDefault(p => p.Id == countryId);
|
var data = cacheData.SingleOrDefault(p => p.Id == countryId);
|
||||||
if (data == null)
|
return data;
|
||||||
{
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
return data.Name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Area>> GetAreas(long parentId, bool? reload = false)
|
/// <summary>
|
||||||
|
/// 获取区域数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="countryId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<List<StateProvince>> GetStateProvinces(long countryId, bool? reload = false)
|
||||||
{
|
{
|
||||||
if (parentId == 0)
|
bool reloadData = reload.HasValue ? reload.Value : false;
|
||||||
|
var cacheData = await GetCacheAsync<List<StateProvince>>($"{CacheKeys.StateProvince}.{countryId}");
|
||||||
|
if (cacheData == null || reloadData)
|
||||||
{
|
{
|
||||||
return await GetCountry();
|
var stateProvinces = (from p in _dbContext.StateProvinces
|
||||||
|
where p.CountryId == countryId && p.Enabled
|
||||||
|
select p).ToList();
|
||||||
|
await SetCacheAsync($"{CacheKeys.StateProvince}.{countryId}", stateProvinces);
|
||||||
|
return stateProvinces;
|
||||||
|
|
||||||
}
|
}
|
||||||
var cacheData = await GetCacheAsync<List<Area>>($"{CacheKeys.Area}.{parentId}");
|
return cacheData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取州省数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stateProvinceId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<StateProvince> GetStateProvince(long countryId, long stateProvinceId)
|
||||||
|
{
|
||||||
|
var cacheData = await GetStateProvinces(countryId);
|
||||||
|
var data = cacheData.SingleOrDefault(p => p.Id == stateProvinceId);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取地区数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="countryId"></param>
|
||||||
|
/// <param name="reload"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<List<Area>> GetAreas(long countryId, bool? reload = false)
|
||||||
|
{
|
||||||
|
var cacheData = await GetCacheAsync<List<Area>>($"{CacheKeys.City}.{countryId}");
|
||||||
bool reloadData = reload.HasValue ? reload.Value : false;
|
bool reloadData = reload.HasValue ? reload.Value : false;
|
||||||
if (cacheData == null || reloadData)
|
if (cacheData == null || reloadData)
|
||||||
{
|
{
|
||||||
var data = (from p in _dbContext.Areas
|
List<Area> areas = new();
|
||||||
where p.ParentId == 0
|
var query = from p in _dbContext.Areas
|
||||||
select p).ToList();
|
where p.CountryId == countryId && p.Enabled
|
||||||
await SetCacheAsync(CacheKeys.Country, data);
|
select p;
|
||||||
return data;
|
var count = query.Count();
|
||||||
|
int size = 50;
|
||||||
|
var pageCount = (int)Math.Ceiling(count / (double)size) + 1;
|
||||||
|
for (var i = 1; i < pageCount; i++)
|
||||||
|
{
|
||||||
|
var list = query.Skip((i - 1) * size).Take(size).ToList();
|
||||||
|
areas.AddRange(list);
|
||||||
|
}
|
||||||
|
await SetCacheAsync(CacheKeys.Country, areas);
|
||||||
|
return areas;
|
||||||
}
|
}
|
||||||
return cacheData;
|
return cacheData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ResetArea(Area area)
|
public async Task ResetArea(Area area)
|
||||||
{
|
{
|
||||||
var cacheData = await GetAreas(area.ParentId);
|
var cacheData = await GetAreas(area.CountryId);
|
||||||
var data = cacheData.Where(p => p.Id == area.Id).SingleOrDefault();
|
var data = cacheData.Where(p => p.Id == area.Id).SingleOrDefault();
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
cacheData.Remove(data);
|
cacheData.Remove(data);
|
||||||
}
|
}
|
||||||
cacheData.Add(area);
|
cacheData.Add(area);
|
||||||
await SetCacheAsync($"{CacheKeys.Area}.{area.ParentId}", cacheData);
|
await SetCacheAsync($"{CacheKeys.City}.{area.CountryId}", cacheData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新调整州省缓存数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stateProvince"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task ResetStateProvince(StateProvince stateProvince)
|
||||||
|
{
|
||||||
|
var cacheData = await GetStateProvinces(stateProvince.CountryId);
|
||||||
|
var data = cacheData.Where(p => p.Id == stateProvince.Id).SingleOrDefault();
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
cacheData.Remove(data);
|
||||||
|
}
|
||||||
|
cacheData.Add(stateProvince);
|
||||||
|
await SetCacheAsync($"{CacheKeys.StateProvince}.{stateProvince.CountryId}", cacheData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新调整国家缓存数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="country"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task ResetCountry(Country country)
|
||||||
|
{
|
||||||
|
var cacheData = await GetCountries();
|
||||||
|
var data = cacheData.Where(p => p.Id == country.Id).SingleOrDefault();
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
cacheData.Remove(data);
|
||||||
|
}
|
||||||
|
cacheData.Add(country);
|
||||||
|
await SetCacheAsync($"{CacheKeys.Country}", cacheData);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
var item = new KeyValueTree
|
||||||
|
{
|
||||||
|
Key = area.Id.ToString(),
|
||||||
|
Value = area.Name,
|
||||||
|
Children = new List<KeyValueTree>()
|
||||||
|
};
|
||||||
|
var childs = areas.Where(p => p.ParentId == area.Id).ToList();
|
||||||
|
if (childs.Count > 0)
|
||||||
|
{
|
||||||
|
var childrenTrees = BuildAreaTree(area.Id, areas, result);
|
||||||
|
item.Children.AddRange(childrenTrees);
|
||||||
|
}
|
||||||
|
result.Add(item);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Atomx.Utils.Extension
|
|
||||||
{
|
|
||||||
public static class TreeExtension
|
|
||||||
{
|
|
||||||
public static List<T> ToTree<T>(this List<T> list, Func<T, string> getId, Func<T, string> getParentId, Action<T, List<T>> setChildren, string rootParentId = "0")
|
|
||||||
{
|
|
||||||
var lookup = new Dictionary<string, T>();
|
|
||||||
var result = new List<T>();
|
|
||||||
foreach (var item in list)
|
|
||||||
{
|
|
||||||
var id = getId(item);
|
|
||||||
lookup[id] = item;
|
|
||||||
}
|
|
||||||
foreach (var item in list)
|
|
||||||
{
|
|
||||||
var parentId = getParentId(item);
|
|
||||||
if (parentId == rootParentId || !lookup.ContainsKey(parentId))
|
|
||||||
{
|
|
||||||
result.Add(item);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var parent = lookup[parentId];
|
|
||||||
var children = new List<T>();
|
|
||||||
setChildren(parent, children);
|
|
||||||
children.Add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user