mirror of
https://github.com/Spythere/srjp-td2.git
synced 2026-05-03 05:28:12 +00:00
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "srjp-td2",
|
"name": "srjp-td2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --mode staging",
|
"dev": "vite --mode staging",
|
||||||
|
|||||||
@@ -285,7 +285,7 @@
|
|||||||
<table class="h-full w-full border-collapse">
|
<table class="h-full w-full border-collapse">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="border-b-[1px] border-b-black dark:border-b-white">
|
<tr class="border-b-[1px] border-b-black dark:border-b-white">
|
||||||
<td>{{ row.stockMass }}</td>
|
<td>{{ Math.floor(row.stockMass / 1000) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ row.stockLength }}</td>
|
<td>{{ row.stockLength }}</td>
|
||||||
@@ -305,6 +305,28 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div class="mt-2">
|
||||||
|
<b><u>Kursuje:</u></b>
|
||||||
|
<div>
|
||||||
|
- {{ parseTimetableRunDate(computedTimetableRows[0].scheduledDepartureDate!) }}
|
||||||
|
<span
|
||||||
|
v-if="computedTimetableRows[computedTimetableRows.length - 1].scheduledArrivalDate!.getDate() != computedTimetableRows[0].scheduledDepartureDate!.getDate()"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
{{
|
||||||
|
parseTimetableRunDate(
|
||||||
|
computedTimetableRows[computedTimetableRows.length - 1].scheduledArrivalDate!
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="timetableWarnings.length != 0">
|
||||||
|
<b><u>Uwagi do rozkładu:</u></b>
|
||||||
|
<div>- {{ timetableWarnings }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -313,6 +335,7 @@ import { computed } from 'vue';
|
|||||||
import { useApiStore } from '../../stores/api.store';
|
import { useApiStore } from '../../stores/api.store';
|
||||||
import { useGlobalStore } from '../../stores/global.store';
|
import { useGlobalStore } from '../../stores/global.store';
|
||||||
import type { SceneryRoute, StopRow, TimetablePathData } from '../../types/common.types';
|
import type { SceneryRoute, StopRow, TimetablePathData } from '../../types/common.types';
|
||||||
|
import { parseTimetableRunDate } from '../../utils/dateUtils';
|
||||||
|
|
||||||
const globalStore = useGlobalStore();
|
const globalStore = useGlobalStore();
|
||||||
const apiStore = useApiStore();
|
const apiStore = useApiStore();
|
||||||
@@ -320,6 +343,14 @@ const apiStore = useApiStore();
|
|||||||
// Tymczasowa tabelka z posterunkami APO
|
// Tymczasowa tabelka z posterunkami APO
|
||||||
const apoNames = ['Stary Kisielin, pe', 'Czerwony Dwór, pe', 'Szczejkowice, pe'];
|
const apoNames = ['Stary Kisielin, pe', 'Czerwony Dwór, pe', 'Szczejkowice, pe'];
|
||||||
|
|
||||||
|
const timetableWarnings = computed(() => {
|
||||||
|
const timetableData = globalStore.currentTimetableData;
|
||||||
|
|
||||||
|
if (!timetableData) return '';
|
||||||
|
|
||||||
|
return timetableData.warningNotes;
|
||||||
|
});
|
||||||
|
|
||||||
const computedTimetableRows = computed(() => {
|
const computedTimetableRows = computed(() => {
|
||||||
const timetableData = globalStore.currentTimetableData;
|
const timetableData = globalStore.currentTimetableData;
|
||||||
|
|
||||||
@@ -328,7 +359,7 @@ const computedTimetableRows = computed(() => {
|
|||||||
let timeFrom = Date.now();
|
let timeFrom = Date.now();
|
||||||
|
|
||||||
const stockVmax = timetableData.trainMaxSpeed,
|
const stockVmax = timetableData.trainMaxSpeed,
|
||||||
stockMass = Math.floor(timetableData.mass / 1000),
|
stockMass = timetableData.mass,
|
||||||
stockLength = timetableData.length;
|
stockLength = timetableData.length;
|
||||||
|
|
||||||
const timetablePath = parseTimetablePath(timetableData.path);
|
const timetablePath = parseTimetablePath(timetableData.path);
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { useApiStore } from '../stores/api.store';
|
||||||
|
|
||||||
|
export function useVehicleMixin() {
|
||||||
|
const apiStore = useApiStore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets loco load (obc. lok.) in tons - effectively train mass without locomotive or lone locomotive / unit mass
|
||||||
|
*/
|
||||||
|
function getLocoLoad(trainMass: number, stockString: string) {
|
||||||
|
if (!apiStore.vehiclesData) return trainMass;
|
||||||
|
|
||||||
|
const stockArray = stockString.split(';');
|
||||||
|
const headUnitsNames = stockArray.slice(0, 3).filter((v) => /-\d{3,}$/.test(v));
|
||||||
|
|
||||||
|
if (headUnitsNames.length == 1 && stockArray.length == 1) return trainMass;
|
||||||
|
|
||||||
|
const headVehicleData = apiStore.vehiclesData.find((v) => v.name == headUnitsNames[0]);
|
||||||
|
|
||||||
|
if (!headVehicleData) return trainMass;
|
||||||
|
|
||||||
|
return Math.min(trainMass, trainMass - headVehicleData.group.weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { getLocoLoad };
|
||||||
|
}
|
||||||
+21
-2
@@ -4,9 +4,15 @@ import { defineStore } from 'pinia';
|
|||||||
import {
|
import {
|
||||||
DataStatus,
|
DataStatus,
|
||||||
type ActiveDataResponse,
|
type ActiveDataResponse,
|
||||||
type SceneriesDataResponse
|
type SceneriesDataResponse,
|
||||||
|
type VehiclesDataResponse
|
||||||
} from '../types/api.types';
|
} from '../types/api.types';
|
||||||
import type { ActiveData, JournalTimetableShort, SceneryData } from '../types/common.types';
|
import type {
|
||||||
|
ActiveData,
|
||||||
|
JournalTimetableShort,
|
||||||
|
SceneryData,
|
||||||
|
VehicleData
|
||||||
|
} from '../types/common.types';
|
||||||
|
|
||||||
let activeDataInterval = -1;
|
let activeDataInterval = -1;
|
||||||
|
|
||||||
@@ -17,6 +23,7 @@ export const useApiStore = defineStore('api', {
|
|||||||
|
|
||||||
activeData: null as ActiveData | null,
|
activeData: null as ActiveData | null,
|
||||||
sceneryData: null as SceneryData[] | null,
|
sceneryData: null as SceneryData[] | null,
|
||||||
|
vehiclesData: null as VehicleData[] | null,
|
||||||
journalTimetablesData: null as JournalTimetableShort[] | null,
|
journalTimetablesData: null as JournalTimetableShort[] | null,
|
||||||
|
|
||||||
outdatedTimerId: -1,
|
outdatedTimerId: -1,
|
||||||
@@ -57,6 +64,8 @@ export const useApiStore = defineStore('api', {
|
|||||||
}, 25000);
|
}, 25000);
|
||||||
|
|
||||||
this.fetchSceneriesData();
|
this.fetchSceneriesData();
|
||||||
|
this.fetchVehiclesData();
|
||||||
|
|
||||||
await this.fetchActiveData();
|
await this.fetchActiveData();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -86,6 +95,16 @@ export const useApiStore = defineStore('api', {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchVehiclesData() {
|
||||||
|
try {
|
||||||
|
const response = (await this.client!.get<VehiclesDataResponse>('/api/getVehicles')).data;
|
||||||
|
|
||||||
|
this.vehiclesData = response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import type {
|
|||||||
ViewMode
|
ViewMode
|
||||||
} from '../types/common.types';
|
} from '../types/common.types';
|
||||||
import { getHeadUnits } from '../utils/trainUtils';
|
import { getHeadUnits } from '../utils/trainUtils';
|
||||||
|
import { useVehicleMixin } from '../mixins/useVehicleMixin';
|
||||||
|
|
||||||
export const useGlobalStore = defineStore('global', {
|
export const useGlobalStore = defineStore('global', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@@ -48,6 +49,8 @@ export const useGlobalStore = defineStore('global', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
currentTimetableData(): TimetableData | null {
|
currentTimetableData(): TimetableData | null {
|
||||||
|
const vehicleUtils = useVehicleMixin();
|
||||||
|
|
||||||
if (this.viewMode == 'active') {
|
if (this.viewMode == 'active') {
|
||||||
const selectedTrain = this.selectedActiveTrain;
|
const selectedTrain = this.selectedActiveTrain;
|
||||||
|
|
||||||
@@ -55,7 +58,7 @@ export const useGlobalStore = defineStore('global', {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
trainNo: selectedTrain.trainNo,
|
trainNo: selectedTrain.trainNo,
|
||||||
mass: selectedTrain.mass,
|
mass: vehicleUtils.getLocoLoad(selectedTrain.mass, selectedTrain.stockString),
|
||||||
length: selectedTrain.length,
|
length: selectedTrain.length,
|
||||||
driverId: selectedTrain.driverId,
|
driverId: selectedTrain.driverId,
|
||||||
driverName: selectedTrain.driverName,
|
driverName: selectedTrain.driverName,
|
||||||
@@ -88,7 +91,10 @@ export const useGlobalStore = defineStore('global', {
|
|||||||
return {
|
return {
|
||||||
journalCreatedAt: new Date(selectedTimetable.createdAt).getTime(),
|
journalCreatedAt: new Date(selectedTimetable.createdAt).getTime(),
|
||||||
trainNo: selectedTimetable.trainNo,
|
trainNo: selectedTimetable.trainNo,
|
||||||
mass: selectedTimetable.stockMass,
|
mass: vehicleUtils.getLocoLoad(
|
||||||
|
selectedTimetable.stockMass,
|
||||||
|
selectedTimetable.stockString
|
||||||
|
),
|
||||||
length: selectedTimetable.stockLength,
|
length: selectedTimetable.stockLength,
|
||||||
driverId: selectedTimetable.driverId,
|
driverId: selectedTimetable.driverId,
|
||||||
driverName: selectedTimetable.driverName,
|
driverName: selectedTimetable.driverName,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ActiveData, JournalTimetableShort, SceneryData } from './common.types';
|
import type { ActiveData, JournalTimetableShort, SceneryData, VehicleData } from './common.types';
|
||||||
|
|
||||||
export type ActiveDataResponse = ActiveData;
|
export type ActiveDataResponse = ActiveData;
|
||||||
|
|
||||||
@@ -6,9 +6,11 @@ export type SceneriesDataResponse = SceneryData[];
|
|||||||
|
|
||||||
export type JournalTimetablesShortResponse = JournalTimetableShort[];
|
export type JournalTimetablesShortResponse = JournalTimetableShort[];
|
||||||
|
|
||||||
|
export type VehiclesDataResponse = VehicleData[];
|
||||||
|
|
||||||
export enum DataStatus {
|
export enum DataStatus {
|
||||||
'INIT' = -1,
|
'INIT' = -1,
|
||||||
'LOADING' = 0,
|
'LOADING' = 0,
|
||||||
'SUCCESS' = 1,
|
'SUCCESS' = 1,
|
||||||
'ERROR' = 2,
|
'ERROR' = 2
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,3 +286,47 @@ export interface TimetableData {
|
|||||||
savedTimestamp?: number;
|
savedTimestamp?: number;
|
||||||
journalCreatedAt?: number;
|
journalCreatedAt?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface VehicleData {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
group: VehicleGroup;
|
||||||
|
cabinName?: string;
|
||||||
|
restrictions?: VehicleRestrictions;
|
||||||
|
simulatorVersion: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VehicleRestrictions {
|
||||||
|
sponsorOnly?: number;
|
||||||
|
teamOnly?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VehicleGroup {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
speed: number;
|
||||||
|
speedLoaded?: number;
|
||||||
|
speedLoco?: number;
|
||||||
|
length: number;
|
||||||
|
weight: number;
|
||||||
|
cargoTypes?: VehicleCargoType[];
|
||||||
|
locoProps?: VehicleLocoProps;
|
||||||
|
massSpeeds?: VehicleMassSpeeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VehicleCargoType {
|
||||||
|
id: string;
|
||||||
|
weight: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VehicleLocoProps {
|
||||||
|
coldStart: boolean;
|
||||||
|
doubleManned: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VehicleMassSpeeds {
|
||||||
|
none: number;
|
||||||
|
cargo?: Record<string, number>;
|
||||||
|
passenger?: Record<string, number>;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
const romanMonthDigits = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII'];
|
||||||
|
|
||||||
|
export function parseTimetableRunDate(date: Date) {
|
||||||
|
return `${date.getDate()}.${romanMonthDigits[date.getMonth()]}.${date
|
||||||
|
.getFullYear()
|
||||||
|
.toString()
|
||||||
|
.slice(2)}`;
|
||||||
|
}
|
||||||
+4
-1
@@ -14,9 +14,12 @@ export default defineConfig({
|
|||||||
cleanupOutdatedCaches: true,
|
cleanupOutdatedCaches: true,
|
||||||
runtimeCaching: [
|
runtimeCaching: [
|
||||||
{
|
{
|
||||||
urlPattern: /^https:\/\/stacjownik.spythere.eu\/api\/getSceneries/i,
|
urlPattern: /^https:\/\/stacjownik.spythere.eu\/api\/(getSceneries|getVehicles)/i,
|
||||||
handler: 'NetworkFirst',
|
handler: 'NetworkFirst',
|
||||||
options: {
|
options: {
|
||||||
|
expiration: {
|
||||||
|
maxAgeSeconds: 3600
|
||||||
|
},
|
||||||
cacheName: 'stacjownik-api-cache',
|
cacheName: 'stacjownik-api-cache',
|
||||||
cacheableResponse: { statuses: [0, 200] }
|
cacheableResponse: { statuses: [0, 200] }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user