using Masuit.MyBlogs.Core.Common; using Masuit.MyBlogs.Core.Configs; using Masuit.MyBlogs.Core.Models.ViewModel; using Masuit.Tools; using Masuit.Tools.Core.Validator; using Masuit.Tools.Models; using MaxMind.GeoIP2.Exceptions; using MaxMind.GeoIP2.Responses; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Polly; using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using TimeZoneConverter; #if DEBUG #endif namespace Masuit.MyBlogs.Core.Controllers { /// /// 黑科技 /// [Route("tools")] public class ToolsController : BaseController { private readonly HttpClient _httpClient; public ToolsController(IHttpClientFactory httpClientFactory) { _httpClient = httpClientFactory.CreateClient(); } /// /// 获取ip地址详细信息 /// /// /// [Route("ip"), Route("ip/{ip?}", Order = 1), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "ip" }, VaryByHeader = "Cookie")] public async Task GetIpInfo([IsIPAddress] string ip) { if (string.IsNullOrEmpty(ip)) { ip = ClientIP; } if (ip.IsPrivateIP()) { return Ok("内网IP"); } ViewBag.IP = ip; var cityInfo = Policy.Handle().Fallback(() => new CityResponse()).Execute(() => CommonHelper.MaxmindReader.City(ip)); var location = ip.GetIPLocation(); var address = new IpInfo() { CityInfo = cityInfo, Address = $"{location}(UTC{TZConvert.GetTimeZoneInfo(cityInfo.Location.TimeZone ?? "Asia/Shanghai").BaseUtcOffset.Hours:+#;-#;0})", Asn = ip.GetIPAsn(), IsProxy = location.Contains(new[] { "cloud", "Compute", "Serv", "Tech", "Solution", "Host", "云", "Data Services" }) || await ip.IsProxy() }; if (Request.Method.Equals(HttpMethods.Get)) { return View(address); } return Json(address); } /// /// 根据经纬度获取详细地理信息 /// /// /// /// [HttpGet("pos"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "lat", "lng" }, VaryByHeader = "Cookie")] public async Task Position(string lat, string lng) { if (string.IsNullOrEmpty(lat) || string.IsNullOrEmpty(lng)) { var ip = ClientIP; #if DEBUG var r = new Random(); ip = $"{r.Next(210)}.{r.Next(255)}.{r.Next(255)}.{r.Next(255)}"; #endif var location = Policy.Handle().Fallback(() => new CityResponse()).Execute(() => CommonHelper.MaxmindReader.City(ip)); var address = new PhysicsAddress() { Status = 0, AddressResult = new AddressResult() { FormattedAddress = ip.GetIPLocation(), Location = new Location() { Lng = location.Location.Longitude ?? 0, Lat = location.Location.Latitude ?? 0 } } }; return View(address); } var s = await _httpClient.GetStringAsync($"http://api.map.baidu.com/geocoder/v2/?location={lat},{lng}&output=json&pois=1&ak={AppConfig.BaiduAK}", new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token).ContinueWith(t => { if (t.IsCompletedSuccessfully) { return JsonConvert.DeserializeObject(t.Result); } return new PhysicsAddress(); }); return View(s); } /// /// 详细地理信息转经纬度 /// /// /// [Route("addr"), ResponseCache(Duration = 600, VaryByQueryKeys = new[] { "addr" }, VaryByHeader = "Cookie")] public async Task Address(string addr) { if (string.IsNullOrEmpty(addr)) { var ip = ClientIP; #if DEBUG Random r = new Random(); ip = $"{r.Next(210)}.{r.Next(255)}.{r.Next(255)}.{r.Next(255)}"; #endif var location = Policy.Handle().Fallback(() => new CityResponse()).Execute(() => CommonHelper.MaxmindReader.City(ip)); var address = new PhysicsAddress() { Status = 0, AddressResult = new AddressResult() { FormattedAddress = ip.GetIPLocation(), Location = new Location() { Lng = location.Location.Longitude ?? 0, Lat = location.Location.Latitude ?? 0 } } }; ViewBag.Address = address.AddressResult.FormattedAddress; if (Request.Method.Equals(HttpMethods.Get)) { return View(address.AddressResult.Location); } return Json(address.AddressResult.Location); } ViewBag.Address = addr; var physicsAddress = await _httpClient.GetStringAsync($"http://api.map.baidu.com/geocoder/v2/?output=json&address={addr}&ak={AppConfig.BaiduAK}", new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token).ContinueWith(t => { if (t.IsCompletedSuccessfully) { return JsonConvert.DeserializeObject(t.Result); } return new PhysicsAddress(); }); if (Request.Method.Equals(HttpMethods.Get)) { return View(physicsAddress?.AddressResult?.Location); } return Json(physicsAddress?.AddressResult?.Location); } } }