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

@@ -8,8 +8,8 @@ interface OpenFirmResponse {
intro: string;
hotlinePhone: string;
hqAddress: string;
hqLatitude: number;
hqLongitude: number;
hqLatitude: number | string | null;
hqLongitude: number | string | null;
officeCount: number;
lawyerCount: number;
officeList: string[];
@@ -42,11 +42,62 @@ interface OpenCardDetailResponse {
specialties: string[];
firmName: string;
firmAddress: string;
firmLatitude: number;
firmLongitude: number;
firmLatitude: number | string | null;
firmLongitude: number | string | null;
}
function parseCoordinate(value: number | string | null | undefined): number | null {
if (typeof value === 'number') {
return Number.isFinite(value) ? value : null;
}
if (typeof value !== 'string') {
return null;
}
const normalized = value.trim();
if (!normalized) {
return null;
}
const parsed = Number(normalized);
return Number.isFinite(parsed) ? parsed : null;
}
function isLatitude(value: number | null): value is number {
return value !== null && value >= -90 && value <= 90;
}
function isLongitude(value: number | null): value is number {
return value !== null && value >= -180 && value <= 180;
}
function normalizeCoordinates(latitude: number | string | null | undefined, longitude: number | string | null | undefined): {
latitude: number;
longitude: number;
} {
const parsedLatitude = parseCoordinate(latitude);
const parsedLongitude = parseCoordinate(longitude);
if (isLatitude(parsedLatitude) && isLongitude(parsedLongitude)) {
return {
latitude: parsedLatitude,
longitude: parsedLongitude,
};
}
if (isLatitude(parsedLongitude) && isLongitude(parsedLatitude)) {
return {
latitude: parsedLongitude,
longitude: parsedLatitude,
};
}
return {
latitude: 0,
longitude: 0,
};
}
function toFirmInfo(payload: OpenFirmResponse): FirmInfo {
const coordinates = normalizeCoordinates(payload.hqLatitude, payload.hqLongitude);
return {
id: payload.name || 'firm',
name: payload.name || '',
@@ -54,8 +105,8 @@ function toFirmInfo(payload: OpenFirmResponse): FirmInfo {
intro: payload.intro || '',
hotlinePhone: payload.hotlinePhone || '',
hqAddress: payload.hqAddress || '',
hqLatitude: payload.hqLatitude || 0,
hqLongitude: payload.hqLongitude || 0,
hqLatitude: coordinates.latitude,
hqLongitude: coordinates.longitude,
officeCount: payload.officeCount || 0,
lawyerCount: payload.lawyerCount || 0,
heroImage: payload.heroImage || '',
@@ -114,6 +165,7 @@ export async function getLawyerDetail(cardId: string, sourceType = 'DIRECT', sha
const payload = await request<OpenCardDetailResponse>({
url: `/api/open/cards/${encodeURIComponent(cardId)}?${queryParts.join('&')}`,
});
const coordinates = normalizeCoordinates(payload.firmLatitude, payload.firmLongitude);
return {
firm: {
@@ -123,8 +175,8 @@ export async function getLawyerDetail(cardId: string, sourceType = 'DIRECT', sha
intro: '',
hotlinePhone: '',
hqAddress: payload.firmAddress || '',
hqLatitude: payload.firmLatitude || 0,
hqLongitude: payload.firmLongitude || 0,
hqLatitude: coordinates.latitude,
hqLongitude: coordinates.longitude,
officeCount: 0,
lawyerCount: 0,
heroImage: '',