refactor: alle Services strukturiert und vereinheitlicht (v1.1.120) – Webservice/Database getrennt, Postfix 'Service' eingeführt

This commit is contained in:
ISA
2025-05-20 15:03:05 +02:00
parent 6f9a50ef5c
commit 4c94ba82ae
7 changed files with 72 additions and 95 deletions

View File

@@ -4,6 +4,36 @@ Alle bedeutenden Änderungen an diesem Projekt werden in dieser Datei dokumentie
--- ---
## [1.1.120] 2025-05-20
### Refactor
- 🔁 Alle Webservice- und Datenbank-Fetches vollständig auf strukturierte Service-Dateien umgestellt
- Einheitliches Schema für Servicenamen: `fetchXyzService.js`
- Webservice-Dateien erwarten keine Importe mehr, sondern holen `?m` und `?u` direkt aus der URL
### Struktur
- `/services/webservice/` → für TALAS WebServices (Port 80)
- z.B. `fetchGisSystemStaticService.js`, `fetchGisStationsMeasurementsService.js`
- `/services/database/` → für API-Fetches von Next.js (Port 3000)
- z.B. `fetchDeviceNameByIdService.js`, `updateLocationInDatabaseService.js`
- `/services/utils/` → z.B. `fetchWithTimeout.js`
### Cleanup
- ❌ Veraltete Hooks entfernt: `useFetchWebServiceMap`, `setGisSystemStaticLoaded`, etc.
- 🧼 Nicht verwendete Service-Imports aus `MapComponent.js` bereinigt
- ❌ Datei `PoiUtils.js` gelöscht (nicht verwendet)
### Motivation
- ✅ Klare Trennung zwischen Webservice- und DB-Logik
- 🧠 Bessere Lesbarkeit im Code durch Postfix `Service`
- 👨‍💻 Einfache Navigation & Wartbarkeit der Anwendung
---
## [1.1.117] 2025-05-20 ## [1.1.117] 2025-05-20
### Changed ### Changed

View File

@@ -37,7 +37,6 @@ import CoordinateModal from "../CoordinateModal.js";
import CoordinatePopup from "../CoordinatePopup.js"; import CoordinatePopup from "../CoordinatePopup.js";
//------------------------Daten aus API-------------------- //------------------------Daten aus API--------------------
import { fetchPoiDataService } from "../../services/database/fetchPoiDataService.js"; import { fetchPoiDataService } from "../../services/database/fetchPoiDataService.js";
import { fetchGisStationsMeasurementsService } from "../../services/webservice/fetchGisStationsMeasurementsService.js";
import { selectPolylineVisible, setPolylineVisible } from "../../redux/slices/polylineLayerVisibleSlice.js"; import { selectPolylineVisible, setPolylineVisible } from "../../redux/slices/polylineLayerVisibleSlice.js";
import { fetchLocationDevicesFromDB } from "../../redux/slices/db/locationDevicesFromDBSlice"; import { fetchLocationDevicesFromDB } from "../../redux/slices/db/locationDevicesFromDBSlice";
import { fetchGisStationsStaticDistrictFromWebService } from "../../redux/slices/webService/gisStationsStaticDistrictSlice"; import { fetchGisStationsStaticDistrictFromWebService } from "../../redux/slices/webService/gisStationsStaticDistrictSlice";
@@ -54,7 +53,6 @@ import { updateCountdown, closePolylineContextMenu } from "../../redux/slices/po
//-------------------MapComponent.js hooks-------------------- //-------------------MapComponent.js hooks--------------------
import useInitializeMap from "./hooks/useInitializeMap"; import useInitializeMap from "./hooks/useInitializeMap";
import useLoadUserRights from "./hooks/useLoadUserRights"; import useLoadUserRights from "./hooks/useLoadUserRights";
import useFetchWebServiceMap from "./hooks/useFetchWebServiceMap";
import useFetchPoiData from "./hooks/useFetchPoiData.js"; import useFetchPoiData from "./hooks/useFetchPoiData.js";
import useRestoreMapSettings from "./hooks/useRestoreMapSettings"; import useRestoreMapSettings from "./hooks/useRestoreMapSettings";
import { setSelectedPoi } from "../../redux/slices/selectedPoiSlice"; import { setSelectedPoi } from "../../redux/slices/selectedPoiSlice";
@@ -95,7 +93,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
const [currentPoiData, setCurrentPoiData] = useState(null); const [currentPoiData, setCurrentPoiData] = useState(null);
const [showVersionInfoModal, setShowVersionInfoModal] = useState(false); const [showVersionInfoModal, setShowVersionInfoModal] = useState(false);
const zoomTrigger = useSelector((state) => state.zoomTrigger.trigger); const zoomTrigger = useSelector((state) => state.zoomTrigger.trigger);
const [gisSystemStaticLoaded, setGisSystemStaticLoaded] = useState(false);
const [poiTypMap, setPoiTypMap] = useState(new Map()); const [poiTypMap, setPoiTypMap] = useState(new Map());
const [showPopup, setShowPopup] = useState(false); const [showPopup, setShowPopup] = useState(false);
const poiReadTrigger = useSelector((state) => state.poiReadFromDbTrigger.trigger); const poiReadTrigger = useSelector((state) => state.poiReadFromDbTrigger.trigger);
@@ -104,13 +102,11 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
const [map, setMap] = useState(null); // Zustand der Karteninstanz const [map, setMap] = useState(null); // Zustand der Karteninstanz
const [oms, setOms] = useState(null); // State für OMS-Instanz const [oms, setOms] = useState(null); // State für OMS-Instanz
const GisStationsStaticDistrict = useSelector(selectGisStationsStaticDistrict); const GisStationsStaticDistrict = useSelector(selectGisStationsStaticDistrict);
const [GisStationsStatusDistrict, setGisStationsStatusDistrict] = useState([]); // Zustand für Statusdaten
const [GisStationsMeasurements, setGisStationsMeasurements] = useState([]); // Zustand für Messdaten const [GisStationsMeasurements, setGisStationsMeasurements] = useState([]); // Zustand für Messdaten
const GisSystemStatic = useSelector(selectGisSystemStatic); const GisSystemStatic = useSelector(selectGisSystemStatic);
const gisSystemStaticStatus = useSelector((state) => state.gisSystemStatic.status);
// Konstanten für die URLs // Konstanten für die URLs
const mapGisStationsStatusDistrictUrl = config.mapGisStationsStatusDistrictUrl;
const mapGisStationsMeasurementsUrl = config.mapGisStationsMeasurementsUrl; const mapGisStationsMeasurementsUrl = config.mapGisStationsMeasurementsUrl;
const mapGisSystemStaticUrl = config.mapGisSystemStaticUrl;
const webserviceGisLinesStatusUrl = config.webserviceGisLinesStatusUrl; const webserviceGisLinesStatusUrl = config.webserviceGisLinesStatusUrl;
//console.log("priorityConfig in MapComponent1: ", priorityConfig); //console.log("priorityConfig in MapComponent1: ", priorityConfig);
//----------------------------------------- //-----------------------------------------
@@ -146,10 +142,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
const [showCoordinatesModal, setShowCoordinatesModal] = useState(false); const [showCoordinatesModal, setShowCoordinatesModal] = useState(false);
const [popupCoordinates, setPopupCoordinates] = useState(null); const [popupCoordinates, setPopupCoordinates] = useState(null);
const [popupVisible, setPopupVisible] = useState(false); const [popupVisible, setPopupVisible] = useState(false);
const handleAddStation = (stationData) => {
setAddPoiModalWindowState(false);
closePopup(); // Schließt das Popup nach dem Hinzufügen
};
const openVersionInfoModal = () => { const openVersionInfoModal = () => {
setShowVersionInfoModal(true); setShowVersionInfoModal(true);
}; };
@@ -188,7 +181,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
...tkComponentsMarkers, ...tkComponentsMarkers,
...ulafMarkers, ...ulafMarkers,
]; ];
const useMock = process.env.NEXT_PUBLIC_USE_MOCK_API === "true";
//-------------------------------------------- //--------------------------------------------
const gmaLayerRef = useRef(null); const gmaLayerRef = useRef(null);
const talasLayerRef = useRef(null); const talasLayerRef = useRef(null);
@@ -214,7 +206,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
dispatch(setUserId(params.get("u"))); dispatch(setUserId(params.get("u")));
}, [dispatch]); }, [dispatch]);
//--------------------------------------------------------------- //---------------------------------------------------------------
useFetchWebServiceMap(mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl, setGisStationsStatusDistrict, setGisStationsMeasurements, setGisSystemStatic, setGisSystemStaticLoaded);
//-------------------------------------------------------- //--------------------------------------------------------
useEffect(() => { useEffect(() => {
const endpoint = "/api/talas_v5_DB/gisLines/readGisLines"; const endpoint = "/api/talas_v5_DB/gisLines/readGisLines";
@@ -296,9 +288,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
//--------------------------------------------- //---------------------------------------------
//console.log("priorityConfig in MapComponent2: ", priorityConfig); //console.log("priorityConfig in MapComponent2: ", priorityConfig);
useEffect(() => { useEffect(() => {
if (gisSystemStaticLoaded && map) { if (map) {
} }
}, [gisSystemStaticLoaded, map, GisSystemStatic, priorityConfig]); }, [map, GisSystemStatic, priorityConfig]);
//-------------------------------------------- //--------------------------------------------
useEffect(() => { useEffect(() => {
if (map) { if (map) {
@@ -655,7 +647,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
useLayerVisibility(map, ulafMarkers, mapLayersVisibility, "ULAF", oms); useLayerVisibility(map, ulafMarkers, mapLayersVisibility, "ULAF", oms);
//-------------------------------------------- //--------------------------------------------
useEffect(() => { useEffect(() => {
if (!gisSystemStaticLoaded || !map) return; // Sicherstellen, dass die Karte und Daten geladen sind if (gisSystemStaticStatus !== "succeeded" || !map) return;
const layerGroups = [ const layerGroups = [
{ ref: gmaLayerRef, id: 11, setState: setGmaMarkers }, { ref: gmaLayerRef, id: 11, setState: setGmaMarkers },
@@ -740,7 +732,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
} }
}); });
}; };
}, [gisSystemStaticLoaded, map, GisSystemStatic, priorityConfig]); }, [map, GisSystemStatic, priorityConfig]);
//--------------------------------------- //---------------------------------------
// Initialisiere Leaflet-Karte // Initialisiere Leaflet-Karte

View File

@@ -1,52 +0,0 @@
// /components/mainComponent/hooks/useFetchWebServiceMap.js
import { useEffect } from "react";
import { fetchGisStationsStatusDistrictService } from "../../../services/webservice/fetchGisStationsStatusDistrictService";
import { fetchGisStationsMeasurementsService } from "../../../services/webservice/fetchGisStationsMeasurementsService";
import { fetchGisSystemStaticService } from "../../../services/webservice/fetchGisSystemStaticService";
const useFetchWebServiceMap = (mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl, setGisStationsStatusDistrict, setGisStationsMeasurements, setGisSystemStatic, setGisSystemStaticLoaded) => {
useEffect(() => {
//console.log("✅ useFetchWebServiceMap wurde ausgeführt!");
const fetchWebServiceMap = async () => {
try {
let requestCount = localStorage.getItem("fetchWebServiceMap") || 0;
requestCount = parseInt(requestCount, 10);
console.log("📡 Starte API-Anfragen...");
const fetchOptions = {
method: "GET",
headers: { Connection: "close" },
};
// GIS Stations Status District abrufen
//console.log("⏳ Abrufen von GIS Stations Status District...");
await fetchGisStationsStatusDistrictService(mapGisStationsStatusDistrictUrl, setGisStationsStatusDistrict, fetchOptions);
// console.log("✅ fetchGisStationsStatusDistrictService erfolgreich!");
requestCount++;
localStorage.setItem("fetchWebServiceMap", requestCount);
// GIS Stations Measurements abrufen
//console.log("⏳ Abrufen von GIS Stations Measurements...");
await fetchGisStationsMeasurementsService(mapGisStationsMeasurementsUrl, setGisStationsMeasurements, fetchOptions);
// console.log("✅ fetchGisStationsMeasurementsService erfolgreich!");
requestCount++;
localStorage.setItem("fetchWebServiceMap", requestCount);
// GIS System Static abrufen
//console.log("⏳ Abrufen von GIS System Static...");
await fetchGisSystemStaticService(mapGisSystemStaticUrl, setGisSystemStatic, setGisSystemStaticLoaded, fetchOptions);
//console.log("✅ fetchGisSystemStaticService erfolgreich!");
requestCount++;
localStorage.setItem("fetchWebServiceMap", requestCount);
} catch (error) {
console.error("❌ Fehler beim Abrufen der WebService-Daten:", error);
}
};
fetchWebServiceMap();
}, [mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl]);
};
export default useFetchWebServiceMap;

View File

@@ -1,28 +1,17 @@
// /components/pois/PoiUpdateModal.js // /components/pois/PoiUpdateModal.js
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import Select from "react-select"; // Importiere react-select import Select from "react-select"; // Importiere react-select
import { selectedPoiState } from "../../redux/slices/selectedPoiSlice";
import { currentPoiState } from "../../redux/slices/currentPoiSlice";
import { mapLayersState } from "../../redux/slices/mapLayersSlice";
import { fetchLocationDevicesFromDB } from "../../redux/slices/db/locationDevicesFromDBSlice"; import { fetchLocationDevicesFromDB } from "../../redux/slices/db/locationDevicesFromDBSlice";
import { useSelector, useDispatch } from "react-redux"; import { useSelector, useDispatch } from "react-redux";
import { selectCurrentPoi } from "../../redux/slices/currentPoiSlice";
import { selectMapLayersState } from "../../redux/slices/mapLayersSlice"; import { selectMapLayersState } from "../../redux/slices/mapLayersSlice";
const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => { const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const currentPoi = useSelector(selectCurrentPoi);
const selectedPoi = useSelector(selectCurrentPoi);
const mapLayersVisibility = useSelector(selectMapLayersState); const mapLayersVisibility = useSelector(selectMapLayersState);
const [poiId, setPoiId] = useState(poiData ? poiData.idPoi : ""); const [poiId, setPoiId] = useState(poiData ? poiData.idPoi : "");
const [name, setName] = useState(poiData ? poiData.name : ""); const [name, setName] = useState(poiData ? poiData.name : "");
const [poiTypData, setPoiTypData] = useState([]); const [poiTypData, setPoiTypData] = useState([]);
const [poiTypeId, setPoiTypeId] = useState(null); // Verwende null für react-select const [poiTypeId, setPoiTypeId] = useState(null); // Verwende null für react-select
const [locationDeviceData, setLocationDeviceData] = useState([]);
const [filteredDevices, setFilteredDevices] = useState([]); const [filteredDevices, setFilteredDevices] = useState([]);
const [deviceName, setDeviceName] = useState(poiData ? poiData.deviceName : null); // Verwende null für react-select const [deviceName, setDeviceName] = useState(poiData ? poiData.deviceName : null); // Verwende null für react-select
const [idLD, setIdLD] = useState(poiData ? poiData.idLD : ""); const [idLD, setIdLD] = useState(poiData ? poiData.idLD : "");

View File

@@ -1,2 +1,2 @@
// /config/appVersion // /config/appVersion
export const APP_VERSION = "1.1.120"; export const APP_VERSION = "1.1.121";

View File

@@ -1,4 +1,4 @@
// services/utils/fetchWithTimeout.js // /services/utils/fetchWithTimeout.js
const fetchWithTimeout = (url, options, timeout = 5000) => { const fetchWithTimeout = (url, options, timeout = 5000) => {
const controller = new AbortController(); const controller = new AbortController();

View File

@@ -1,18 +1,36 @@
// /services/webservice/fetchGisSystemStaticService.js // /services/webservice/fetchGisSystemStaticService.js
export const fetchGisSystemStaticService = async (url, setGisSystemStatic, setGisSystemStaticLoaded) => { /**
try { * Holt GIS-Systemdaten (Systemübersicht) vom TALAS WebService.
*
* @returns {Promise<Array>} Liste mit Systems[]
* @throws {Error} bei Fehler oder ungültiger Antwortstruktur
*/
export const fetchGisSystemStaticService = async () => {
const mode = process.env.NEXT_PUBLIC_API_PORT_MODE;
const apiBaseUrl = mode === "dev" ? `${window.location.protocol}//${window.location.hostname}:80/talas5/ClientData/WebServiceMap.asmx` : `${window.location.origin}/talas5/ClientData/WebServiceMap.asmx`;
const params = new URLSearchParams(window.location.search);
const idMap = params.get("m");
const idUser = params.get("u");
const url = `${apiBaseUrl}/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`;
console.log("📡 fetchGisSystemStaticService von service URL:", url);
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) {
const message = `❌ Fehler: ${response.status} ${response.statusText}`;
console.error(message);
throw new Error(message);
}
const jsonResponse = await response.json(); const jsonResponse = await response.json();
if (jsonResponse && jsonResponse.Systems) {
setGisSystemStatic(jsonResponse.Systems); if (!jsonResponse?.Systems) {
setGisSystemStaticLoaded(true); throw new Error("Antwortstruktur ungültig 'Systems' fehlt");
} else {
console.error('Erwartete Daten im "Systems"-Array nicht gefunden', jsonResponse);
setGisSystemStatic([]);
}
} catch (error) {
console.error("Fehler beim Laden der Daten: ", error);
setGisSystemStatic([]);
} }
return jsonResponse.Systems;
}; };