208 lines
5.4 KiB
TypeScript
208 lines
5.4 KiB
TypeScript
import { makeAutoObservable, runInAction } from "mobx";
|
||
import {
|
||
authInstance,
|
||
languageInstance,
|
||
languageStore,
|
||
isMediaIdEmpty,
|
||
} from "@shared";
|
||
|
||
export type Route = {
|
||
route_name: string;
|
||
carrier: string;
|
||
carrier_id: number;
|
||
center_latitude: number;
|
||
center_longitude: number;
|
||
governor_appeal: number;
|
||
id: number;
|
||
icon: string;
|
||
path: number[][];
|
||
rotate: number;
|
||
route_direction: boolean;
|
||
route_number: string;
|
||
route_sys_number: string;
|
||
scale_max: number;
|
||
scale_min: number;
|
||
video_preview: string;
|
||
};
|
||
|
||
class RouteStore {
|
||
routes: {
|
||
data: Route[];
|
||
loaded: boolean;
|
||
} = {
|
||
data: [],
|
||
loaded: false,
|
||
};
|
||
|
||
route: Record<string, Route> = {};
|
||
|
||
constructor() {
|
||
makeAutoObservable(this);
|
||
}
|
||
|
||
getRoutes = async () => {
|
||
if (this.routes.loaded) return;
|
||
const response = await authInstance.get("/route");
|
||
|
||
runInAction(() => {
|
||
this.routes = {
|
||
data: response.data,
|
||
loaded: true,
|
||
};
|
||
});
|
||
};
|
||
|
||
createRoute = async (route: any) => {
|
||
const response = await authInstance.post("/route", route);
|
||
const id = response.data.id;
|
||
|
||
runInAction(() => {
|
||
this.route[id] = { ...route, id };
|
||
this.routes.data = [...this.routes.data, { ...route, id }];
|
||
});
|
||
};
|
||
|
||
deleteRoute = async (id: number) => {
|
||
await authInstance.delete(`/route/${id}`);
|
||
|
||
runInAction(() => {
|
||
this.routes = {
|
||
data: this.routes.data.filter((route) => route.id !== id),
|
||
loaded: true,
|
||
};
|
||
});
|
||
};
|
||
|
||
routeStations: Record<string, any[]> = {};
|
||
|
||
getRoute = async (id: number) => {
|
||
if (this.route[id]) return this.route[id];
|
||
const response = await authInstance.get(`/route/${id}`);
|
||
const stations = await authInstance.get(`/route/${id}/station`);
|
||
|
||
runInAction(() => {
|
||
this.route[id] = response.data;
|
||
this.routeStations[id] = stations.data;
|
||
});
|
||
|
||
return response.data;
|
||
};
|
||
|
||
setRouteStations = (routeId: number, stationId: number, data: any) => {
|
||
this.routeStations[routeId] = this.routeStations[routeId]?.map((station) =>
|
||
station.id === stationId ? { ...station, ...data } : station
|
||
);
|
||
};
|
||
|
||
saveRouteStations = async (routeId: number, stationId: number) => {
|
||
const { language } = languageStore;
|
||
|
||
// Получаем актуальные данные станции с сервера
|
||
const stationResponse = await languageInstance(language).get(
|
||
`/station/${stationId}`
|
||
);
|
||
const fullStationData = stationResponse.data;
|
||
|
||
// Получаем отредактированные данные из локального кеша
|
||
const editedStationData = this.routeStations[routeId]?.find(
|
||
(station) => station.id === stationId
|
||
);
|
||
|
||
// Формируем данные для отправки: все поля станции + отредактированные offset
|
||
const dataToSend: any = {
|
||
station_id: stationId,
|
||
offset_x: editedStationData?.offset_x ?? fullStationData.offset_x ?? 0,
|
||
offset_y: editedStationData?.offset_y ?? fullStationData.offset_y ?? 0,
|
||
align: editedStationData?.align ?? fullStationData.align ?? 0,
|
||
transfers: fullStationData.transfers || {},
|
||
};
|
||
|
||
await authInstance.patch(`/route/${routeId}/station`, dataToSend);
|
||
|
||
// Обновляем локальный кеш после успешного сохранения
|
||
runInAction(() => {
|
||
if (this.routeStations[routeId]) {
|
||
this.routeStations[routeId] = this.routeStations[routeId].map(
|
||
(station) =>
|
||
station.id === stationId
|
||
? {
|
||
...station,
|
||
...dataToSend,
|
||
}
|
||
: station
|
||
);
|
||
}
|
||
});
|
||
};
|
||
|
||
editRouteData = {
|
||
route_name: "",
|
||
carrier: "",
|
||
carrier_id: 0,
|
||
center_latitude: "",
|
||
center_longitude: "",
|
||
governor_appeal: 0,
|
||
id: 0,
|
||
icon: "",
|
||
path: [] as number[][],
|
||
rotate: 0,
|
||
route_direction: false,
|
||
route_number: "",
|
||
route_sys_number: "",
|
||
scale_max: 0,
|
||
scale_min: 0,
|
||
video_preview: "" as string | undefined,
|
||
};
|
||
|
||
setEditRouteData = (data: any) => {
|
||
this.editRouteData = { ...this.editRouteData, ...data };
|
||
};
|
||
|
||
editRoute = async (id: number) => {
|
||
if (
|
||
!this.editRouteData.video_preview ||
|
||
isMediaIdEmpty(this.editRouteData.video_preview)
|
||
) {
|
||
delete this.editRouteData.video_preview;
|
||
}
|
||
if (!this.editRouteData.icon || isMediaIdEmpty(this.editRouteData.icon)) {
|
||
delete (this.editRouteData as any).icon;
|
||
}
|
||
const dataToSend: any = {
|
||
...this.editRouteData,
|
||
center_latitude: parseFloat(this.editRouteData.center_latitude),
|
||
center_longitude: parseFloat(this.editRouteData.center_longitude),
|
||
};
|
||
if (
|
||
this.editRouteData.governor_appeal === 0 ||
|
||
!this.editRouteData.governor_appeal
|
||
) {
|
||
dataToSend.governor_appeal = null;
|
||
}
|
||
const response = await authInstance.patch(`/route/${id}`, dataToSend);
|
||
|
||
runInAction(() => {
|
||
this.route[id] = response.data;
|
||
this.routes.data = this.routes.data.map((route) =>
|
||
route.id === id ? response.data : route
|
||
);
|
||
});
|
||
};
|
||
|
||
copyRouteAction = async (id: number) => {
|
||
const response = await authInstance.post(`/route/${id}/copy`);
|
||
|
||
runInAction(() => {
|
||
this.routes.data = [...this.routes.data, response.data];
|
||
});
|
||
};
|
||
|
||
selectedStationId = 0;
|
||
|
||
setSelectedStationId = (id: number) => {
|
||
this.selectedStationId = id;
|
||
};
|
||
}
|
||
|
||
export const routeStore = new RouteStore();
|