Skip to content

Commit 5e06328

Browse files
committed
feat: 增加 IRegionService 方法实现类
1 parent ad11f85 commit 5e06328

3 files changed

Lines changed: 194 additions & 0 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
namespace BootstrapBlazor.Components;
6+
7+
/// <summary>
8+
/// Region 类
9+
/// </summary>
10+
public readonly record struct CountyItem
11+
{
12+
/// <summary>
13+
/// 城市编码
14+
/// </summary>
15+
public string Code { get; init; }
16+
17+
/// <summary>
18+
/// 城市名称
19+
/// </summary>
20+
public string Name { get; init; }
21+
}

src/components/BootstrapBlazor.Region/Services/DefaultRegionService.cs

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,156 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33
// Website: https://www.blazor.zone or https://argozhang.github.io/
44

5+
#if NET9_0_OR_GREATER
6+
using System.Collections.Frozen;
7+
#endif
8+
9+
using System.Collections.Concurrent;
10+
using System.Runtime.CompilerServices;
11+
512
namespace BootstrapBlazor.Components;
613

714
class DefaultRegionService : IRegionService
815
{
16+
private static readonly ConcurrentDictionary<string, IReadOnlySet<string>> _citiesCache = new();
17+
private static readonly ConcurrentDictionary<string, IReadOnlySet<CountyItem>> _countiesCache = new();
18+
19+
private static bool _initialized = false;
20+
21+
#if NET9_0_OR_GREATER
22+
private static readonly Lock _lock = new();
23+
#else
24+
private static readonly object _lock = new();
25+
#endif
26+
27+
public IReadOnlySet<string> GetProvinces() => Provinces;
28+
29+
public IReadOnlySet<string> GetCities(string province)
30+
{
31+
LoadCityData();
32+
return _citiesCache.TryGetValue(province, out var cities) ? cities : new HashSet<string>();
33+
}
34+
35+
public IReadOnlySet<CountyItem> GetCounties(string city)
36+
{
37+
LoadCityData();
38+
return _countiesCache.TryGetValue(city, out var counties) ? counties : new HashSet<CountyItem>();
39+
}
40+
41+
public List<string> GetDetails(string county)
42+
{
43+
throw new NotImplementedException();
44+
}
45+
46+
private static void LoadCityData()
47+
{
48+
if (_initialized)
49+
{
50+
return;
51+
}
52+
53+
lock (_lock)
54+
{
55+
if (_initialized)
56+
{
57+
return;
58+
}
59+
60+
_initialized = true;
61+
var data = typeof(DefaultRegionService).Assembly.GetManifestResourceStream("BootstrapBlazor.Components.Data.data.json");
62+
if (data != null)
63+
{
64+
var city = "";
65+
HashSet<string> cities = [];
66+
HashSet<CountyItem>? counties = null;
67+
using var stream = new StreamReader(data);
68+
while (!stream.EndOfStream)
69+
{
70+
var content = stream.ReadLine();
71+
if (!string.IsNullOrEmpty(content))
72+
{
73+
var index = content.IndexOf(':');
74+
if (index == -1)
75+
{
76+
continue;
77+
}
78+
79+
var mem = content.AsMemory();
80+
var code = Trim(mem[0..index].ToString());
81+
var value = Trim(mem[(index + 1)..(mem.Length - 1)].ToString());
82+
83+
if (code[2..] == "0000")
84+
{
85+
city = value;
86+
cities = [];
87+
_citiesCache.TryAdd(value, cities);
88+
counties = null;
89+
continue;
90+
}
91+
92+
if (code[4..] == "00")
93+
{
94+
cities.Add(value);
95+
counties = [];
96+
_countiesCache.TryAdd(value, counties);
97+
continue;
98+
}
99+
100+
if (counties == null)
101+
{
102+
counties = [];
103+
_countiesCache.TryAdd(city, counties);
104+
}
105+
106+
counties.Add(new CountyItem() { Name = value, Code = code });
107+
}
108+
}
109+
}
110+
}
111+
}
112+
113+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
114+
private static string Trim(string segment) => segment.Replace("\"", string.Empty).Trim();
9115

116+
#if NET9_0_OR_GREATER
117+
private static readonly FrozenSet<string> Provinces =
118+
#else
119+
private static readonly HashSet<string> Provinces =
120+
#endif
121+
[
122+
"北京市",
123+
"天津市",
124+
"上海市",
125+
"重庆市",
126+
"河北省",
127+
"山西省",
128+
"辽宁省",
129+
"吉林省",
130+
"黑龙江省",
131+
"江苏省",
132+
"浙江省",
133+
"安徽省",
134+
"福建省",
135+
"江西省",
136+
"山东省",
137+
"河南省",
138+
"湖北省",
139+
"湖南省",
140+
"广东省",
141+
"海南省",
142+
"四川省",
143+
"贵州省",
144+
"云南省",
145+
"陕西省",
146+
"甘肃省",
147+
"青海省",
148+
"内蒙古自治区",
149+
"广西壮族自治区",
150+
"西藏自治区",
151+
"宁夏回族自治区",
152+
"新疆维吾尔自治区",
153+
"香港特别行政区",
154+
"澳门特别行政区",
155+
"台湾省"
156+
];
10157
}

src/components/BootstrapBlazor.Region/Services/IRegionService.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,30 @@ namespace BootstrapBlazor.Components;
99
/// </summary>
1010
public interface IRegionService
1111
{
12+
/// <summary>
13+
/// 获得所有省份数据
14+
/// </summary>
15+
/// <returns></returns>
16+
IReadOnlySet<string> GetProvinces();
17+
18+
/// <summary>
19+
/// 获得指定省份的城市数据
20+
/// </summary>
21+
/// <param name="province"></param>
22+
/// <returns></returns>
23+
IReadOnlySet<string> GetCities(string province);
24+
25+
/// <summary>
26+
/// 获得指定城市的区县数据
27+
/// </summary>
28+
/// <param name="city"></param>
29+
/// <returns></returns>
30+
IReadOnlySet<CountyItem> GetCounties(string city);
31+
32+
/// <summary>
33+
/// 获得指定区县的街道地址数据
34+
/// </summary>
35+
/// <param name="county"></param>
36+
/// <returns></returns>
37+
List<string> GetDetails(string county);
1238
}

0 commit comments

Comments
 (0)