Files
EasyCard/frontend_miniprogram/miniprogram/api/open.ts
陈子默 9605384edc feat: 搭建微信小程序展示端
- 初始化小程序工程配置与类型声明

- 增加首页、律所、律师列表、详情与历史页面

- 补充公共组件、运行时配置与示例素材
2026-03-20 12:44:31 +08:00

148 lines
3.9 KiB
TypeScript

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;
hqLongitude: number;
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;
firmLongitude: number;
}
function toFirmInfo(payload: OpenFirmResponse): FirmInfo {
return {
id: payload.name || 'firm',
name: payload.name || '',
logo: payload.logo || '',
intro: payload.intro || '',
hotlinePhone: payload.hotlinePhone || '',
hqAddress: payload.hqAddress || '',
hqLatitude: payload.hqLatitude || 0,
hqLongitude: payload.hqLongitude || 0,
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<FirmInfo> {
const payload = await request<OpenFirmResponse>({
url: '/api/open/firm/profile',
});
return toFirmInfo(payload);
}
export async function listLawyers(params: {
keyword?: string;
office?: string;
practiceArea?: string;
}): Promise<Lawyer[]> {
const query = Object.entries(params)
.filter(([, value]) => Boolean(value))
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value as string)}`)
.join('&');
const payload = await request<OpenCardListItem[]>({
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<OpenCardDetailResponse>({
url: `/api/open/cards/${encodeURIComponent(cardId)}?${queryParts.join('&')}`,
});
return {
firm: {
id: payload.firmName || 'firm',
name: payload.firmName || '',
logo: '',
intro: '',
hotlinePhone: '',
hqAddress: payload.firmAddress || '',
hqLatitude: payload.firmLatitude || 0,
hqLongitude: payload.firmLongitude || 0,
officeCount: 0,
lawyerCount: 0,
heroImage: '',
officeList: [],
practiceAreas: [],
},
lawyer: toLawyer(payload),
};
}
export async function recordCardShare(cardId: string, sharePath: string): Promise<void> {
await request<void>({
url: `/api/open/cards/${encodeURIComponent(cardId)}/share`,
method: 'POST',
data: {
shareChannel: 'WECHAT_FRIEND',
sharePath,
},
});
}