增加功能:地理信息支持国际城市 closed #IUU35

#Issue
https://gitee.com/LongbowEnterprise/dashboard/issues?id=IUU35
This commit is contained in:
Argo Zhang 2019-03-29 18:18:56 +08:00
parent 4977a8d7f1
commit 136239a838
14 changed files with 276 additions and 26 deletions

Binary file not shown.

View File

@ -1,11 +1,11 @@
using Bootstrap.DataAccess;
using Longbow.Configuration;
using Bootstrap.DataAccess;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace Bootstrap.Admin
{
@ -15,6 +15,7 @@ namespace Bootstrap.Admin
internal class DefaultOnlineUsers : IOnlineUsers
{
private ConcurrentDictionary<string, OnlineUserCache> _onlineUsers = new ConcurrentDictionary<string, OnlineUserCache>();
private ConcurrentDictionary<string, string> _ipLocator = new ConcurrentDictionary<string, string>();
private HttpClient _client;
private IEnumerable<string> _local = new string[] { "::1", "127.0.0.1" };
/// <summary>
@ -59,28 +60,112 @@ namespace Bootstrap.Admin
/// <returns></returns>
public string RetrieveLocaleByIp(string ip = null)
{
if (DictHelper.RetrieveLocaleIP() == 0 || ip.IsNullOrEmpty() || _local.Any(p => p == ip)) return "本地连接";
if (string.IsNullOrEmpty(DictHelper.RetrieveLocaleIPSvr()) || ip.IsNullOrEmpty() || _local.Any(p => p == ip)) return "本地连接";
var url = ConfigurationManager.AppSettings["IPSvrUrl"];
var task = _client.GetAsJsonAsync<IPLocator>($"{url}{ip}");
task.Wait();
return task.Result.status == "0" ? string.Join(" ", task.Result.address.SpanSplit("|").Skip(1).Take(2)) : "XX XX";
return _ipLocator.GetOrAdd(ip, key =>
{
var ipSvr = DictHelper.RetrieveLocaleIPSvr();
var url = $"{DictHelper.RetrieveLocaleIPSvrUrl(ipSvr)}{ip}";
var task = ipSvr == "BaiDuIPSvr" ? RetrieveLocator<BaiDuIPLocator>(url) : RetrieveLocator<JuheIPLocator>(url);
task.Wait();
return task.Result;
});
}
private async Task<string> RetrieveLocator<T>(string url)
{
var result = await _client.GetAsJsonAsync<T>(url);
return result.ToString();
}
/// <summary>
///
/// </summary>
private class IPLocator
private class BaiDuIPLocator
{
/// <summary>
/// 详细地址信息
/// </summary>
public string address { get; set; }
public string Address { get; set; }
/// <summary>
/// 结果状态返回码
/// </summary>
public string status { get; set; }
public string Status { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Status == "0" ? string.Join(" ", Address.SpanSplit("|").Skip(1).Take(2)) : "XX XX";
}
}
private class JuheIPLocator
{
/// <summary>
///
/// </summary>
public string ResultCode { get; set; }
/// <summary>
///
/// </summary>
public string Reason { get; set; }
/// <summary>
///
/// </summary>
public JuheIPLocatorResult Result { get; set; }
/// <summary>
///
/// </summary>
/// <value></value>
public int Error_Code { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Error_Code != 0 ? "XX XX" : Result.ToString();
}
}
private class JuheIPLocatorResult
{
/// <summary>
///
/// </summary>
public string Country { get; set; }
/// <summary>
///
/// </summary>
public string Province { get; set; }
/// <summary>
///
/// </summary>
public string City { get; set; }
/// <summary>
///
/// </summary>
public string Isp { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Country != "中国" ? $"{Country} {Province} {Isp}" : $"{Province} {City} {Isp}";
}
}
}
}

View File

@ -1,4 +1,4 @@
{
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {

View File

@ -1,4 +1,4 @@
{
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
@ -49,7 +49,6 @@
}
}
],
"IPSvrUrl": "http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=",
"SwaggerPathBase": "/BA",
"AllowOrigins": "http://localhost,http://argo.zylweb.cn",
"KeyPath": "..\\..\\keys",

View File

@ -153,10 +153,17 @@ namespace Bootstrap.DataAccess
public int RetrieveCookieExpiresPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "Cookie保留时长" && d.Define == 0)?.Code, 7);
/// <summary>
/// 获得 项目是否获取登录地点 默认为false
/// 获得 IP地理位置
/// </summary>
/// <returns></returns>
public int RetrieveLocaleIP() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "获取IP地点" && d.Define == 0)?.Code, 0);
public string RetrieveLocaleIPSvr() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "IP地理位置接口" && d.Define == 0)?.Code;
/// <summary>
/// 获得 项目是否获取登录地点 默认为false
/// </summary>
/// <param name="ipSvr">服务提供名称</param>
/// <returns></returns>
public string RetrieveLocaleIPSvrUrl(string ipSvr) => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == ipSvr && d.Define == 0)?.Code;
/// <summary>
/// 获得 访问日志保留时长 默认为1个月

View File

@ -164,7 +164,13 @@ namespace Bootstrap.DataAccess
///
/// </summary>
/// <returns></returns>
public static int RetrieveLocaleIP() => DbContextManager.Create<Dict>().RetrieveLocaleIP();
public static string RetrieveLocaleIPSvr() => DbContextManager.Create<Dict>().RetrieveLocaleIPSvr();
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string RetrieveLocaleIPSvrUrl(string ipSvr) => DbContextManager.Create<Dict>().RetrieveLocaleIPSvrUrl(ipSvr);
/// <summary>
/// 访问日志保留时长 默认一个月

View File

@ -40,7 +40,9 @@ INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设
-- 时长单位 天
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'Cookie保留时长', '7', 0)
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'获取IP地点', '0', 0)
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'IP地理位置接口', 'JuheIPSvr', 0)
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0)
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0)
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'演示系统', '0', 0)
DELETE FROM Navigations

View File

@ -310,19 +310,33 @@
{
"_id": ObjectId("5bd6c73d5fa31256f77e4a44"),
"Category": "系统设置",
"Name": "获取IP地点",
"Code": "0",
"Name": "IP地理位置接口",
"Code": "JuheIPSvr",
"Define": NumberInt(0)
},
{
"_id": ObjectId("5bd6c73d5fa31256f77e4a45"),
"Category": "系统设置",
"Name": "BaiDuIPSvr",
"Code": "http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=",
"Define": NumberInt(0)
},
{
"_id": ObjectId("5bd6c73d5fa31256f77e4a46"),
"Category": "系统设置",
"Name": "JuheIPSvr",
"Code": "http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=",
"Define": NumberInt(0)
},
{
"_id": ObjectId("5bd6c73d5fa31256f77e4a47"),
"Category": "系统设置",
"Name": "访问日志保留时长",
"Code": "1",
"Define": NumberInt(0)
},
{
"_id": ObjectId("5bd6c73d5fa31256f77e4a46"),
"_id": ObjectId("5bd6c73d5fa31256f77e4a48"),
"Category": "系统设置",
"Name": "演示系统",
"Code": "0",

View File

@ -37,7 +37,9 @@ INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '访问
-- 时长单位 天
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'Cookie保留时长', '7', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '获取IP地点', '0', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'IP地理位置接口', 'JuheIPSvr', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '演示系统', '0', 0);
DELETE FROM Navigations;

View File

@ -37,7 +37,9 @@ INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '访问
-- 时长单位 天
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'Cookie保留时长', '7', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '获取IP地点', '0', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'IP地理位置接口', 'JuheIPSvr', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '演示系统', '0', 0);
DELETE FROM Navigations;

View File

@ -35,7 +35,9 @@ INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置
-- 时长单位 天
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', 'Cookie保留时长', '7', 0);
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', '获取IP地点', '0', 0);
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', 'IP地理位置接口', 'JuheIPSvr', 0);
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', 'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0);
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', 'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0);
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', '演示系统', '0', 0);
DELETE FROM Navigations;

View File

@ -1,4 +1,6 @@
using System;
using System.Linq;
using System.Net.Http;
using Xunit;
namespace Bootstrap.DataAccess
@ -129,7 +131,44 @@ namespace Bootstrap.DataAccess
public void RetrieveLocaleIP_Ok()
{
var dict = new Dict();
Assert.Equal(0, dict.RetrieveLocaleIP());
var ipSvr = dict.RetrieveLocaleIPSvr();
Assert.Equal("JuheIPSvr", ipSvr);
var ipUri = dict.RetrieveLocaleIPSvrUrl(ipSvr);
Assert.NotNull(ipUri);
}
[Fact]
public async void BaiduIPSvr_Ok()
{
var dict = new Dict();
var ipUri = dict.RetrieveLocaleIPSvrUrl("BaiDuIPSvr");
var client = HttpClientFactory.Create();
// 日本东京
var locator = await client.GetAsJsonAsync<BaiDuIPLocator>($"{ipUri}207.148.111.94");
Assert.NotEqual("0", locator.Status);
// 四川成都
locator = await client.GetAsJsonAsync<BaiDuIPLocator>($"{ipUri}182.148.123.196");
Assert.Equal("0", locator.Status);
}
[Fact]
public async void JuheIPSvr_Ok()
{
var dict = new Dict();
var ipUri = dict.RetrieveLocaleIPSvrUrl("JuheIPSvr");
// 日本东京
var client = HttpClientFactory.Create();
var locator = await client.GetAsJsonAsync<JuheIPLocator>($"{ipUri}207.148.111.94");
Assert.Equal(0, locator.Error_Code);
// 四川成都
locator = await client.GetAsJsonAsync<JuheIPLocator>($"{ipUri}182.148.123.196");
Assert.Equal(0, locator.Error_Code);
}
[Fact]
@ -138,5 +177,97 @@ namespace Bootstrap.DataAccess
var dict = new Dict();
Assert.Equal(1, dict.RetrieveAccessLogPeriod());
}
#region Private Class For Test
/// <summary>
///
/// </summary>
private class BaiDuIPLocator
{
/// <summary>
/// 详细地址信息
/// </summary>
public string Address { get; set; }
/// <summary>
/// 结果状态返回码
/// </summary>
public string Status { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Status == "0" ? string.Join(" ", Address.SpanSplit("|").Skip(1).Take(2)) : "XX XX";
}
}
private class JuheIPLocator
{
/// <summary>
///
/// </summary>
public string ResultCode { get; set; }
/// <summary>
///
/// </summary>
public string Reason { get; set; }
/// <summary>
///
/// </summary>
public JuheIPLocatorResult Result { get; set; }
/// <summary>
///
/// </summary>
/// <value></value>
public int Error_Code { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Error_Code != 0 ? "XX XX" : Result.ToString();
}
}
private class JuheIPLocatorResult
{
/// <summary>
///
/// </summary>
public string Country { get; set; }
/// <summary>
///
/// </summary>
public string Province { get; set; }
/// <summary>
///
/// </summary>
public string City { get; set; }
/// <summary>
///
/// </summary>
public string Isp { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Country != "中国" ? $"{Country} {Province} {Isp}" : $"{Province} {City} {Isp}";
}
}
#endregion
}
}

Binary file not shown.

View File

@ -1,4 +1,4 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
@ -60,7 +60,7 @@ namespace UnitTest
{
var dbPath = RetrievePath($"UnitTest{Path.DirectorySeparatorChar}DB{Path.DirectorySeparatorChar}UnitTest.db");
var dbFile = Path.Combine(AppContext.BaseDirectory, "UnitTest.db");
if (!File.Exists(dbFile)) File.Copy(dbPath, dbFile);
File.Copy(dbPath, dbFile, true);
builder.ConfigureAppConfiguration(app => app.AddInMemoryCollection(new KeyValuePair<string, string>[] {
new KeyValuePair<string, string>("DB:0:Enabled", "false"),