Compare commits

...

2 Commits

Author SHA1 Message Date
5e25d68faf Merge remote-tracking branch 'origin/main' 2026-04-15 15:42:26 +08:00
d4c7138dc3 app添加自动获取定位功能 2026-04-15 15:36:16 +08:00
6 changed files with 207 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
package com.ruoyi.fadapp.controller;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.fadapp.service.IFadAppLocationService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* FAD APP 定位控制器
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/fadapp/location")
public class FadAppLocationController {
private final IFadAppLocationService locationService;
/**
* 根据经纬度获取城市
*
* @param latitude 纬度
* @param longitude 经度
* @return 城市名称
*/
@GetMapping("/city")
public R<String> getCity(@RequestParam Double latitude, @RequestParam Double longitude) {
return R.ok(locationService.getCityByLocation(latitude, longitude));
}
}

View File

@@ -11,9 +11,18 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.NotNull;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* FAD APP用户管理Controller
@@ -26,6 +35,7 @@ import javax.validation.constraints.NotNull;
@RequestMapping("/fadapp/user")
public class FadAppUserController extends BaseController {
private static final String IPSTACK_ACCESS_KEY = "";
private final IFadAppUserService userService;
/**
@@ -63,4 +73,56 @@ public class FadAppUserController extends BaseController {
public R<Object> getUserStats() {
return R.ok(userService.getUserStats());
}
/**
* 根据经纬度获取城市
*/
@GetMapping("/location/city")
public R<Object> getCityByLocation(@RequestParam Double latitude,
@RequestParam Double longitude) {
return R.ok(resolveCity(latitude, longitude));
}
private String resolveCity(Double latitude, Double longitude) {
if (latitude == null || longitude == null) {
return "";
}
try {
String urlStr = "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat="
+ URLEncoder.encode(String.valueOf(latitude), StandardCharsets.UTF_8.name())
+ "&lon=" + URLEncoder.encode(String.valueOf(longitude), StandardCharsets.UTF_8.name())
+ "&zoom=10&addressdetails=1";
HttpURLConnection connection = (HttpURLConnection) new URL(urlStr).openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setRequestProperty("User-Agent", "FAD-App/1.0");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
return extractCity(result.toString());
}
} catch (Exception e) {
return "";
}
}
private String extractCity(String json) {
if (json == null || json.isEmpty()) {
return "";
}
String[] keys = new String[]{"city", "town", "village", "county", "state"};
for (String key : keys) {
Pattern pattern = Pattern.compile("\\\"" + key + "\\\"\\s*:\\s*\\\"([^\\\"]+)\\\"");
Matcher matcher = pattern.matcher(json);
if (matcher.find()) {
return matcher.group(1);
}
}
return "";
}
}

View File

@@ -0,0 +1,16 @@
package com.ruoyi.fadapp.service;
/**
* FAD APP 定位服务接口
*/
public interface IFadAppLocationService {
/**
* 根据经纬度获取城市
*
* @param latitude 纬度
* @param longitude 经度
* @return 城市名称
*/
String getCityByLocation(Double latitude, Double longitude);
}

View File

@@ -0,0 +1,87 @@
package com.ruoyi.fadapp.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.fadapp.service.IFadAppLocationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* FAD APP 定位服务实现
*/
@Slf4j
@Service
public class FadAppLocationServiceImpl implements IFadAppLocationService {
private static final String AMAP_REVERSE_URL = "https://restapi.amap.com/v3/geocode/regeo";
private final RestTemplate restTemplate = new RestTemplate();
@Value("${fad.amap.key:}")
private String amapKey;
@Override
public String getCityByLocation(Double latitude, Double longitude) {
if (latitude == null || longitude == null) {
return "";
}
if (!org.springframework.util.StringUtils.hasText(amapKey)) {
log.warn("高德地图 key 未配置");
return "";
}
try {
Map<String, Object> params = new LinkedHashMap<>();
params.put("key", amapKey);
params.put("location", longitude + "," + latitude);
params.put("extensions", "base");
params.put("batch", "false");
params.put("roadlevel", 0);
params.put("output", "JSON");
StringBuilder url = new StringBuilder(AMAP_REVERSE_URL).append("?");
params.forEach((key, value) -> url.append(key).append("=").append(value).append("&"));
url.setLength(url.length() - 1);
JSONObject response = restTemplate.getForObject(url.toString(), JSONObject.class);
if (response == null) {
return "";
}
if (!"1".equals(response.getString("status"))) {
log.warn("高德逆地理编码失败: {}", response);
return "";
}
JSONObject regeocode = response.getJSONObject("regeocode");
if (regeocode == null) {
return "";
}
JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
if (addressComponent == null) {
return "";
}
String city = addressComponent.getString("city");
if (org.springframework.util.StringUtils.hasText(city)) {
return city;
}
String province = addressComponent.getString("province");
if (org.springframework.util.StringUtils.hasText(province)) {
return province;
}
return "";
} catch (Exception e) {
log.warn("根据经纬度获取城市失败, latitude={}, longitude={}, err={}", latitude, longitude, e.getMessage());
return "";
}
}
}

View File

@@ -0,0 +1,3 @@
fad:
amap:
key: 978ae5bc551f57d172d3e397af5a6f67

View File

@@ -317,3 +317,8 @@ flowable:
check-process-definitions: false
# 关闭历史任务定时任务job
async-history-executor-activate: false
fad:
amap:
key: 978ae5bc551f57d172d3e397af5a6f67