Add Falukant region and transport management features

- Implemented new endpoints in AdminController for managing Falukant regions, including fetching, updating, and deleting region distances.
- Enhanced the FalukantService with methods for retrieving region distances and handling upsert operations.
- Updated the router to expose new routes for region management and transport creation.
- Introduced a transport management interface in the frontend, allowing users to create and manage transports between branches.
- Added localization for new transport-related terms and improved the vehicle management interface to include transport options.
- Enhanced the database initialization logic to support new region and transport models.
This commit is contained in:
Torsten Schulz (local)
2025-11-26 16:44:27 +01:00
parent d389e78edf
commit 6976ac52a6
27 changed files with 2100 additions and 57 deletions

View File

@@ -24,6 +24,18 @@
</select>
</label>
<label class="form-label">
{{ $t('falukant.branch.transport.mode') }}
<select v-model="mode" class="form-control">
<option value="buy">
{{ $t('falukant.branch.transport.modeBuy') }}
</option>
<option value="build">
{{ $t('falukant.branch.transport.modeBuild') }}
</option>
</select>
</label>
<label class="form-label">
{{ $t('falukant.branch.transport.quantity') }}
<input
@@ -39,6 +51,11 @@
<strong>{{ formatCost(totalCost) }}</strong>
</p>
<p v-if="selectedType" class="buildtime">
{{ $t('falukant.branch.transport.buildTime') }}:
<span>{{ formattedBuildTime }}</span>
</p>
<p v-if="totalCost > money" class="warning">
{{ $t('falukant.branch.transport.notEnoughMoney') }}
</p>
@@ -64,6 +81,7 @@ export default {
vehicleTypes: [],
selectedTypeId: null,
quantity: 1,
mode: 'buy',
money: 0,
loaded: false,
};
@@ -73,7 +91,10 @@ export default {
return [
{ text: this.$t('Cancel'), action: this.close },
{
text: this.$t('falukant.branch.transport.buy'),
text:
this.mode === 'build'
? this.$t('falukant.branch.transport.buildAction')
: this.$t('falukant.branch.transport.buyAction'),
action: this.onConfirm,
disabled: !this.canBuy,
},
@@ -85,7 +106,11 @@ export default {
totalCost() {
if (!this.selectedType) return 0;
const q = Math.max(1, this.quantity || 0);
return this.selectedType.cost * q;
const unit =
this.mode === 'build'
? Math.round(this.selectedType.cost * 0.75)
: this.selectedType.cost;
return unit * q;
},
canBuy() {
return (
@@ -99,11 +124,23 @@ export default {
formattedMoney() {
return this.formatCost(this.money);
},
formattedBuildTime() {
if (!this.selectedType || !this.selectedType.buildTimeMinutes) return '-';
const total = this.selectedType.buildTimeMinutes;
const h = Math.floor(total / 60);
const m = total % 60;
if (h > 0 && m > 0) {
return `${h} h ${m} min`;
}
if (h > 0) return `${h} h`;
return `${m} min`;
},
},
methods: {
async open() {
this.loaded = false;
this.quantity = 1;
this.mode = 'buy';
await Promise.all([this.loadVehicleTypes(), this.loadMoney()]);
if (this.vehicleTypes.length && !this.selectedTypeId) {
this.selectedTypeId = this.vehicleTypes[0].id;
@@ -139,6 +176,7 @@ export default {
vehicleTypeId: this.selectedTypeId,
quantity: this.quantity,
regionId: this.regionId,
mode: this.mode,
});
this.$emit('bought');
this.close();