import { createApiClient } from "../lib/apiClient"; import { authorizedPostBlobDownload, authorizedPostMultipartJson } from "../lib/batchFileHttp"; import { normalizeLocationFromApi, type LocationCreateInput, type LocationDto, type LocationGetListInput, type LocationUpdateInput, type PagedResultDto, } from "../types/location"; const api = createApiClient({ // 如果项目后续接入登录,可在这里加 token 获取逻辑 getToken: () => { try { return localStorage.getItem("access_token") ?? localStorage.getItem("token") ?? null; } catch { return null; } }, }); /** * ABP Conventional Controller 默认路由通常为: * - GET /api/app/location * - POST /api/app/location * 这里按该约定实现;如果后端实际路由不同,以 Swagger 为准调整 path。 */ function trimOrNullHours(v: string | null | undefined): string | null { const t = (v ?? "").trim(); return t ? t : null; } export async function getLocations(input: LocationGetListInput, signal?: AbortSignal): Promise> { const raw = await api.requestJson & { items?: unknown[]; Items?: unknown[] }>({ path: "/location", method: "GET", query: { SkipCount: input.skipCount, MaxResultCount: input.maxResultCount, Sorting: input.sorting, Keyword: input.keyword, Partner: input.partner, GroupName: input.groupName, State: input.state, }, signal, }); const itemsRaw = raw.items ?? raw.Items ?? []; const items = (Array.isArray(itemsRaw) ? itemsRaw : []).map((x) => normalizeLocationFromApi(x)); return { ...raw, items, totalCount: raw.totalCount ?? (raw as { TotalCount?: number }).TotalCount ?? items.length }; } export async function createLocation(input: LocationCreateInput): Promise { const raw = await api.requestJson({ path: "/location", method: "POST", body: { partner: input.partner, groupName: input.groupName, locationCode: input.locationCode, locationName: input.locationName, street: input.street, city: input.city, stateCode: input.stateCode, country: input.country, zipCode: input.zipCode, phone: input.phone, email: input.email, latitude: input.latitude, longitude: input.longitude, state: input.state ?? true, operatingHours: trimOrNullHours(input.operatingHours ?? undefined), }, }); return normalizeLocationFromApi(raw); } /** * ABP Conventional Controller 的 UpdateAsync 常见路由为: * - PUT /api/app/location/{id} * 以 Swagger 为准;若后端使用其它形式(如 /location?id=xxx),在此调整即可。 */ export async function updateLocation(id: string, input: LocationUpdateInput): Promise { const raw = await api.requestJson({ path: `/location/${encodeURIComponent(id)}`, method: "PUT", body: { partner: input.partner, groupName: input.groupName, locationCode: input.locationCode, locationName: input.locationName, street: input.street, city: input.city, stateCode: input.stateCode, country: input.country, zipCode: input.zipCode, phone: input.phone, email: input.email, latitude: input.latitude, longitude: input.longitude, state: input.state ?? true, operatingHours: trimOrNullHours(input.operatingHours ?? undefined), }, }); return normalizeLocationFromApi(raw); } /** * ABP Conventional Controller 的 DeleteAsync 常见路由为: * - DELETE /api/app/location/{id} * 以 Swagger 为准;若后端路由不同,在此调整 path。 */ export async function deleteLocation(id: string): Promise { await api.requestJson({ path: `/location/${encodeURIComponent(id)}`, method: "DELETE", }); } /** 与列表筛选一致,用于模板下载外的 Excel 全量导出(不含分页)。 */ export type LocationExportQueryInput = { sorting?: string; keyword?: string; partner?: string; groupName?: string; state?: boolean; }; export type LocationBatchImportResultDto = { successCount: number; failCount: number; skippedEmptyRows?: number; errors?: Array<{ rowNumber?: number; locationCode?: string; message?: string; }>; }; export type LocationBulkUpdateItemVo = { id: string; partner?: string | null; groupName?: string | null; locationName: string; street?: string | null; city?: string | null; stateCode?: string | null; country?: string | null; zipCode?: string | null; phone?: string | null; email?: string | null; latitude?: number | null; longitude?: number | null; state?: boolean; }; export type LocationBulkUpdateResultDto = { successCount: number; failCount: number; errors?: Array<{ rowNumber?: number; id?: string; message?: string }>; }; export async function downloadLocationImportTemplate(signal?: AbortSignal): Promise { await authorizedPostBlobDownload({ path: "/location/download-location-import-template", defaultFileName: "Location-Manager-template.xlsx", signal, }); } export async function exportLocationsExcel(input: LocationExportQueryInput, signal?: AbortSignal): Promise { await authorizedPostBlobDownload({ path: "/location/export-locations-excel", query: { Sorting: input.sorting, Keyword: input.keyword, Partner: input.partner, GroupName: input.groupName, State: input.state, }, defaultFileName: "locations-export.xlsx", signal, }); } export async function importLocationsBatch(file: File, signal?: AbortSignal): Promise { return authorizedPostMultipartJson({ path: "/location/import-locations-batch", fieldName: "file", file, signal, }); } export async function updateLocationsBulk( body: { items: LocationBulkUpdateItemVo[] }, ): Promise { // ABP:`UpdateLocationsBulkAsync` → `locations-bulk`(勿写 `update-locations-bulk`) return api.requestJson({ path: "/location/locations-bulk", method: "PUT", body, }); }