Änderung: Erweiterung der Taxi-Map-Logik und Verbesserung der Benutzeroberfläche

Änderungen:
- Hinzufügung neuer Modelle für TaxiMapTile, TaxiStreetName und TaxiMapTileStreet zur Unterstützung der Tile- und Straßennamen-Logik.
- Anpassung der TaxiMap- und TaxiMapService-Logik zur Verwaltung von Tiles und Straßennamen.
- Implementierung von Methoden zur Upsert-Logik für Tiles und Straßennamen in der TaxiMapService.
- Verbesserung der Benutzeroberfläche in TaxiToolsView.vue zur Anzeige und Bearbeitung von Straßennamen und zusätzlichen Elementen.

Diese Anpassungen verbessern die Funktionalität und Benutzererfahrung im Taxi-Minispiel erheblich, indem sie eine detailliertere Verwaltung von Karten und Straßennamen ermöglichen.
This commit is contained in:
Torsten Schulz (local)
2025-09-17 18:55:57 +02:00
parent 76fe67fbe3
commit 9db7c88086
20 changed files with 969 additions and 98 deletions

View File

@@ -1,6 +1,9 @@
import BaseService from './BaseService.js';
import TaxiMap from '../models/taxi/taxiMap.js';
import TaxiMapType from '../models/taxi/taxiMapType.js';
import TaxiMapTile from '../models/taxi/taxiMapTile.js';
import TaxiStreetName from '../models/taxi/taxiStreetName.js';
import TaxiMapTileStreet from '../models/taxi/taxiMapTileStreet.js';
class TaxiMapService extends BaseService {
constructor() {
@@ -30,10 +33,18 @@ class TaxiMapService extends BaseService {
try {
const maps = await TaxiMap.findAll({
where: { isActive: true },
include: [{
model: TaxiMapType,
as: 'mapType'
}],
include: [
{ model: TaxiMapType, as: 'mapType' },
{ model: TaxiMapTile, as: 'tiles' },
{
model: TaxiMapTileStreet,
as: 'tileStreets',
include: [
{ model: TaxiStreetName, as: 'streetNameH' },
{ model: TaxiStreetName, as: 'streetNameV' }
]
}
],
order: [['name', 'ASC']]
});
return maps;
@@ -53,10 +64,18 @@ class TaxiMapService extends BaseService {
id: mapId,
isActive: true
},
include: [{
model: TaxiMapType,
as: 'mapType'
}]
include: [
{ model: TaxiMapType, as: 'mapType' },
{ model: TaxiMapTile, as: 'tiles' },
{
model: TaxiMapTileStreet,
as: 'tileStreets',
include: [
{ model: TaxiStreetName, as: 'streetNameH' },
{ model: TaxiStreetName, as: 'streetNameV' }
]
}
]
});
return map;
} catch (error) {
@@ -93,8 +112,18 @@ class TaxiMapService extends BaseService {
*/
async createMap(mapData) {
try {
const map = await TaxiMap.create(mapData);
return map;
const { tiles, tileStreetNames, ...mapFields } = mapData;
// mapData JSON ist entfernt map erstellen ohne mapData
const map = await TaxiMap.create(mapFields);
// Tiles upsert (optional)
if (Array.isArray(tiles) && tiles.length > 0) {
await this.upsertTiles(map.id, tiles);
}
// Street names (optional)
if (tileStreetNames && Object.keys(tileStreetNames).length > 0) {
await this.upsertTileStreetNames(map.id, tileStreetNames);
}
return await this.getMapById(map.id);
} catch (error) {
console.error('Error creating map:', error);
throw error;
@@ -106,7 +135,8 @@ class TaxiMapService extends BaseService {
*/
async updateMap(mapId, updateData) {
try {
const [updatedRowsCount] = await TaxiMap.update(updateData, {
const { tiles, tileStreetNames, ...mapFields } = updateData;
const [updatedRowsCount] = await TaxiMap.update(mapFields, {
where: { id: mapId }
});
@@ -114,6 +144,13 @@ class TaxiMapService extends BaseService {
throw new Error('Map not found');
}
// Tiles upsert (optional)
if (Array.isArray(tiles)) {
await this.upsertTiles(mapId, tiles);
}
if (tileStreetNames && Object.keys(tileStreetNames).length > 0) {
await this.upsertTileStreetNames(mapId, tileStreetNames);
}
return await this.getMapById(mapId);
} catch (error) {
console.error('Error updating map:', error);
@@ -121,6 +158,53 @@ class TaxiMapService extends BaseService {
}
}
/**
* Speichert Straßennamen-Belegungen für eine Map
* @param {number} mapId
* @param {{[cellKey:string]:{streetNameH?:string, streetNameV?:string}}} tileNames
*/
async upsertTileStreetNames(mapId, tileNames) {
const entries = Object.entries(tileNames || {});
for (const [cellKey, data] of entries) {
const [x, y] = cellKey.split(',').map(Number);
const record = { mapId, x, y };
// Street names: findOrCreate
if (data.streetNameH) {
const [snH] = await TaxiStreetName.findOrCreate({ where: { name: data.streetNameH }, defaults: { name: data.streetNameH } });
record.streetNameHId = snH.id;
} else {
record.streetNameHId = null;
}
if (data.streetNameV) {
const [snV] = await TaxiStreetName.findOrCreate({ where: { name: data.streetNameV }, defaults: { name: data.streetNameV } });
record.streetNameVId = snV.id;
} else {
record.streetNameVId = null;
}
const [row] = await TaxiMapTileStreet.findOrCreate({ where: { mapId, x, y }, defaults: record });
await row.update(record);
}
return { success: true };
}
/**
* Upsert Tiles (x,y,tileType,meta?) pro Map
* Erwartet: tiles: Array<{x:number,y:number,tileType:string, meta?:object}>
*/
async upsertTiles(mapId, tiles) {
for (const tile of tiles) {
const { x, y, tileType, meta } = tile;
if (typeof x !== 'number' || typeof y !== 'number' || !tileType) continue;
const [row] = await TaxiMapTile.findOrCreate({
where: { mapId, x, y },
defaults: { mapId, x, y, tileType, meta: meta || null }
});
await row.update({ tileType, meta: meta || null });
}
return { success: true };
}
/**
* Löscht eine Map (soft delete)
*/