auto-sync: 2026-04-25 01:40:01
This commit is contained in:
@@ -551,7 +551,8 @@ def schedule_data():
|
||||
"track_points": r.get("track_points"),
|
||||
"sched_source": r.get("sched_source"),
|
||||
# Эффективная длительность: FA > schedule
|
||||
"duration_eff": r.get("fa_flight_time") or r.get("duration_min"),
|
||||
# fa_flight_time — секунды (FR24), duration_min — минуты (Яндекс)
|
||||
"duration_eff": (lambda fa_ft: (int(fa_ft) // 60 if fa_ft else None) or r.get("duration_min"))(r.get("fa_flight_time")),
|
||||
# Маршрут из FR24 (IATA коды → города)
|
||||
"fa_origin_iata": r.get("fa_orig_iata"),
|
||||
"fa_dest_iata": r.get("fa_dest_iata"),
|
||||
|
||||
@@ -330,8 +330,7 @@
|
||||
<th>Маршрут</th>
|
||||
<th>Аэропорт</th>
|
||||
<th>По расп.</th>
|
||||
<th>Взлёт факт</th>
|
||||
<th>Посадка факт</th>
|
||||
<th>Фактическое</th>
|
||||
<th>Длит.</th>
|
||||
<th>ВПП</th>
|
||||
<th>ВС</th>
|
||||
@@ -339,7 +338,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="table-body">
|
||||
<tr><td colspan="13" class="state-msg">Загрузка…</td></tr>
|
||||
<tr><td colspan="12" class="state-msg">Загрузка…</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -107,7 +107,7 @@ async function loadData() {
|
||||
function renderTable(flights) {
|
||||
const tbody = document.getElementById("table-body");
|
||||
if (!flights.length) {
|
||||
tbody.innerHTML = `<tr><td colspan="13" class="state-msg">Нет данных по выбранным фильтрам</td></tr>`;
|
||||
tbody.innerHTML = `<tr><td colspan="12" class="state-msg">Нет данных по выбранным фильтрам</td></tr>`;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -140,23 +140,20 @@ function renderTable(flights) {
|
||||
// 7. По расписанию (MSK)
|
||||
const sched = fmtTime(f.scheduled_at);
|
||||
|
||||
// 8. Взлёт факт + задержка
|
||||
const actTakeoffCell = f.actual_takeoff
|
||||
? `<span class="act-time">${fmtTime(f.actual_takeoff)}</span> ${delayCell(f.delay_takeoff_min)}`
|
||||
// 8. Фактическое время: вылет → actual_takeoff, прилёт → actual_landed
|
||||
const actTime = f.direction === "departure" ? f.actual_takeoff : f.actual_landed;
|
||||
const actDelay = f.direction === "departure" ? f.delay_takeoff_min : f.delay_landed_min;
|
||||
const actCell = actTime
|
||||
? `<span class="act-time">${fmtTime(actTime)}</span> ${delayCell(actDelay)}`
|
||||
: "—";
|
||||
|
||||
// 9. Посадка факт
|
||||
const actLandedCell = f.actual_landed
|
||||
? `<span class="act-time">${fmtTime(f.actual_landed)}</span> ${delayCell(f.delay_landed_min)}`
|
||||
: "—";
|
||||
|
||||
// 10. Длительность (FA flight_time > schedule duration_min)
|
||||
// 9. Длительность (FA flight_time > schedule duration_min)
|
||||
const durationCell = fmtDuration(f.duration_eff);
|
||||
|
||||
// 11. ВПП
|
||||
const runway = (f.runway_takeoff || f.runway_landed)
|
||||
? `${f.runway_takeoff || "?"}→${f.runway_landed || "?"}`
|
||||
: "—";
|
||||
// 11. ВПП (по направлению рейса)
|
||||
const runway = f.direction === "departure"
|
||||
? (f.runway_takeoff || "—")
|
||||
: (f.runway_landed || "—");
|
||||
|
||||
// 12. Тип ВС
|
||||
const acType = f.aircraft_type ? esc(f.aircraft_type) : "—";
|
||||
@@ -182,8 +179,7 @@ function renderTable(flights) {
|
||||
<td>${esc(route)}</td>
|
||||
<td>${airport}</td>
|
||||
<td>${sched}</td>
|
||||
<td>${actTakeoffCell}</td>
|
||||
<td>${actLandedCell}</td>
|
||||
<td>${actCell}</td>
|
||||
<td>${durationCell}</td>
|
||||
<td>${runway}</td>
|
||||
<td>${acType}</td>
|
||||
@@ -229,9 +225,9 @@ function renderCards(flights) {
|
||||
f.registration ? `<span style="color:#6e7681">${esc(f.registration)}</span>` : "",
|
||||
].filter(Boolean).join(" / ");
|
||||
|
||||
const runway = (f.runway_takeoff || f.runway_landed)
|
||||
? `${f.runway_takeoff || "?"}→${f.runway_landed || "?"}`
|
||||
: "—";
|
||||
const runway = f.direction === "departure"
|
||||
? (f.runway_takeoff || "—")
|
||||
: (f.runway_landed || "—");
|
||||
|
||||
return `<div class="card">
|
||||
<div class="card-header">
|
||||
@@ -353,7 +349,7 @@ function esc(s) {
|
||||
function setLoading(on) {
|
||||
if (on) {
|
||||
document.getElementById("table-body").innerHTML =
|
||||
`<tr><td colspan="13" class="state-msg">Загрузка…</td></tr>`;
|
||||
`<tr><td colspan="12" class="state-msg">Загрузка…</td></tr>`;
|
||||
document.getElementById("cards-container").innerHTML =
|
||||
`<div class="state-msg">Загрузка…</div>`;
|
||||
}
|
||||
@@ -361,7 +357,7 @@ function setLoading(on) {
|
||||
|
||||
function showError(msg) {
|
||||
document.getElementById("table-body").innerHTML =
|
||||
`<tr><td colspan="13" class="state-msg" style="color:#f85149">Ошибка: ${esc(msg)}</td></tr>`;
|
||||
`<tr><td colspan="12" class="state-msg" style="color:#f85149">Ошибка: ${esc(msg)}</td></tr>`;
|
||||
document.getElementById("cards-container").innerHTML =
|
||||
`<div class="state-msg" style="color:#f85149">Ошибка: ${esc(msg)}</div>`;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# UI Schedule Fix — 2026-04-25
|
||||
|
||||
## Задача
|
||||
Три правки в UI расписания (schedule.js, schedule.html, main.py).
|
||||
|
||||
## Правки
|
||||
|
||||
### 1. duration_eff — единицы (main.py, строка 554–555)
|
||||
**Проблема:** `fa_flight_time` из FR24 — секунды, `duration_min` из Яндекса — минуты. Смешивались без конвертации.
|
||||
|
||||
**Было:**
|
||||
```python
|
||||
"duration_eff": r.get("fa_flight_time") or r.get("duration_min"),
|
||||
```
|
||||
|
||||
**Стало:**
|
||||
```python
|
||||
# fa_flight_time — секунды (FR24), duration_min — минуты (Яндекс)
|
||||
"duration_eff": (lambda fa_ft: (int(fa_ft) // 60 if fa_ft else None) or r.get("duration_min"))(r.get("fa_flight_time")),
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Колонки фактического времени (schedule.js + schedule.html)
|
||||
**Проблема:** Было 2 колонки «Взлёт факт» и «Посадка факт», показывались обе независимо от направления рейса.
|
||||
|
||||
**Стало:** 1 колонка «Фактическое» — для вылетов `actual_takeoff`, для прилётов `actual_landed`.
|
||||
|
||||
**schedule.js (renderTable):**
|
||||
```js
|
||||
const actTime = f.direction === "departure" ? f.actual_takeoff : f.actual_landed;
|
||||
const actDelay = f.direction === "departure" ? f.delay_takeoff_min : f.delay_landed_min;
|
||||
const actCell = actTime
|
||||
? `<span class="act-time">${fmtTime(actTime)}</span> ${delayCell(actDelay)}`
|
||||
: "—";
|
||||
```
|
||||
|
||||
**schedule.html:** Убрана колонка «Посадка факт», «Взлёт факт» → «Фактическое».
|
||||
|
||||
**Обновлено:** все `colspan="13"` → `colspan="12"` (schedule.js × 3, schedule.html × 1).
|
||||
|
||||
---
|
||||
|
||||
### 3. ВПП по направлению рейса (schedule.js)
|
||||
**Проблема:** Показывалось `runway_takeoff→runway_landed` вне зависимости от типа рейса.
|
||||
|
||||
**Стало:** только один runway по направлению.
|
||||
|
||||
**renderTable и renderCards:**
|
||||
```js
|
||||
const runway = f.direction === "departure"
|
||||
? (f.runway_takeoff || "—")
|
||||
: (f.runway_landed || "—");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Деплой
|
||||
- Файлы загружены на VM: `/home/fr24/projects/fr24/frontend/`
|
||||
- `docker cp` в контейнер `fr24-api`
|
||||
- `docker restart fr24-api` — успешно
|
||||
|
||||
## Статус
|
||||
✅ Все три правки применены и задеплоены.
|
||||
Reference in New Issue
Block a user