635 lines
16 KiB
TypeScript
635 lines
16 KiB
TypeScript
import { authInstance, languageInstance, languageStore } from "@shared";
|
||
import { makeAutoObservable, runInAction } from "mobx";
|
||
import { routeStore } from "../RouteStore";
|
||
|
||
type Language = "ru" | "en" | "zh";
|
||
|
||
type StationLanguageData = {
|
||
name: string;
|
||
system_name: string;
|
||
address: string;
|
||
loaded: boolean;
|
||
};
|
||
|
||
type StationCommonData = {
|
||
city_id: number;
|
||
description: string;
|
||
icon: string;
|
||
latitude: number;
|
||
longitude: number;
|
||
offset_x: number;
|
||
offset_y: number;
|
||
transfers: {
|
||
bus: string;
|
||
metro_blue: string;
|
||
metro_green: string;
|
||
metro_orange: string;
|
||
metro_purple: string;
|
||
metro_red: string;
|
||
train: string;
|
||
tram: string;
|
||
trolleybus: string;
|
||
};
|
||
city: string;
|
||
};
|
||
|
||
type EditStationData = {
|
||
[key in Language]: StationLanguageData;
|
||
} & { common: StationCommonData };
|
||
|
||
type Station = {
|
||
id: number;
|
||
address: string;
|
||
city: string;
|
||
city_id: number;
|
||
description: string;
|
||
icon: string;
|
||
latitude: number;
|
||
longitude: number;
|
||
name: string;
|
||
offset_x: number;
|
||
offset_y: number;
|
||
system_name: string;
|
||
transfers: {
|
||
bus: string;
|
||
metro_blue: string;
|
||
metro_green: string;
|
||
metro_orange: string;
|
||
metro_purple: string;
|
||
metro_red: string;
|
||
train: string;
|
||
tram: string;
|
||
trolleybus: string;
|
||
};
|
||
};
|
||
|
||
type CreateStationData = {
|
||
[key in Language]: StationLanguageData;
|
||
} & { common: StationCommonData };
|
||
|
||
class StationsStore {
|
||
stations: Station[] = [];
|
||
station: Station | null = null;
|
||
|
||
stationLists: {
|
||
[key in Language]: {
|
||
data: Station[];
|
||
loaded: boolean;
|
||
};
|
||
} = {
|
||
ru: {
|
||
data: [],
|
||
loaded: false,
|
||
},
|
||
en: {
|
||
data: [],
|
||
loaded: false,
|
||
},
|
||
zh: {
|
||
data: [],
|
||
loaded: false,
|
||
},
|
||
};
|
||
|
||
stationPreview: Record<
|
||
string,
|
||
Record<string, { loaded: boolean; data: Station }>
|
||
> = {};
|
||
|
||
editStationData: EditStationData = {
|
||
ru: {
|
||
name: "",
|
||
system_name: "",
|
||
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
en: {
|
||
name: "",
|
||
system_name: "",
|
||
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
zh: {
|
||
name: "",
|
||
system_name: "",
|
||
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
common: {
|
||
city: "",
|
||
city_id: 0,
|
||
description: "",
|
||
icon: "",
|
||
latitude: 0,
|
||
longitude: 0,
|
||
offset_x: 0,
|
||
offset_y: 0,
|
||
transfers: {
|
||
bus: "",
|
||
metro_blue: "",
|
||
metro_green: "",
|
||
metro_orange: "",
|
||
metro_purple: "",
|
||
metro_red: "",
|
||
train: "",
|
||
tram: "",
|
||
trolleybus: "",
|
||
},
|
||
},
|
||
};
|
||
|
||
createStationData: CreateStationData = {
|
||
ru: {
|
||
name: "",
|
||
system_name: "",
|
||
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
en: {
|
||
name: "",
|
||
system_name: "",
|
||
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
zh: {
|
||
name: "",
|
||
system_name: "",
|
||
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
common: {
|
||
city: "",
|
||
city_id: 0,
|
||
description: "",
|
||
icon: "",
|
||
latitude: 0,
|
||
longitude: 0,
|
||
offset_x: 0,
|
||
offset_y: 0,
|
||
transfers: {
|
||
bus: "",
|
||
metro_blue: "",
|
||
metro_green: "",
|
||
metro_orange: "",
|
||
metro_purple: "",
|
||
metro_red: "",
|
||
train: "",
|
||
tram: "",
|
||
trolleybus: "",
|
||
},
|
||
},
|
||
};
|
||
|
||
constructor() {
|
||
makeAutoObservable(this);
|
||
}
|
||
|
||
getStations = async () => {
|
||
const response = await authInstance.get("/station");
|
||
|
||
runInAction(() => {
|
||
this.stations = response.data;
|
||
});
|
||
};
|
||
|
||
getStationList = async () => {
|
||
const { language } = languageStore;
|
||
if (this.stationLists[language].loaded) {
|
||
return;
|
||
}
|
||
const response = await authInstance.get("/station");
|
||
|
||
runInAction(() => {
|
||
this.stationLists[language].data = response.data;
|
||
this.stationLists[language].loaded = true;
|
||
});
|
||
};
|
||
|
||
setEditCommonData = (data: Partial<StationCommonData>) => {
|
||
this.editStationData.common = {
|
||
...this.editStationData.common,
|
||
...data,
|
||
};
|
||
};
|
||
|
||
getEditStation = async (id: number) => {
|
||
const ruResponse = await languageInstance("ru").get(`/station/${id}`);
|
||
const enResponse = await languageInstance("en").get(`/station/${id}`);
|
||
const zhResponse = await languageInstance("zh").get(`/station/${id}`);
|
||
|
||
this.editStationData = {
|
||
ru: {
|
||
name: ruResponse.data.name,
|
||
system_name: ruResponse.data.system_name,
|
||
|
||
address: ruResponse.data.address,
|
||
loaded: true,
|
||
},
|
||
en: {
|
||
name: enResponse.data.name,
|
||
system_name: enResponse.data.system_name,
|
||
|
||
address: enResponse.data.address,
|
||
loaded: true,
|
||
},
|
||
zh: {
|
||
name: zhResponse.data.name,
|
||
system_name: zhResponse.data.system_name,
|
||
|
||
address: zhResponse.data.address,
|
||
loaded: true,
|
||
},
|
||
common: {
|
||
city: ruResponse.data.city,
|
||
city_id: ruResponse.data.city_id,
|
||
description: ruResponse.data.description,
|
||
icon: ruResponse.data.icon,
|
||
latitude: ruResponse.data.latitude,
|
||
longitude: ruResponse.data.longitude,
|
||
offset_x: ruResponse.data.offset_x,
|
||
offset_y: ruResponse.data.offset_y,
|
||
transfers: ruResponse.data.transfers,
|
||
},
|
||
};
|
||
};
|
||
|
||
setLanguageEditStationData = (
|
||
language: Language,
|
||
data: Partial<StationLanguageData>
|
||
) => {
|
||
this.editStationData[language] = {
|
||
...this.editStationData[language],
|
||
...data,
|
||
};
|
||
};
|
||
|
||
editStation = async (id: number) => {
|
||
const commonDataPayload = {
|
||
city_id: this.editStationData.common.city_id,
|
||
icon: this.editStationData.common.icon,
|
||
latitude: this.editStationData.common.latitude,
|
||
longitude: this.editStationData.common.longitude,
|
||
offset_x: this.editStationData.common.offset_x,
|
||
offset_y: this.editStationData.common.offset_y,
|
||
transfers: this.editStationData.common.transfers,
|
||
city: this.editStationData.common.city,
|
||
};
|
||
|
||
for (const language of ["ru", "en", "zh"] as const) {
|
||
const { name, address } = this.editStationData[language];
|
||
const description = this.editStationData.common.description;
|
||
const response = await languageInstance(language).patch(
|
||
`/station/${id}`,
|
||
{
|
||
name: (name || "").trim(),
|
||
system_name: (name || "").trim(),
|
||
description: (description || "").trim(),
|
||
address: (address || "").trim(),
|
||
...commonDataPayload,
|
||
}
|
||
);
|
||
|
||
runInAction(() => {
|
||
if (this.stationPreview[id]) {
|
||
this.stationPreview[id][language] = {
|
||
loaded: true,
|
||
data: {
|
||
...this.stationPreview[id][language].data,
|
||
id: response.data.id,
|
||
name: response.data.name,
|
||
system_name: response.data.system_name,
|
||
description: response.data.description,
|
||
address: response.data.address,
|
||
...commonDataPayload,
|
||
} as Station,
|
||
};
|
||
}
|
||
if (this.stationLists[language].data) {
|
||
this.stationLists[language].data = this.stationLists[
|
||
language
|
||
].data.map((station: Station) =>
|
||
station.id === id
|
||
? ({
|
||
...station,
|
||
name: response.data.name,
|
||
system_name: response.data.system_name,
|
||
description: description || "",
|
||
address: response.data.address,
|
||
...commonDataPayload,
|
||
} as Station)
|
||
: station
|
||
);
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
deleteStation = async (id: number) => {
|
||
await authInstance.delete(`/station/${id}`);
|
||
|
||
runInAction(() => {
|
||
this.stations = this.stations.filter((station) => station.id !== id);
|
||
|
||
if (this.stationPreview[id]) {
|
||
delete this.stationPreview[id];
|
||
}
|
||
|
||
for (const lang of ["ru", "en", "zh"] as const) {
|
||
if (this.stationLists[lang].data) {
|
||
this.stationLists[lang].data = this.stationLists[lang].data.filter(
|
||
(station) => station.id !== id
|
||
);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
getStation = async (id: number) => {
|
||
const response = await authInstance.get(`/station/${id}`);
|
||
this.station = response.data;
|
||
};
|
||
|
||
getStationPreview = async (id: number) => {
|
||
const { language } = languageStore;
|
||
|
||
if (this.stationPreview[id]?.[language]?.loaded) {
|
||
return;
|
||
}
|
||
|
||
const response = await languageInstance(language).get(`/station/${id}`);
|
||
runInAction(() => {
|
||
if (!this.stationPreview[id]) {
|
||
this.stationPreview[id] = {
|
||
ru: { loaded: false, data: {} as Station },
|
||
en: { loaded: false, data: {} as Station },
|
||
zh: { loaded: false, data: {} as Station },
|
||
};
|
||
}
|
||
this.stationPreview[id][language] = {
|
||
loaded: true,
|
||
data: response.data as Station,
|
||
};
|
||
});
|
||
};
|
||
|
||
setCreateCommonData = (data: Partial<StationCommonData>) => {
|
||
this.createStationData.common = {
|
||
...this.createStationData.common,
|
||
...data,
|
||
};
|
||
};
|
||
|
||
setLanguageCreateStationData = (
|
||
language: Language,
|
||
data: Partial<StationLanguageData>
|
||
) => {
|
||
this.createStationData[language] = {
|
||
...this.createStationData[language],
|
||
...data,
|
||
};
|
||
};
|
||
|
||
createStation = async () => {
|
||
const { language } = languageStore;
|
||
let commonDataPayload: Partial<StationCommonData> = {
|
||
city_id: this.createStationData.common.city_id,
|
||
icon: this.createStationData.common.icon,
|
||
latitude: this.createStationData.common.latitude,
|
||
longitude: this.createStationData.common.longitude,
|
||
offset_x: this.createStationData.common.offset_x,
|
||
offset_y: this.createStationData.common.offset_y,
|
||
transfers: this.createStationData.common.transfers,
|
||
city: this.createStationData.common.city,
|
||
};
|
||
|
||
if (this.createStationData.common.icon === "") {
|
||
delete commonDataPayload.icon;
|
||
}
|
||
|
||
const { name, address } = this.createStationData[language];
|
||
const description = this.createStationData.common.description;
|
||
const response = await languageInstance(language).post("/station", {
|
||
name: (name || "").trim(),
|
||
system_name: (name || "").trim(),
|
||
description: (description || "").trim(),
|
||
address: (address || "").trim(),
|
||
...commonDataPayload,
|
||
});
|
||
|
||
runInAction(() => {
|
||
this.stationLists[language].data.push(response.data);
|
||
});
|
||
|
||
const stationId = response.data.id;
|
||
|
||
for (const lang of ["ru", "en", "zh"].filter(
|
||
(lang) => lang !== language
|
||
) as Language[]) {
|
||
const { name, address } = this.createStationData[lang];
|
||
const description = this.createStationData.common.description;
|
||
const response = await languageInstance(lang).patch(
|
||
`/station/${stationId}`,
|
||
{
|
||
name: (name || "").trim(),
|
||
system_name: (name || "").trim(),
|
||
description: (description || "").trim(),
|
||
address: (address || "").trim(),
|
||
...commonDataPayload,
|
||
}
|
||
);
|
||
|
||
runInAction(() => {
|
||
this.stationLists[lang].data.push(response.data);
|
||
});
|
||
}
|
||
|
||
runInAction(() => {
|
||
this.createStationData = {
|
||
ru: {
|
||
name: "",
|
||
system_name: "",
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
en: {
|
||
name: "",
|
||
system_name: "",
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
zh: {
|
||
name: "",
|
||
system_name: "",
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
common: {
|
||
city: "",
|
||
city_id: 0,
|
||
icon: "",
|
||
latitude: 0,
|
||
description: "",
|
||
longitude: 0,
|
||
offset_x: 0,
|
||
offset_y: 0,
|
||
transfers: {
|
||
bus: "",
|
||
metro_blue: "",
|
||
metro_green: "",
|
||
metro_orange: "",
|
||
metro_purple: "",
|
||
metro_red: "",
|
||
train: "",
|
||
tram: "",
|
||
trolleybus: "",
|
||
},
|
||
},
|
||
};
|
||
});
|
||
return response.data;
|
||
};
|
||
|
||
resetEditStationData = () => {
|
||
this.editStationData = {
|
||
ru: {
|
||
name: "",
|
||
system_name: "",
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
en: {
|
||
name: "",
|
||
system_name: "",
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
zh: {
|
||
name: "",
|
||
system_name: "",
|
||
address: "",
|
||
loaded: false,
|
||
},
|
||
common: {
|
||
city: "",
|
||
city_id: 0,
|
||
description: "",
|
||
icon: "",
|
||
latitude: 0,
|
||
longitude: 0,
|
||
offset_x: 0,
|
||
offset_y: 0,
|
||
transfers: {
|
||
bus: "",
|
||
metro_blue: "",
|
||
metro_green: "",
|
||
metro_orange: "",
|
||
metro_purple: "",
|
||
metro_red: "",
|
||
train: "",
|
||
tram: "",
|
||
trolleybus: "",
|
||
},
|
||
},
|
||
};
|
||
};
|
||
|
||
updateStationTransfers = async (
|
||
id: number,
|
||
transfers: {
|
||
bus: string;
|
||
metro_blue: string;
|
||
metro_green: string;
|
||
metro_orange: string;
|
||
metro_purple: string;
|
||
metro_red: string;
|
||
train: string;
|
||
tram: string;
|
||
trolleybus: string;
|
||
}
|
||
) => {
|
||
const { language } = languageStore;
|
||
|
||
const response = await languageInstance(language).get(`/station/${id}`);
|
||
const stationData = response.data as Station;
|
||
|
||
if (!stationData) {
|
||
throw new Error("Station not found");
|
||
}
|
||
|
||
// Формируем commonDataPayload как в editStation, с обновленными transfers
|
||
const commonDataPayload = {
|
||
city_id: stationData.city_id,
|
||
latitude: stationData.latitude,
|
||
longitude: stationData.longitude,
|
||
offset_x: stationData.offset_x,
|
||
offset_y: stationData.offset_y,
|
||
transfers: transfers,
|
||
city: stationData.city || "",
|
||
};
|
||
|
||
// Отправляем один PATCH запрос, так как пересадки общие для всех языков
|
||
const patchResponse = await languageInstance(language).patch(
|
||
`/station/${id}`,
|
||
{
|
||
name: stationData.name || "",
|
||
system_name: stationData.system_name || "",
|
||
description: stationData.description || "",
|
||
address: stationData.address || "",
|
||
...commonDataPayload,
|
||
}
|
||
);
|
||
|
||
// Обновляем данные для всех языков в локальном состоянии
|
||
runInAction(() => {
|
||
const updatedTransfers = patchResponse.data.transfers;
|
||
|
||
for (const lang of ["ru", "en", "zh"] as const) {
|
||
if (this.stationPreview[id]) {
|
||
this.stationPreview[id][lang] = {
|
||
...this.stationPreview[id][lang],
|
||
data: {
|
||
...this.stationPreview[id][lang].data,
|
||
transfers: updatedTransfers,
|
||
},
|
||
};
|
||
}
|
||
if (this.stationLists[lang].data) {
|
||
this.stationLists[lang].data = this.stationLists[lang].data.map(
|
||
(station: Station) =>
|
||
station.id === id
|
||
? {
|
||
...station,
|
||
transfers: updatedTransfers,
|
||
}
|
||
: station
|
||
);
|
||
}
|
||
}
|
||
|
||
// Обновляем пересадки в RouteStore.routeStations для всех маршрутов
|
||
if (routeStore?.routeStations) {
|
||
for (const routeId in routeStore.routeStations) {
|
||
routeStore.routeStations[routeId] = routeStore.routeStations[
|
||
routeId
|
||
].map((station: any) =>
|
||
station.id === id
|
||
? {
|
||
...station,
|
||
transfers: updatedTransfers,
|
||
}
|
||
: station
|
||
);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
}
|
||
|
||
export const stationsStore = new StationsStore();
|