import type { FirmInfo, Lawyer } from '../types/card'; import { request } from '../utils/http'; interface OpenFirmResponse { name: string; logo: string; heroImage: string; intro: string; hotlinePhone: string; hqAddress: string; hqLatitude: number | string | null; hqLongitude: number | string | null; officeCount: number; lawyerCount: number; officeList: string[]; practiceAreas: string[]; } interface OpenCardListItem { id: number; name: string; title: string; office: string; phone: string; email: string; avatar: string; specialties: string[]; } interface OpenCardDetailResponse { id: number; name: string; title: string; office: string; phone: string; email: string; address: string; avatar: string; coverImage: string; wechatQrImage: string; bio: string; specialties: string[]; firmName: string; firmAddress: string; 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 || '', logo: payload.logo || '', intro: payload.intro || '', hotlinePhone: payload.hotlinePhone || '', hqAddress: payload.hqAddress || '', hqLatitude: coordinates.latitude, hqLongitude: coordinates.longitude, officeCount: payload.officeCount || 0, lawyerCount: payload.lawyerCount || 0, heroImage: payload.heroImage || '', officeList: payload.officeList || [], practiceAreas: payload.practiceAreas || [], }; } function toLawyer(payload: OpenCardListItem | OpenCardDetailResponse): Lawyer { return { id: String(payload.id), name: payload.name || '', title: payload.title || '', office: payload.office || '', phone: payload.phone || '', email: payload.email || '', address: 'address' in payload ? payload.address || '' : '', avatar: payload.avatar || '', coverImage: 'coverImage' in payload ? payload.coverImage || '' : '', specialties: payload.specialties || [], bio: 'bio' in payload ? payload.bio || '' : '', wechatQrImage: 'wechatQrImage' in payload ? payload.wechatQrImage || '' : '', }; } export async function getFirmProfile(): Promise { const payload = await request({ url: '/api/open/firm/profile', }); return toFirmInfo(payload); } export async function listLawyers(params: { keyword?: string; office?: string; practiceArea?: string; }): Promise { const query = Object.entries(params) .filter(([, value]) => Boolean(value)) .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value as string)}`) .join('&'); const payload = await request({ url: `/api/open/cards${query ? `?${query}` : ''}`, }); return payload.map((item) => toLawyer(item)); } export async function getLawyerDetail(cardId: string, sourceType = 'DIRECT', shareFromCardId = ''): Promise<{ firm: FirmInfo; lawyer: Lawyer; }> { const queryParts = [`sourceType=${encodeURIComponent(sourceType)}`]; if (shareFromCardId) { queryParts.push(`shareFromCardId=${encodeURIComponent(shareFromCardId)}`); } const payload = await request({ url: `/api/open/cards/${encodeURIComponent(cardId)}?${queryParts.join('&')}`, }); const coordinates = normalizeCoordinates(payload.firmLatitude, payload.firmLongitude); return { firm: { id: payload.firmName || 'firm', name: payload.firmName || '', logo: '', intro: '', hotlinePhone: '', hqAddress: payload.firmAddress || '', hqLatitude: coordinates.latitude, hqLongitude: coordinates.longitude, officeCount: 0, lawyerCount: 0, heroImage: '', officeList: [], practiceAreas: [], }, lawyer: toLawyer(payload), }; } export async function recordCardShare(cardId: string, sharePath: string): Promise { await request({ url: `/api/open/cards/${encodeURIComponent(cardId)}/share`, method: 'POST', data: { shareChannel: 'WECHAT_FRIEND', sharePath, }, }); }