fix: 修复地图坐标校验与解析

- 小程序兼容字符串坐标并自动纠正历史经纬度反向数据

- 后台机构资料页增加经纬度与地址联动校验

- org 模块保存机构资料时拦截非法坐标输入
This commit is contained in:
2026-03-21 11:17:02 +08:00
parent 74543cb9bf
commit 728847a8e3
3 changed files with 218 additions and 19 deletions

View File

@@ -17,6 +17,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.util.List;
@@ -58,6 +59,7 @@ public class TenantOrgService {
profile.setCreatedBy(loginUser.userId());
profile.setDeleted(0);
}
CoordinateValue coordinates = parseCoordinates(request.hqAddress(), request.hqLatitude(), request.hqLongitude());
profile.setFirmName(request.firmName());
profile.setFirmShortName(request.firmShortName());
profile.setEnglishName(request.englishName());
@@ -68,8 +70,8 @@ public class TenantOrgService {
profile.setWebsiteUrl(request.websiteUrl());
profile.setWechatOfficialAccount(request.wechatOfficialAccount());
profile.setHqAddress(request.hqAddress());
profile.setHqLatitude(toBigDecimal(request.hqLatitude()));
profile.setHqLongitude(toBigDecimal(request.hqLongitude()));
profile.setHqLatitude(coordinates.latitude());
profile.setHqLongitude(coordinates.longitude());
profile.setUpdatedBy(loginUser.userId());
if (profile.getId() == null) {
orgFirmProfileMapper.insert(profile);
@@ -217,11 +219,51 @@ public class TenantOrgService {
);
}
private BigDecimal toBigDecimal(String value) {
if (value == null || value.isBlank()) {
return null;
private CoordinateValue parseCoordinates(String address, String latitude, String longitude) {
String latitudeText = normalizeCoordinate(latitude);
String longitudeText = normalizeCoordinate(longitude);
boolean hasLatitude = StringUtils.hasText(latitudeText);
boolean hasLongitude = StringUtils.hasText(longitudeText);
if (!hasLatitude && !hasLongitude) {
return new CoordinateValue(null, null);
}
return new BigDecimal(value);
if (!hasLatitude || !hasLongitude) {
throw new BusinessException("FIRM_COORDINATE_INVALID", "纬度和经度需同时填写");
}
if (!StringUtils.hasText(address)) {
throw new BusinessException("FIRM_ADDRESS_REQUIRED", "填写地图坐标时请同时填写详细地址");
}
BigDecimal latitudeValue = parseCoordinateValue(latitudeText, "纬度");
BigDecimal longitudeValue = parseCoordinateValue(longitudeText, "经度");
if (!isInRange(latitudeValue, -90, 90)) {
if (isInRange(latitudeValue, -180, 180) && isInRange(longitudeValue, -90, 90)) {
throw new BusinessException("FIRM_COORDINATE_INVALID", "纬度超出范围,请检查是否与经度填反");
}
throw new BusinessException("FIRM_COORDINATE_INVALID", "纬度范围应在 -90 到 90 之间");
}
if (!isInRange(longitudeValue, -180, 180)) {
throw new BusinessException("FIRM_COORDINATE_INVALID", "经度范围应在 -180 到 180 之间");
}
return new CoordinateValue(latitudeValue, longitudeValue);
}
private String normalizeCoordinate(String value) {
return value == null ? "" : value.trim();
}
private BigDecimal parseCoordinateValue(String value, String fieldLabel) {
try {
return new BigDecimal(value);
} catch (NumberFormatException exception) {
throw new BusinessException("FIRM_COORDINATE_INVALID", fieldLabel + "必须是数字");
}
}
private boolean isInRange(BigDecimal value, int min, int max) {
return value.compareTo(BigDecimal.valueOf(min)) >= 0 && value.compareTo(BigDecimal.valueOf(max)) <= 0;
}
private String resolveAssetUrl(Long assetId) {
@@ -270,6 +312,9 @@ public class TenantOrgService {
) {
}
private record CoordinateValue(BigDecimal latitude, BigDecimal longitude) {
}
public record PracticeAreaView(Long id, String areaCode, String areaName, Integer displayOrder, String areaStatus) {
}