generated from VLADIMIR/template_frontend
update
This commit is contained in:
parent
a895c0f910
commit
aa8fe39310
@ -2,10 +2,10 @@
|
|||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { apiGetDays } from './client';
|
import { apiGetDays } from './client';
|
||||||
import type { Schedule } from './models';
|
import type { Schedule } from './models';
|
||||||
import { formatRussianDate, getRelativeDayName } from './date';
|
import { formatRussianDate, getRelativeDayName, timeAgo } from './date';
|
||||||
import { capitalizeFirstLetter } from './text';
|
import { capitalizeFirstLetter } from './text';
|
||||||
|
|
||||||
const schedule = ref<Schedule>({ days: [] })
|
const schedule = ref<Schedule>({ updateTime: "", days: [] })
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
schedule.value = await apiGetDays()
|
schedule.value = await apiGetDays()
|
||||||
@ -15,6 +15,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
Обновлено: {{ timeAgo(schedule.updateTime) }}
|
||||||
<div v-for="day in schedule.days" :key="day.date" class="day-block">
|
<div v-for="day in schedule.days" :key="day.date" class="day-block">
|
||||||
{{ capitalizeFirstLetter(formatRussianDate(day.date)) }}
|
{{ capitalizeFirstLetter(formatRussianDate(day.date)) }}
|
||||||
<span v-if="getRelativeDayName(day.date) !== ''">({{ getRelativeDayName(day.date) }})</span>
|
<span v-if="getRelativeDayName(day.date) !== ''">({{ getRelativeDayName(day.date) }})</span>
|
||||||
@ -53,7 +54,5 @@ onMounted(async () => {
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.performance-block {
|
.performance-block {}
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -73,3 +73,79 @@ export function getRelativeDayName(dateStr: string): string {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Функция для склонения слов (1 минута, 2 минуты, 5 минут)
|
||||||
|
*/
|
||||||
|
function getDeclension(number: number, titles: [string, string, string]): string {
|
||||||
|
const cases = [2, 0, 1, 1, 1, 2];
|
||||||
|
return titles[
|
||||||
|
(number % 100 > 4 && number % 100 < 20)
|
||||||
|
? 2
|
||||||
|
: cases[(number % 10 < 5) ? number % 10 : 5]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Основная функция форматирования времени
|
||||||
|
*/
|
||||||
|
export function timeAgo(goDateStr: string): string {
|
||||||
|
// 1. Парсим строку регуляркой, чтобы вытащить дату, время и смещение пояса.
|
||||||
|
// Игнорируем "m=+..." и доли секунд, так как для "5 минут назад" они не нужны.
|
||||||
|
// Группы: 1-Дата, 2-Время, 3-Часовой пояс (например +0700)
|
||||||
|
const regex = /^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})(?:\.\d+)? ([+-]\d{4})/;
|
||||||
|
const match = goDateStr.match(regex);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
console.error("Неверный формат даты:", goDateStr);
|
||||||
|
return goDateStr; // Возвращаем как есть в случае ошибки
|
||||||
|
}
|
||||||
|
|
||||||
|
const datePart = match[1];
|
||||||
|
const timePart = match[2];
|
||||||
|
const timezone = match[3];
|
||||||
|
|
||||||
|
// 2. Приводим к формату ISO 8601, который понимает любой браузер:
|
||||||
|
// "2026-03-26T12:11:18+0700"
|
||||||
|
const isoString = `${datePart}T${timePart}${timezone}`;
|
||||||
|
const date = new Date(isoString);
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// 3. Считаем разницу в секундах
|
||||||
|
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
|
||||||
|
|
||||||
|
// Если дата в будущем (например, как в вашем примере 2026 год)
|
||||||
|
if (seconds < 0) {
|
||||||
|
return "в будущем";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Логика интервалов
|
||||||
|
const minutes = Math.floor(seconds / 60);
|
||||||
|
const hours = Math.floor(minutes / 60);
|
||||||
|
const days = Math.floor(hours / 24);
|
||||||
|
|
||||||
|
if (seconds < 60) {
|
||||||
|
return "только что";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minutes < 60) {
|
||||||
|
return `${minutes} ${getDeclension(minutes, ['минуту', 'минуты', 'минут'])} назад`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hours < 24) {
|
||||||
|
return `${hours} ${getDeclension(hours, ['час', 'часа', 'часов'])} назад`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (days < 7) {
|
||||||
|
return `${days} ${getDeclension(days, ['день', 'дня', 'дней'])} назад`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если прошло больше недели, возвращаем просто дату
|
||||||
|
// Можно использовать Intl.DateTimeFormat для красоты
|
||||||
|
return date.toLocaleDateString("ru-RU", {
|
||||||
|
day: "numeric",
|
||||||
|
month: "long",
|
||||||
|
year: "numeric"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
export type Schedule = {
|
export type Schedule = {
|
||||||
|
updateTime: string
|
||||||
days: Day[]
|
days: Day[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user