docs: README.md mit Bilder
This commit is contained in:
@@ -25,4 +25,4 @@ NEXT_PUBLIC_USE_MOCKS=true
|
|||||||
NEXT_PUBLIC_BASE_PATH=/talas5
|
NEXT_PUBLIC_BASE_PATH=/talas5
|
||||||
# Oder leer lassen für direkten Zugriff -> NEXT_PUBLIC_BASE_PATH=
|
# Oder leer lassen für direkten Zugriff -> NEXT_PUBLIC_BASE_PATH=
|
||||||
# App-Versionsnummer
|
# App-Versionsnummer
|
||||||
NEXT_PUBLIC_APP_VERSION=1.1.274
|
NEXT_PUBLIC_APP_VERSION=1.1.275
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ NEXT_PUBLIC_BASE_PATH=/talas5
|
|||||||
# Oder leer lassen für direkten Zugriff -> NEXT_PUBLIC_BASE_PATH=
|
# Oder leer lassen für direkten Zugriff -> NEXT_PUBLIC_BASE_PATH=
|
||||||
|
|
||||||
# App-Versionsnummer
|
# App-Versionsnummer
|
||||||
NEXT_PUBLIC_APP_VERSION=1.1.274
|
NEXT_PUBLIC_APP_VERSION=1.1.275
|
||||||
10
README.md
10
README.md
@@ -89,10 +89,11 @@ SharePoint verfügbar:
|
|||||||
|
|
||||||
#### 📂 Ablauf:
|
#### 📂 Ablauf:
|
||||||
|
|
||||||
1. 🛑 **Dienst stoppen**
|
1. 🛑 **Dienst beenden**
|
||||||
|
|
||||||
- Vor dem Update muss der bestehende Windows-Dienst `NodeMapService` gestoppt werden,
|
- Vor dem Update muss der bestehende Windows-Dienst `NodeMapService` beendet werden,
|
||||||
um Dateikonflikte beim Löschen zu vermeiden.
|
um Dateikonflikte beim Löschen zu vermeiden.
|
||||||
|

|
||||||
|
|
||||||
2. 🔍 **Prüfen, ob passende `node_modules-v1.1.xxx.zip` Datei vorhanden ist**
|
2. 🔍 **Prüfen, ob passende `node_modules-v1.1.xxx.zip` Datei vorhanden ist**
|
||||||
|
|
||||||
@@ -105,8 +106,9 @@ SharePoint verfügbar:
|
|||||||
3. 📦 **ZIP entpacken**
|
3. 📦 **ZIP entpacken**
|
||||||
|
|
||||||
- `NodeMap V1.1.260.zip` entpacken
|
- `NodeMap V1.1.260.zip` entpacken
|
||||||
⚠️ **Wichtig:** Nur den **Inhalt** des entpackten `deployment`-Ordners nach
|
⚠️ **Wichtig:** Nur den **Inhalt** des entpackten `deployment`-Ordners nach `C:\inetpub\wwwroot\talas5\nodeMap\`
|
||||||
`C:\inetpub\wwwroot\talas5\nodeMap\` kopieren – **nicht** den Ordner selbst.
|
kopieren – **nicht** den Ordner selbst.
|
||||||
|

|
||||||
|
|
||||||
4. 🚀 **Dienst starten**
|
4. 🚀 **Dienst starten**
|
||||||
- Windows-Dienst `NodeMapService` wieder starten
|
- Windows-Dienst `NodeMapService` wieder starten
|
||||||
|
|||||||
29
deployment/.env.production
Normal file
29
deployment/.env.production
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#.env.local
|
||||||
|
# DB-Settings (nur Backend)
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_USER=root
|
||||||
|
DB_PASSWORD="root#$"
|
||||||
|
DB_NAME=talas_v5
|
||||||
|
DB_PORT=3306
|
||||||
|
|
||||||
|
# Public Settings (Client braucht IP/Domain) , Variablen mit dem Präfix "NEXT_PUBLIC" ist in Browser sichtbar
|
||||||
|
NEXT_PUBLIC_DEBUG_LOG=false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#auf dem Entwicklungsrechner dev läuft auf Port 3000 und auf dem Server prod auf Port 80, aber der WebService ist immer auf PORT 80
|
||||||
|
NEXT_PUBLIC_API_PORT_MODE=prod
|
||||||
|
NEXT_PUBLIC_USE_MOCKS=false
|
||||||
|
|
||||||
|
# Der Unterordner talas5 gleich hinter der IP-Adresse (oder Servername) muss konfigurierbar sein.
|
||||||
|
# Es muss auch möglich sein kein Unterorder anzugeben (z.B. nur http://talasserver/).
|
||||||
|
# Ein Unterordner in der dort hinter liegenden Ordnerstruktur (z.B. http://talasserver/talas5/nodemap/api/talas_v5_DB/ usw.)
|
||||||
|
# kann bleiben da der Kunde diesen Unterordner talas:v5_db nicht ändert.
|
||||||
|
#Füge in deiner .env.local Datei die folgende Zeile hinzu wenn du einen Unterordner verwenden möchtest mit entsprechende Bezeichnung.
|
||||||
|
# z.B. http://10.10.0.13/talas5/index.aspx -> NEXT_PUBLIC_BASE_PATH=/talas5
|
||||||
|
# z.B. http://10.10.0.13/xyz/index.aspx -> NEXT_PUBLIC_BASE_PATH=/xyz
|
||||||
|
NEXT_PUBLIC_BASE_PATH=/talas5
|
||||||
|
# Oder leer lassen für direkten Zugriff -> NEXT_PUBLIC_BASE_PATH=
|
||||||
|
|
||||||
|
# App-Versionsnummer
|
||||||
|
NEXT_PUBLIC_APP_VERSION=1.1.274
|
||||||
7670
deployment/package-lock.json
generated
Normal file
7670
deployment/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
62
deployment/package.json
Normal file
62
deployment/package.json
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"name": "nodemap",
|
||||||
|
"version": "1.1.274",
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/react": "^11.13.3",
|
||||||
|
"@emotion/styled": "^11.13.0",
|
||||||
|
"@heroicons/react": "^2.1.5",
|
||||||
|
"@mui/icons-material": "^6.0.2",
|
||||||
|
"@reduxjs/toolkit": "^2.5.1",
|
||||||
|
"autoprefixer": "^10.4.19",
|
||||||
|
"axios": "^1.7.9",
|
||||||
|
"cookies": "^0.9.1",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"express": "^4.19.2",
|
||||||
|
"fast-xml-parser": "^4.5.1",
|
||||||
|
"http-proxy-middleware": "^3.0.0",
|
||||||
|
"leaflet": "^1.9.4",
|
||||||
|
"leaflet-contextmenu": "^1.4.0",
|
||||||
|
"leaflet-control-geocoder": "^3.1.0",
|
||||||
|
"leaflet.smooth_marker_bouncing": "^3.1.0",
|
||||||
|
"mysql": "^2.18.1",
|
||||||
|
"mysql2": "^3.11.0",
|
||||||
|
"next": "^14.2.5",
|
||||||
|
"nextjs-cors": "^2.2.0",
|
||||||
|
"overlapping-marker-spiderfier-leaflet": "^0.2.7",
|
||||||
|
"postcss": "^8.4.40",
|
||||||
|
"react": "^18.3.1",
|
||||||
|
"react-dom": "^18.3.1",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
|
"react-select": "^5.8.0",
|
||||||
|
"react-toastify": "^10.0.5",
|
||||||
|
"redux": "^5.0.1",
|
||||||
|
"redux-thunk": "^3.1.0",
|
||||||
|
"socket.io": "^4.8.1",
|
||||||
|
"socket.io-client": "^4.8.1",
|
||||||
|
"tailwindcss": "^3.4.7",
|
||||||
|
"xml2js": "^0.6.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "node server.js",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "cross-env NODE_ENV=production node server.js",
|
||||||
|
"export": "next export",
|
||||||
|
"test": "jest",
|
||||||
|
"cypress": "cypress open",
|
||||||
|
"cypress:run": "cypress run",
|
||||||
|
"prepare": "husky",
|
||||||
|
"bump-version": "node ./scripts/bumpVersion.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"cypress": "^13.17.0",
|
||||||
|
"husky": "^9.1.7",
|
||||||
|
"identity-obj-proxy": "^3.0.0",
|
||||||
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
|
"jest-fetch-mock": "^3.0.3",
|
||||||
|
"jest-junit": "^16.0.0",
|
||||||
|
"node-fetch": "^3.3.2",
|
||||||
|
"node-mocks-http": "^1.16.2",
|
||||||
|
"raw-loader": "^4.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
128
deployment/server.js
Normal file
128
deployment/server.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
// server.js
|
||||||
|
const { createServer } = require("http");
|
||||||
|
const next = require("next");
|
||||||
|
const { Server } = require("socket.io");
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
const fetch = (...args) => import("node-fetch").then(({ default: fetch }) => fetch(...args));
|
||||||
|
|
||||||
|
const dev = process.env.NODE_ENV !== "production";
|
||||||
|
const app = next({ dev });
|
||||||
|
const handle = app.getRequestHandler();
|
||||||
|
const PORT = 3000;
|
||||||
|
|
||||||
|
// Hilfsfunktion zum Schreiben von JSON-Dateien bei Änderung
|
||||||
|
const writeJsonFile = (filename, data) => {
|
||||||
|
const dir = path.join(process.cwd(), "websocketDump");
|
||||||
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir);
|
||||||
|
const fullPath = path.join(dir, filename);
|
||||||
|
fs.writeFileSync(fullPath, JSON.stringify(data, null, 2), "utf-8");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extrahiert relevante Datenstruktur aus Antwort
|
||||||
|
const extractData = (json, name) => {
|
||||||
|
return (
|
||||||
|
json?.Statis || json?.Points || json?.Systems || json?.Rights || json?.[name] || json || []
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
app.prepare().then(() => {
|
||||||
|
const server = createServer((req, res) => {
|
||||||
|
handle(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
const io = new Server(server);
|
||||||
|
|
||||||
|
io.on("connection", socket => {
|
||||||
|
const { m: idMap, u: idUser } = socket.handshake.query;
|
||||||
|
console.log(`🔌 WebSocket verbunden (idMap=${idMap}, idUser=${idUser})`);
|
||||||
|
|
||||||
|
const endpoints = [
|
||||||
|
{
|
||||||
|
name: "GisLinesStatus",
|
||||||
|
getUrl: () => `WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`,
|
||||||
|
mock: "GisLinesStatus.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GisStationsMeasurements",
|
||||||
|
getUrl: () => `WebServiceMap.asmx/GisStationsMeasurements?idMap=${idMap}`,
|
||||||
|
mock: "GisStationsMeasurements.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GisStationsStaticDistrict",
|
||||||
|
getUrl: () =>
|
||||||
|
`WebServiceMap.asmx/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`,
|
||||||
|
mock: "GisStationsStaticDistrict.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GisStationsStatusDistrict",
|
||||||
|
getUrl: () =>
|
||||||
|
`WebServiceMap.asmx/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`,
|
||||||
|
mock: "GisStationsStatusDistrict.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GisSystemStatic",
|
||||||
|
getUrl: () => `WebServiceMap.asmx/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`,
|
||||||
|
mock: "GisSystemStatic.json",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const lastDataMap = {};
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
for (const { name, getUrl, mock } of endpoints) {
|
||||||
|
try {
|
||||||
|
let statis;
|
||||||
|
|
||||||
|
if (dev) {
|
||||||
|
const mockPath = path.join(process.cwd(), "mockData", mock);
|
||||||
|
const jsonStr = fs.readFileSync(mockPath, "utf-8");
|
||||||
|
const json = JSON.parse(jsonStr);
|
||||||
|
statis = extractData(json, name);
|
||||||
|
console.log(`🧪 [Mock] ${name}`);
|
||||||
|
} else {
|
||||||
|
const fetchUrl = `http://localhost/talas5/ClientData/${getUrl()}`;
|
||||||
|
const res = await fetch(fetchUrl);
|
||||||
|
const text = await res.text();
|
||||||
|
|
||||||
|
let json;
|
||||||
|
try {
|
||||||
|
json = JSON.parse(text);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`❌ ${name}: JSON Parsing fehlgeschlagen:`, err.message);
|
||||||
|
console.error(`🔍 Antwort war:`, text.slice(0, 300));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
statis = extractData(json, name);
|
||||||
|
console.log(`📡 Webservice-Daten empfangen für ${name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newDataStr = JSON.stringify(statis);
|
||||||
|
if (newDataStr !== lastDataMap[name]) {
|
||||||
|
lastDataMap[name] = newDataStr;
|
||||||
|
socket.emit(`${name}Updated`, statis);
|
||||||
|
console.log(`✅ Änderung bei ${name} erkannt → gesendet`);
|
||||||
|
writeJsonFile(`${name}.json`, statis);
|
||||||
|
} else {
|
||||||
|
// console.log(`🔁 ${name}: Keine Änderung`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`❌ Fehler bei ${name}:`, error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// fetchData immer ausführen – unabhängig vom Modus
|
||||||
|
fetchData();
|
||||||
|
const interval = setInterval(fetchData, 5000); // 5 Sekunden ,TALAS.web nutzt 12 Sekunden
|
||||||
|
socket.on("disconnect", () => {
|
||||||
|
clearInterval(interval);
|
||||||
|
console.log("❌ WebSocket getrennt");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(PORT, () => {
|
||||||
|
console.log(`🚀 App + WebSocket läuft auf http://localhost:${PORT}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
BIN
docs/screenshots/Dienst-beenden.png
Normal file
BIN
docs/screenshots/Dienst-beenden.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
BIN
docs/screenshots/Dienste.png
Normal file
BIN
docs/screenshots/Dienste.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
docs/screenshots/nodeMap-inhalt.png
Normal file
BIN
docs/screenshots/nodeMap-inhalt.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "nodemap",
|
"name": "nodemap",
|
||||||
"version": "1.1.274",
|
"version": "1.1.275",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "nodemap",
|
"name": "nodemap",
|
||||||
"version": "1.1.274",
|
"version": "1.1.275",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.13.3",
|
"@emotion/react": "^11.13.3",
|
||||||
"@emotion/styled": "^11.13.0",
|
"@emotion/styled": "^11.13.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nodemap",
|
"name": "nodemap",
|
||||||
"version": "1.1.274",
|
"version": "1.1.275",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.13.3",
|
"@emotion/react": "^11.13.3",
|
||||||
"@emotion/styled": "^11.13.0",
|
"@emotion/styled": "^11.13.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user