Änderung: Bereinigung und Optimierung der Taxi-Map-Logik

Änderungen:
- Entfernen der Methode `getMapByPosition` aus dem `TaxiMapController` und der zugehörigen Logik im `TaxiMapService`, um die Komplexität zu reduzieren.
- Anpassung der Datenbankmodelle für `TaxiMap`, `TaxiLevelStats` und `TaxiMapType`, um die Tabellennamen zu vereinheitlichen.
- Aktualisierung der Routen im `taxiMapRouter`, um die entfernte Funktionalität zu reflektieren.
- Hinzufügung von neuen Importen in `index.js`, um die neuen Modelle zu integrieren.
- Verbesserung der Benutzeroberfläche durch neue Erfolgsmeldungen in den Übersetzungsdateien für die Admin-Oberfläche.

Diese Anpassungen tragen zur Vereinfachung der Codebasis und zur Verbesserung der Benutzererfahrung im Taxi-Minispiel bei.
This commit is contained in:
Torsten Schulz (local)
2025-09-15 19:28:57 +02:00
parent f343509d85
commit 935928af75
12 changed files with 35 additions and 172 deletions

View File

@@ -8,7 +8,6 @@ class TaxiMapController {
this.getMapTypes = this.getMapTypes.bind(this); this.getMapTypes = this.getMapTypes.bind(this);
this.getMaps = this.getMaps.bind(this); this.getMaps = this.getMaps.bind(this);
this.getMapById = this.getMapById.bind(this); this.getMapById = this.getMapById.bind(this);
this.getMapByPosition = this.getMapByPosition.bind(this);
this.getDefaultMap = this.getDefaultMap.bind(this); this.getDefaultMap = this.getDefaultMap.bind(this);
this.createMap = this.createMap.bind(this); this.createMap = this.createMap.bind(this);
this.updateMap = this.updateMap.bind(this); this.updateMap = this.updateMap.bind(this);
@@ -52,24 +51,6 @@ class TaxiMapController {
} }
} }
async getMapByPosition(req, res) {
try {
const { positionX, positionY } = req.params;
const map = await this.taxiMapService.getMapByPosition(
parseInt(positionX),
parseInt(positionY)
);
if (!map) {
return res.status(404).json({ success: false, message: 'Map an Position nicht gefunden' });
}
res.json({ success: true, data: map });
} catch (error) {
console.error('Error getting map by position:', error);
res.status(500).json({ success: false, message: 'Fehler beim Laden der Map' });
}
}
async getDefaultMap(req, res) { async getDefaultMap(req, res) {
try { try {

View File

@@ -97,6 +97,8 @@ import Match3UserLevelProgress from './match3/userLevelProgress.js';
// — Taxi Minigame — // — Taxi Minigame —
import { TaxiGameState, TaxiLevelStats } from './taxi/index.js'; import { TaxiGameState, TaxiLevelStats } from './taxi/index.js';
import TaxiMap from './taxi/taxiMap.js';
import TaxiMapType from './taxi/taxiMapType.js';
// — Politische Ämter (Politics) — // — Politische Ämter (Politics) —
import PoliticalOfficeType from './falukant/type/political_office_type.js'; import PoliticalOfficeType from './falukant/type/political_office_type.js';
@@ -237,6 +239,8 @@ const models = {
// Taxi Minigame // Taxi Minigame
TaxiGameState, TaxiGameState,
TaxiLevelStats, TaxiLevelStats,
TaxiMap,
TaxiMapType,
}; };
export default models; export default models;

View File

@@ -52,7 +52,7 @@ const TaxiGameState = sequelize.define('TaxiGameState', {
defaultValue: DataTypes.NOW defaultValue: DataTypes.NOW
} }
}, { }, {
tableName: 'taxi_game_states', tableName: 'taxi_game_state',
schema: 'taxi', schema: 'taxi',
timestamps: true, timestamps: true,
indexes: [ indexes: [

View File

@@ -56,7 +56,7 @@ const TaxiLevelStats = sequelize.define('TaxiLevelStats', {
defaultValue: DataTypes.NOW defaultValue: DataTypes.NOW
} }
}, { }, {
tableName: 'taxi_level_stats', tableName: 'taxi_level_stat',
schema: 'taxi', schema: 'taxi',
timestamps: true, timestamps: true,
indexes: [ indexes: [

View File

@@ -43,16 +43,6 @@ const TaxiMap = sequelize.define('TaxiMap', {
allowNull: false, allowNull: false,
comment: '2D array of map type IDs for each tile position' comment: '2D array of map type IDs for each tile position'
}, },
positionX: {
type: DataTypes.INTEGER,
allowNull: false,
comment: 'X position as continuous integer (1, 2, 3, ...)'
},
positionY: {
type: DataTypes.INTEGER,
allowNull: false,
comment: 'Y position as continuous integer (1, 2, 3, ...)'
},
isActive: { isActive: {
type: DataTypes.BOOLEAN, type: DataTypes.BOOLEAN,
allowNull: false, allowNull: false,
@@ -75,7 +65,7 @@ const TaxiMap = sequelize.define('TaxiMap', {
defaultValue: DataTypes.NOW defaultValue: DataTypes.NOW
} }
}, { }, {
tableName: 'taxi_maps', tableName: 'taxi_map',
schema: 'taxi', schema: 'taxi',
timestamps: true, timestamps: true,
indexes: [ indexes: [
@@ -88,13 +78,6 @@ const TaxiMap = sequelize.define('TaxiMap', {
{ {
fields: ['is_default'] fields: ['is_default']
}, },
{
fields: ['position_x', 'position_y']
},
{
unique: true,
fields: ['position_x', 'position_y']
}
] ]
}); });

View File

@@ -37,7 +37,7 @@ const TaxiMapType = sequelize.define('TaxiMapType', {
defaultValue: DataTypes.NOW defaultValue: DataTypes.NOW
} }
}, { }, {
tableName: 'taxi_map_types', tableName: 'taxi_map_type',
schema: 'taxi', schema: 'taxi',
timestamps: true, timestamps: true,
indexes: [ indexes: [

View File

@@ -14,7 +14,6 @@ router.get('/map-types', (req, res) => taxiMapController.getMapTypes(req, res));
// Maps routes // Maps routes
router.get('/maps', (req, res) => taxiMapController.getMaps(req, res)); router.get('/maps', (req, res) => taxiMapController.getMaps(req, res));
router.get('/maps/default', (req, res) => taxiMapController.getDefaultMap(req, res)); router.get('/maps/default', (req, res) => taxiMapController.getDefaultMap(req, res));
router.get('/maps/position/:positionX/:positionY', (req, res) => taxiMapController.getMapByPosition(req, res));
router.get('/maps/:mapId', (req, res) => taxiMapController.getMapById(req, res)); router.get('/maps/:mapId', (req, res) => taxiMapController.getMapById(req, res));
// Map management routes (admin only - you might want to add admin middleware) // Map management routes (admin only - you might want to add admin middleware)

View File

@@ -34,7 +34,7 @@ class TaxiMapService extends BaseService {
model: TaxiMapType, model: TaxiMapType,
as: 'mapType' as: 'mapType'
}], }],
order: [['positionY', 'ASC'], ['positionX', 'ASC']] order: [['name', 'ASC']]
}); });
return maps; return maps;
} catch (error) { } catch (error) {
@@ -65,28 +65,6 @@ class TaxiMapService extends BaseService {
} }
} }
/**
* Holt eine Map nach Position
*/
async getMapByPosition(positionX, positionY) {
try {
const map = await TaxiMap.findOne({
where: {
positionX: positionX,
positionY: positionY,
isActive: true
},
include: [{
model: TaxiMapType,
as: 'mapType'
}]
});
return map;
} catch (error) {
console.error('Error getting map by position:', error);
throw error;
}
}
/** /**
* Holt die Standard-Map * Holt die Standard-Map
@@ -231,38 +209,6 @@ class TaxiMapService extends BaseService {
* Erstellt eine Standard-Map * Erstellt eine Standard-Map
*/ */
async createDefaultMap() { async createDefaultMap() {
try {
// 8x8 Standard-Map mit verschiedenen Tile-Typen
const mapData = [
['cornerTopLeft', 'horizontal', 'horizontal', 'horizontal', 'horizontal', 'horizontal', 'horizontal', 'cornerTopRight'],
['vertical', 'cross', 'cross', 'cross', 'cross', 'cross', 'cross', 'vertical'],
['vertical', 'cross', 'cross', 'cross', 'cross', 'cross', 'cross', 'vertical'],
['vertical', 'cross', 'cross', 'cross', 'cross', 'cross', 'cross', 'vertical'],
['vertical', 'cross', 'cross', 'cross', 'cross', 'cross', 'cross', 'vertical'],
['vertical', 'cross', 'cross', 'cross', 'cross', 'cross', 'cross', 'vertical'],
['vertical', 'cross', 'cross', 'cross', 'cross', 'cross', 'cross', 'vertical'],
['cornerBottomLeft', 'horizontal', 'horizontal', 'horizontal', 'horizontal', 'horizontal', 'horizontal', 'cornerBottomRight']
];
const map = await TaxiMap.create({
name: 'Standard City Map',
description: 'A standard 8x8 city map with roads and intersections',
width: 8,
height: 8,
tileSize: 50,
mapTypeId: 1, // Assuming first map type
mapData: mapData,
positionX: 1,
positionY: 1,
isDefault: true,
isActive: true
});
return map;
} catch (error) {
console.error('Error creating default map:', error);
throw error;
}
} }
} }

View File

@@ -218,7 +218,10 @@
"delete": "Löschen", "delete": "Löschen",
"update": "Aktualisieren", "update": "Aktualisieren",
"cancel": "Abbrechen", "cancel": "Abbrechen",
"create": "Erstellen" "create": "Erstellen",
"createSuccess": "Map wurde erfolgreich erstellt!",
"updateSuccess": "Map wurde erfolgreich aktualisiert!",
"deleteSuccess": "Map wurde erfolgreich gelöscht!"
} }
} }
} }

View File

@@ -218,7 +218,10 @@
"delete": "Delete", "delete": "Delete",
"update": "Update", "update": "Update",
"cancel": "Cancel", "cancel": "Cancel",
"create": "Create" "create": "Create",
"createSuccess": "Map created successfully!",
"updateSuccess": "Map updated successfully!",
"deleteSuccess": "Map deleted successfully!"
} }
} }
} }

View File

@@ -8,7 +8,7 @@
<SimpleTabs v-model="activeTab" :tabs="tabs" /> <SimpleTabs v-model="activeTab" :tabs="tabs" />
<!-- Map bearbeiten Tab --> <!-- {{ $t('admin.taxiTools.mapEditor.title') }} Tab -->
<div v-if="activeTab === 'map-editor'" class="taxi-tools-admin"> <div v-if="activeTab === 'map-editor'" class="taxi-tools-admin">
<div class="section-header"> <div class="section-header">
<h2>{{ $t('admin.taxiTools.mapEditor.title') }}</h2> <h2>{{ $t('admin.taxiTools.mapEditor.title') }}</h2>
@@ -68,14 +68,6 @@
<div class="map-editor-container"> <div class="map-editor-container">
<!-- Spielbrett (links) --> <!-- Spielbrett (links) -->
<div class="game-board"> <div class="game-board">
<div class="board-info">
<p>Größe: {{ boardWidth }}x{{ boardHeight }}</p>
<p>Position: ({{ minX }}, {{ minY }}) - ({{ maxX }}, {{ maxY }})</p>
<div v-if="selectedCellKey" class="selection-info">
<p><strong>Ausgewählte Position:</strong> ({{ getCellPosition(selectedCellKey).x }}, {{ getCellPosition(selectedCellKey).y }})</p>
<p>Wählen Sie rechts ein Tile aus, um es hier zu platzieren.</p>
</div>
</div>
<div class="board-grid" :style="boardGridStyle"> <div class="board-grid" :style="boardGridStyle">
<div <div
v-for="y in range(minY, maxY)" v-for="y in range(minY, maxY)"
@@ -96,7 +88,6 @@
:alt="getCellAtPosition(x, y).tileType" :alt="getCellAtPosition(x, y).tileType"
class="tile-image" class="tile-image"
/> />
<div v-else class="position-label">{{x}},{{y}}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -171,14 +162,6 @@
<div class="map-editor-container"> <div class="map-editor-container">
<!-- Spielbrett (links) --> <!-- Spielbrett (links) -->
<div class="game-board"> <div class="game-board">
<div class="board-info">
<p>Größe: {{ boardWidth }}x{{ boardHeight }}</p>
<p>Position: ({{ minX }}, {{ minY }}) - ({{ maxX }}, {{ maxY }})</p>
<div v-if="selectedCellKey" class="selection-info">
<p><strong>Ausgewählte Position:</strong> ({{ getCellPosition(selectedCellKey).x }}, {{ getCellPosition(selectedCellKey).y }})</p>
<p>Wählen Sie rechts ein Tile aus, um es hier zu platzieren.</p>
</div>
</div>
<div class="board-grid" :style="boardGridStyle"> <div class="board-grid" :style="boardGridStyle">
<div <div
v-for="y in range(minY, maxY)" v-for="y in range(minY, maxY)"
@@ -199,7 +182,6 @@
:alt="getCellAtPosition(x, y).tileType" :alt="getCellAtPosition(x, y).tileType"
class="tile-image" class="tile-image"
/> />
<div v-else class="position-label">{{x}},{{y}}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -240,17 +222,22 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Message Dialog -->
<MessageDialog ref="messageDialog" />
</div> </div>
</template> </template>
<script> <script>
import SimpleTabs from '../../components/SimpleTabs.vue'; import SimpleTabs from '../../components/SimpleTabs.vue';
import MessageDialog from '../../dialogues/standard/MessageDialog.vue';
import apiClient from '../../utils/axios.js'; import apiClient from '../../utils/axios.js';
export default { export default {
name: 'AdminTaxiToolsView', name: 'AdminTaxiToolsView',
components: { components: {
SimpleTabs SimpleTabs,
MessageDialog
}, },
data() { data() {
return { return {
@@ -487,9 +474,6 @@ export default {
}, },
getRelevantNeighbors(x, y, tileType) { getRelevantNeighbors(x, y, tileType) {
console.log('=== getRelevantNeighbors DEBUG ===');
console.log('Getting neighbors for tile:', tileType, 'at position:', { x, y });
const neighbors = []; const neighbors = [];
switch (tileType) { switch (tileType) {
@@ -550,9 +534,6 @@ export default {
return []; return [];
} }
console.log('Relevant neighbors calculated:', neighbors);
console.log('=====================================');
return neighbors; return neighbors;
}, },
@@ -684,19 +665,6 @@ export default {
return mapData; return mapData;
}, },
calculatePosition() {
if (Object.keys(this.boardCells).length === 0) {
return { x: 1, y: 1 };
}
// Position basiert auf dem ersten platzierten Tile
const firstTile = Object.values(this.boardCells).find(cell => cell.tileType);
if (firstTile) {
return { x: firstTile.x, y: firstTile.y };
}
return { x: this.minX, y: this.minY };
},
cancelEdit() { cancelEdit() {
this.editingMap = null; this.editingMap = null;
@@ -713,20 +681,19 @@ export default {
async saveMap() { async saveMap() {
try { try {
const position = this.calculatePosition();
const mapData = { const mapData = {
...this.mapForm, ...this.mapForm,
width: this.boardWidth, width: this.boardWidth,
height: this.boardHeight, height: this.boardHeight,
tileSize: 50, tileSize: 50,
positionX: position.x,
positionY: position.y,
mapTypeId: 1, // Standard Map-Typ mapTypeId: 1, // Standard Map-Typ
mapData: this.generateMapData() mapData: this.generateMapData()
}; };
let savedMap; let savedMap;
if (this.selectedMapId !== 'new') { const isUpdate = this.selectedMapId !== 'new';
if (isUpdate) {
// Map aktualisieren // Map aktualisieren
const response = await apiClient.put(`/api/taxi-maps/maps/${this.selectedMapId}`, mapData); const response = await apiClient.put(`/api/taxi-maps/maps/${this.selectedMapId}`, mapData);
savedMap = response.data.data; savedMap = response.data.data;
@@ -741,6 +708,10 @@ export default {
this.selectedCellKey = null; this.selectedCellKey = null;
this.selectedTileType = null; this.selectedTileType = null;
this.loadMaps(); this.loadMaps();
// Erfolgsmeldung anzeigen
const message = isUpdate ? 'admin.taxiTools.mapEditor.updateSuccess' : 'admin.taxiTools.mapEditor.createSuccess';
this.$refs.messageDialog.open(`tr:${message}`);
} catch (error) { } catch (error) {
console.error('Fehler beim Speichern der Map:', error); console.error('Fehler beim Speichern der Map:', error);
alert('Fehler beim Speichern der Map'); alert('Fehler beim Speichern der Map');
@@ -752,6 +723,9 @@ export default {
try { try {
await apiClient.delete(`/api/taxi-maps/maps/${mapId}`); await apiClient.delete(`/api/taxi-maps/maps/${mapId}`);
this.loadMaps(); this.loadMaps();
// Erfolgsmeldung anzeigen
this.$refs.messageDialog.open('tr:admin.taxiTools.mapEditor.deleteSuccess');
} catch (error) { } catch (error) {
console.error('Fehler beim Löschen der Map:', error); console.error('Fehler beim Löschen der Map:', error);
} }
@@ -897,32 +871,6 @@ export default {
max-width: 600px; max-width: 600px;
} }
.board-info {
margin-bottom: 10px;
padding: 10px;
background: #f0f0f0;
border-radius: 4px;
font-size: 14px;
color: #666;
}
.board-info p {
margin: 2px 0;
}
.selection-info {
margin-top: 10px;
padding: 8px;
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 4px;
font-size: 13px;
}
.selection-info p {
margin: 2px 0;
color: #856404;
}
.board-grid { .board-grid {
border: 2px solid #333; border: 2px solid #333;
@@ -953,11 +901,6 @@ export default {
transform: scale(1.05); transform: scale(1.05);
} }
.position-label {
font-size: 10px;
color: #666;
font-weight: bold;
}
.board-cell.selected { .board-cell.selected {
border: 3px solid #ffd700; /* Gelb für ausgewählte Zelle */ border: 3px solid #ffd700; /* Gelb für ausgewählte Zelle */

View File

@@ -156,6 +156,7 @@
<script> <script>
import streetCoordinates from '../../utils/streetCoordinates.js'; import streetCoordinates from '../../utils/streetCoordinates.js';
import apiClient from '../../utils/axios.js';
export default { export default {
name: 'TaxiGame', name: 'TaxiGame',