diff --git a/backend/easycard-module-org/src/main/java/com/easycard/module/org/service/TenantOrgService.java b/backend/easycard-module-org/src/main/java/com/easycard/module/org/service/TenantOrgService.java index 9ff6358..4840f56 100644 --- a/backend/easycard-module-org/src/main/java/com/easycard/module/org/service/TenantOrgService.java +++ b/backend/easycard-module-org/src/main/java/com/easycard/module/org/service/TenantOrgService.java @@ -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) { } diff --git a/frontend_admin/src/views/tenant/FirmProfileView.vue b/frontend_admin/src/views/tenant/FirmProfileView.vue index 22f4884..ed87a26 100644 --- a/frontend_admin/src/views/tenant/FirmProfileView.vue +++ b/frontend_admin/src/views/tenant/FirmProfileView.vue @@ -1,5 +1,6 @@