diff --git a/ZR.Admin.WebApi/Controllers/WebApiController.cs b/ZR.Admin.WebApi/Controllers/WebApiController.cs
index 67786b1..18707bb 100644
--- a/ZR.Admin.WebApi/Controllers/WebApiController.cs
+++ b/ZR.Admin.WebApi/Controllers/WebApiController.cs
@@ -7,6 +7,11 @@ using System.Web;
using Org.BouncyCastle.Utilities;
using System.Net;
+using ZR.Common;
+using ZR.Model.Dto;
+using Infrastructure.Model;
+using System.Threading.Tasks;
+using ZR.Common.Model;
namespace ZR.Admin.WebApi.Controllers
{
@@ -18,6 +23,143 @@ namespace ZR.Admin.WebApi.Controllers
[ApiExplorerSettings(GroupName = "webapi")]
public class WebApiController : BaseController
{
-
+ private readonly TencentMapService _tencentMapService;
+
+ public WebApiController(TencentMapService tencentMapService)
+ {
+ _tencentMapService = tencentMapService;
+ }
+
+ ///
+ /// 转换 GPS 经纬度到腾讯地图坐标
+ ///
+ /// 坐标转换请求参数
+ /// 转换后的坐标
+ [HttpPost]
+ [Route("GetLocationTranslate")]
+ public async Task GetLocationTranslate([FromBody] CoordinateTranslateRequest request)
+ {
+ try
+ {
+ if (request == null || string.IsNullOrWhiteSpace(request.Locations))
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
+ }
+
+ var result = await _tencentMapService.GetLocationTranslateAsync(request.Locations, request.Type);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
+ }
+ }
+
+ ///
+ /// 根据坐标获取地址信息
+ ///
+ /// 地理编码请求参数
+ /// 地址信息
+ [HttpPost]
+ [Route("GetLocationGeocoder")]
+ public async Task GetLocationGeocoder([FromBody] GeocoderRequest request)
+ {
+ try
+ {
+ if (request == null || string.IsNullOrWhiteSpace(request.Location))
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
+ }
+
+ var result = await _tencentMapService.GetLocationGeocoderAsync(request.Location);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
+ }
+ }
+
+ ///
+ /// 批量转换GPS坐标并获取地址
+ ///
+ /// 坐标转换请求参数
+ /// 转换后的坐标和地址信息
+ [HttpPost]
+ [Route("GetLocationTranslateAndGeocoder")]
+ public async Task GetLocationTranslateAndGeocoder([FromBody] CoordinateTranslateRequest request)
+ {
+ try
+ {
+ if (request == null || string.IsNullOrWhiteSpace(request.Locations))
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
+ }
+
+ var result = await _tencentMapService.GetLocationTranslateAndGeocoderAsync(request.Locations);
+ return SUCCESS(new
+ {
+ Location = result.Location,
+ Address = result.Address
+ });
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
+ }
+ }
+
+ ///
+ /// 转换 GPS 经纬度到腾讯地图坐标 (GET方式)
+ ///
+ /// 坐标点,格式:lat,lng;lat,lng
+ /// 转换类型,默认1表示GPS坐标转腾讯坐标
+ /// 转换后的坐标
+ [HttpGet]
+ [Route("/webapi/GetLocationTranslate")]
+ [AllowAnonymous]
+ public async Task GetLocationTranslateGet([FromQuery] string locations, [FromQuery] int type = 1)
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(locations))
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
+ }
+
+ var result = await _tencentMapService.GetLocationTranslateAsync(locations, type);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
+ }
+ }
+
+ ///
+ /// 根据坐标获取地址信息 (GET方式)
+ ///
+ /// 坐标点,格式:lat,lng
+ /// 地址信息
+ [HttpGet]
+ [Route("/webapi/GetLocationGeocoder")]
+ [AllowAnonymous]
+ public async Task GetLocationGeocoderGet([FromQuery] string location)
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(location))
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
+ }
+
+ var result = await _tencentMapService.GetLocationGeocoderAsync(location);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
+ }
+ }
}
}
diff --git a/ZR.Admin.WebApi/Controllers/WxOpenController.cs b/ZR.Admin.WebApi/Controllers/WxOpenController.cs
index 67fb8c6..8acf97c 100644
--- a/ZR.Admin.WebApi/Controllers/WxOpenController.cs
+++ b/ZR.Admin.WebApi/Controllers/WxOpenController.cs
@@ -5,7 +5,7 @@ using SKIT.FlurlHttpClient.Wechat.Api.Models;
using System.Web;
-
+
namespace ZR.Admin.WebApi.Controllers
{
///
@@ -16,11 +16,11 @@ namespace ZR.Admin.WebApi.Controllers
public class WxOpenController : BaseController
{
private readonly WechatApiClient _client;
-
+
public WxOpenController(WechatApiClient client)
{
_client = client;
-
+
}
diff --git a/ZR.Admin.WebApi/Program.cs b/ZR.Admin.WebApi/Program.cs
index 8b25e9d..8d3ea75 100644
--- a/ZR.Admin.WebApi/Program.cs
+++ b/ZR.Admin.WebApi/Program.cs
@@ -84,6 +84,10 @@ if (!string.IsNullOrEmpty(GaoDeKey))
{
GeoCodeService.ApiKey = GaoDeKey;
}
+
+// 注册腾讯地图服务
+builder.Services.AddHttpClient();
+builder.Services.AddSingleton();
builder.Services.AddMvc(options =>
{
options.Filters.Add(typeof(GlobalActionMonitor));//全局注册
diff --git a/ZR.Admin.WebApi/appsettings.json b/ZR.Admin.WebApi/appsettings.json
index dfd5c45..67078bd 100644
--- a/ZR.Admin.WebApi/appsettings.json
+++ b/ZR.Admin.WebApi/appsettings.json
@@ -125,5 +125,8 @@
"tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
"vuePath": "", //前端代码存储路径eg:D:\Work\ZRAdmin-Vue3
"uniappPath": "D:\\Work" //h5前端代码存储路径
+ },
+ "TencentMap": {
+ "Key": "2DYBZ-V4N3W-VQ4RA-Y22V5-BXA2E-53FYV" //腾讯地图key
}
}
diff --git a/ZR.Common/Model/TencentMapDto.cs b/ZR.Common/Model/TencentMapDto.cs
new file mode 100644
index 0000000..67a7813
--- /dev/null
+++ b/ZR.Common/Model/TencentMapDto.cs
@@ -0,0 +1,122 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace ZR.Common.Model
+{
+ ///
+ /// 腾讯地图坐标对象
+ ///
+ public class MapLocation
+ {
+ ///
+ /// 纬度
+ ///
+ [JsonPropertyName("lat")]
+ public double Lat { get; set; }
+
+ ///
+ /// 经度
+ ///
+ [JsonPropertyName("lng")]
+ public double Lng { get; set; }
+ }
+
+ ///
+ /// 腾讯地图API响应对象
+ ///
+ public class MapApiResponse
+ {
+ ///
+ /// 状态码
+ ///
+ [JsonPropertyName("status")]
+ public int Status { get; set; }
+
+ ///
+ /// 状态信息
+ ///
+ [JsonPropertyName("message")]
+ public string Message { get; set; }
+
+ ///
+ /// 请求ID
+ ///
+ [JsonPropertyName("request_id")]
+ public string RequestId { get; set; }
+
+ ///
+ /// 坐标列表
+ ///
+ [JsonPropertyName("locations")]
+ public List Locations { get; set; }
+ }
+
+ ///
+ /// 腾讯地图地理编码结果
+ ///
+ public class MapGeocoderResult
+ {
+ ///
+ /// 地址
+ ///
+ [JsonPropertyName("address")]
+ public string Address { get; set; }
+ }
+
+ ///
+ /// 腾讯地图地理编码API响应
+ ///
+ public class MapGeocoderApiResponse
+ {
+ ///
+ /// 状态码
+ ///
+ [JsonPropertyName("status")]
+ public int Status { get; set; }
+
+ ///
+ /// 状态信息
+ ///
+ [JsonPropertyName("message")]
+ public string Message { get; set; }
+
+ ///
+ /// 请求ID
+ ///
+ [JsonPropertyName("request_id")]
+ public string RequestId { get; set; }
+
+ ///
+ /// 地理编码结果
+ ///
+ [JsonPropertyName("result")]
+ public MapGeocoderResult Result { get; set; }
+ }
+
+ ///
+ /// 坐标转换请求参数
+ ///
+ public class CoordinateTranslateRequest
+ {
+ ///
+ /// 坐标点,格式:lat,lng;lat,lng
+ ///
+ public string Locations { get; set; }
+
+ ///
+ /// 转换类型:1-GPS坐标转腾讯坐标
+ ///
+ public int Type { get; set; } = 1;
+ }
+
+ ///
+ /// 地理编码请求参数
+ ///
+ public class GeocoderRequest
+ {
+ ///
+ /// 坐标点,格式:lat,lng
+ ///
+ public string Location { get; set; }
+ }
+}
diff --git a/ZR.Common/TencentMapService.cs b/ZR.Common/TencentMapService.cs
new file mode 100644
index 0000000..dfc7896
--- /dev/null
+++ b/ZR.Common/TencentMapService.cs
@@ -0,0 +1,130 @@
+using Infrastructure;
+
+using System;
+using System.Net.Http;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+using ZR.Common.Model;
+
+namespace ZR.Common
+{
+ ///
+ /// 腾讯地图服务
+ ///
+ public class TencentMapService
+ {
+ private readonly HttpClient _httpClient;
+ private readonly string _apiKey = AppSettings.GetConfig("TencentMap:KEY");
+ private const string BaseUrl = "https://apis.map.qq.com/";
+
+ public TencentMapService(HttpClient httpClient)
+ {
+ _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
+
+ }
+
+ ///
+ /// 转换 GPS 经纬度到腾讯地图坐标
+ ///
+ /// 坐标点,格式:lat,lng;lat,lng
+ /// 转换类型,默认1表示GPS坐标转腾讯坐标
+ /// 转换后的坐标
+ public async Task GetLocationTranslateAsync(string locations, int type = 1)
+ {
+ if (string.IsNullOrWhiteSpace(locations))
+ {
+ throw new ArgumentException("坐标点不能为空", nameof(locations));
+ }
+
+ var url = $"{BaseUrl}ws/coord/v1/translate?locations={locations}&type={type}&key={_apiKey}";
+
+ try
+ {
+ var response = await _httpClient.GetAsync(url);
+ response.EnsureSuccessStatusCode();
+
+ var content = await response.Content.ReadAsStringAsync();
+ var mapResponse = JsonSerializer.Deserialize(content, new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true
+ });
+
+ if (mapResponse?.Status == 0 && mapResponse.Locations?.Count > 0)
+ {
+ return mapResponse.Locations[0];
+ }
+ else
+ {
+ throw new Exception($"坐标转换失败: {mapResponse?.Message}");
+ }
+ }
+ catch (HttpRequestException ex)
+ {
+ throw new Exception("请求腾讯地图API失败", ex);
+ }
+ catch (JsonException ex)
+ {
+ throw new Exception("解析腾讯地图API响应失败", ex);
+ }
+ }
+
+ ///
+ /// 根据转换后的经纬度获取地址
+ ///
+ /// 坐标点,格式:lat,lng
+ /// 地址信息
+ public async Task GetLocationGeocoderAsync(string location)
+ {
+ if (string.IsNullOrWhiteSpace(location))
+ {
+ throw new ArgumentException("坐标点不能为空", nameof(location));
+ }
+
+ var url = $"{BaseUrl}ws/geocoder/v1/?location={location}&key={_apiKey}";
+
+ try
+ {
+ var response = await _httpClient.GetAsync(url);
+ response.EnsureSuccessStatusCode();
+
+ var content = await response.Content.ReadAsStringAsync();
+ var geocoderResponse = JsonSerializer.Deserialize(content, new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true
+ });
+
+ if (geocoderResponse?.Status == 0 && geocoderResponse.Result != null)
+ {
+ return geocoderResponse.Result.Address;
+ }
+ else
+ {
+ throw new Exception($"地理编码失败: {geocoderResponse?.Message}");
+ }
+ }
+ catch (HttpRequestException ex)
+ {
+ throw new Exception("请求腾讯地图API失败", ex);
+ }
+ catch (JsonException ex)
+ {
+ throw new Exception("解析腾讯地图API响应失败", ex);
+ }
+ }
+
+ ///
+ /// 批量转换GPS坐标并获取地址
+ ///
+ /// 坐标点,格式:lat,lng;lat,lng
+ /// 转换后的坐标和地址信息
+ public async Task<(MapLocation Location, string Address)> GetLocationTranslateAndGeocoderAsync(string locations)
+ {
+ var translatedLocation = await GetLocationTranslateAsync(locations);
+ var locationString = $"{translatedLocation.Lat},{translatedLocation.Lng}";
+ var address = await GetLocationGeocoderAsync(locationString);
+
+ return (translatedLocation, address);
+ }
+ }
+}