2D-карта (станции, заявки) и вкладка «Заявки»
Новая вкладка «Заявки»: показ заявок за интервал на 2D-карте, создание заявки рисованием полигона на карте с формой параметров (Оптика/РСА) и удаление выбранной заявки (createRequest/deleteRequest, RequestCreatePanel/RequestDetailsPanel, polygonToWkt). В Tgu2DMapView добавлен изолированный режим рисования полигона. 2D-карта: панели информации о станции и о заявках, слой станций (stationsApi), поддержка выбора объектов через спатиальный индекс. Список слоёв упрощён — трасса/полоса/маркеры КА убраны из переключателя, по умолчанию включены работы плана, станции и заявки.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { RequestFilter, RequestMapItem } from "../model/requestTypes";
|
||||
import type { CreateRequestPayload, CreateRequestResult, RequestFilter, RequestMapItem } from "../model/requestTypes";
|
||||
|
||||
const BASE = "/api/pcp-request/v1";
|
||||
const PAGE_SIZE = 500;
|
||||
@@ -60,3 +60,43 @@ export async function fetchRequestsForMap(
|
||||
truncated: first.totalPages > MAX_PAGES
|
||||
};
|
||||
}
|
||||
|
||||
type ErrorDetail = { field?: string; message?: string };
|
||||
type ErrorBody = { code?: string; message?: string; details?: ErrorDetail[] };
|
||||
|
||||
async function readErrorMessage(response: Response, fallback: string): Promise<string> {
|
||||
try {
|
||||
const body = (await response.json()) as ErrorBody;
|
||||
const details = body.details?.map((d) => (d.field ? `${d.field}: ${d.message}` : d.message)).filter(Boolean);
|
||||
const detailText = details && details.length > 0 ? ` (${details.join("; ")})` : "";
|
||||
if (body.message) return `${body.message}${detailText}`;
|
||||
} catch {
|
||||
// тело ответа не JSON — используем fallback
|
||||
}
|
||||
return `${fallback}: ${response.status}`;
|
||||
}
|
||||
|
||||
export async function createRequest(payload: CreateRequestPayload): Promise<CreateRequestResult> {
|
||||
const response = await fetch(`${BASE}/requests`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(await readErrorMessage(response, "Не удалось создать заявку"));
|
||||
}
|
||||
|
||||
return response.json() as Promise<CreateRequestResult>;
|
||||
}
|
||||
|
||||
export async function deleteRequest(id: string): Promise<void> {
|
||||
const response = await fetch(`${BASE}/requests/${encodeURIComponent(id)}`, {
|
||||
method: "DELETE",
|
||||
headers: { Accept: "application/json" }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(await readErrorMessage(response, "Не удалось удалить заявку"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
export type StationDto = {
|
||||
id: string | null;
|
||||
number: number;
|
||||
name: string;
|
||||
position: { lat: number; long: number; height: number };
|
||||
elevationMin: number;
|
||||
elevationMax: number;
|
||||
};
|
||||
|
||||
export async function fetchStations(): Promise<StationDto[]> {
|
||||
const response = await fetch("/api/stations", {
|
||||
headers: { Accept: "application/json" }
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`Ошибка загрузки станций: ${response.status}`);
|
||||
}
|
||||
return response.json() as Promise<StationDto[]>;
|
||||
}
|
||||
Reference in New Issue
Block a user