Диспетчер

Карта в реальном времени
{{ mapCounters.waiting }}
Ожидают
{{ mapCounters.inProgress }}
В работе
{{ mapCounters.online }}
Онлайн
{{ mapCounters.gpsStale }}
GPS устарел
Стиль карты
{{ s.name }}
Курьер свободен Курьер занят Ресторан Точка доставки

Все заказы

#{{ order.orderDetails.uniqNum }}
{{ orderRiskLabel(order) }} {{ getOrderStatusLabel(order.status) }}
{{ order.orderDetails.cafeName }}
{{ order.orderDetails.customerFullName }}
Готов на кухне в {{ new Date(order.readyAt).toLocaleTimeString('ru-RU', {hour: '2-digit', minute:'2-digit'}) }}
ждёт {{ getPendingMinutes(order.placedAt || order.createdAt) }} мин
{{ formatDateTime(order.createdAt) }}
оповещено: {{ order.notifiedCouriersCount }}
Нет заказов по выбранному фильтру

Персонал

Сортировка
CSV
Загрузка…
Нет данных за выбранный период.
{{ idx + 1 }}. {{ row.name }}
Принятие {{ row.acceptanceRate != null ? Math.round(row.acceptanceRate*100) + '%' : '—' }} В срок {{ row.onTimeRate != null ? Math.round(row.onTimeRate*100) + '%' : '—' }}
Завершил {{ row.completed }} · отмен {{ row.canceled }} · отказов {{ row.refused }}
{{ row[perfSortBy === 'earnings' ? 'earnings' : perfSortBy === 'canceled' ? 'canceled' : 'completed'] }}
~{{ row.avgDeliveryMin }} мин
{{ c.name }}
{{ c.phone }} · {{ c.city }}
В работе {{ c.activeOrderIds.length }} · сегодня {{ c.completedToday || 0 }}
GPS: {{ formatRelativeTime(c.location.lastUpdated) }}
Нет курьеров

Смены курьеров

Нет смен в этом фильтре

Шаблоны смен

Шаблоны автоматически генерируют смены на N дней вперёд каждые 10 минут.
{{ tpl.courierName }} · {{ tpl.startLocal }}–{{ tpl.endLocal }} · {{ tpl.price }} ₽
{{ formatDaysOfWeek(tpl.daysOfWeek) }} · горизонт {{ tpl.horizonDays }} дн{{ tpl.enabled ? '' : ' · ВЫКЛ' }}

Рестораны

Время приготовления нужно диспетчеру, чтобы не отправлять курьеров слишком рано.
{{ cafe.name }}
ID {{ cafe.cafeId }}
мин
Обучено: {{ { high: 'высокое', medium: 'среднее', low: 'низкое' }[cafe.learning_status.confidence] || '—' }} · по факту {{ cafe.prepTimeP50 || '—' }}/{{ cafe.prepTimeP90 || '—' }} мин (медиана/90%) · {{ cafe.learning_status.total_samples || 0 }} заказов, {{ cafe.learning_status.hours_covered || 0 }} ч охвата · обновлено {{ formatTimeAgo(cafe.learning_status.last_updated_at) }}
Приоритет (0–10)
Буфер забора
мин
Ручная корректировка модели
Эти значения модель подбирает сама по фактическим временам приготовления. Меняйте только если уверены.
Рестораны появятся здесь после первых заказов

Аналитика

{{ formattedAnalyticsDate }}
Выручка за {{ periodCompareDays }} дн {{ formatDelta(periodCompare.deltas.revenue) }}
{{ formatMoney(periodCompare.current.revenue) }}
было {{ formatMoney(periodCompare.previous.revenue) }}
Загрузка…
Заказы
{{ periodCompare.current.total }}
{{ formatDelta(periodCompare.deltas.total) }}
было {{ periodCompare.previous.total }}
Завершено
{{ periodCompare.current.completed }}
{{ formatDelta(periodCompare.deltas.completed) }}
было {{ periodCompare.previous.completed }}
Ср. время
{{ periodCompare.current.avgDeliveryMin ?? '—' }} мин
{{ formatDelta(periodCompare.deltas.avgDeliveryMin) }}
было {{ periodCompare.previous.avgDeliveryMin ?? '—' }} мин
Сумма заказов
{{ adminStats.global.revenueToday.toLocaleString() }}
Зараб. курьеров
{{ adminStats.global.deliveryToday.toLocaleString() }}
Активные курьеры
{{ adminStats.global.activeCouriers }}
Всего заказов
{{ adminStats.global.totalOrdersToday }}
Ср. доставка
{{ adminStats.global.avgDeliveryTime }} мин
Ср. дистанция кафе → клиент (30 дн)
{{ adminStats.avgRestaurantToClient.avgKm }} км

Заказы по часам

Статусы заказов

Топ ресторанов

Нет данных
{{ idx + 1 }}
{{ rest._id || 'Неизвестно' }}
{{ rest.count }} зак.

Drilldown

Всего заказов {{ analyticsDrilldown.metrics.totalOrders || 0 }}
Активные {{ analyticsDrilldown.metrics.activeOrders || 0 }}
Завершены {{ analyticsDrilldown.metrics.finishedOrders || 0 }}
Отменены {{ analyticsDrilldown.metrics.canceledOrders || 0 }}

Тепловая карта спрос/курьеры/дефицит

Кастомная статистика
Выполнено заказов
{{ adminCustomResult.count }}
Заработано
{{ adminCustomResult.earnings }} ₽
Список заказов
#{{ order.orderDetails.uniqNum }} +{{ order.orderDetails.deliveryPrice }} ₽
{{ formatDateTime(order.finishedAt) }}
{{ order.orderDetails.cafeName }}
Заказов нет.
PDF-отчёт по ресторану

Формируем отчет...

Бот скоро пришлет файл в чат 📄

Финансы

Период (месяц)
Чистая прибыль
{{ finStats.financials.netProfit.toLocaleString() }} ₽
доход − расходы

Детализация

Выручка (10%) {{ finStats.financials.totalRevenue.toLocaleString() }} ₽
Фиксированные расходы −{{ finStats.financials.fixedCosts.toLocaleString() }} ₽
Доплаты курьерам −{{ finStats.financials.courierSubsidies.toLocaleString() }} ₽
Итого расходы {{ finStats.financials.totalExpenses.toLocaleString() }} ₽

Точка безубыточности

Сколько заказов в день нужно, чтобы выйти в плюс
{{ finStats.analytics.neededOrdersPerDay }}
в день, сейчас {{ finStats.analytics.currentOrdersPerDay }}
(Фикс + доплаты) / средний доход с заказа ({{ finStats.analytics.avgRevenuePerOrder }} ₽)

Структура расходов

Загрузка…
Прогноз cash flow
Загрузка...
7 дней (прогноз)
{{ formatMoney(cashflow.summary.next7Net) }}
14 дней (прогноз)
{{ formatMoney(cashflow.summary.next14Net) }}

Прогноз по дням

{{ d.date.slice(5) }}

Откуда минус (среднее за 14 дн)

Комиссия от заказов (вход)
+{{ formatMoney(cashflow.drilldown.avgDailyCommissionIncome) }}
Выплаты курьерам
−{{ formatMoney(cashflow.drilldown.avgDailyCourierPayout) }}
Цена смен
−{{ formatMoney(cashflow.drilldown.avgDailyShiftPay) }}
Постоянные расходы (в день)
−{{ formatMoney(cashflow.drilldown.dailyFixedCostsAllocation) }}
Net в день
{{ formatMoney(cashflow.drilldown.avgDailyCommissionIncome - cashflow.drilldown.avgDailyCourierPayout - cashflow.drilldown.avgDailyShiftPay - cashflow.drilldown.dailyFixedCostsAllocation) }}
Прогноз построен на основе средних за последние 14 дней. Не учитывает сезонность и манипуляции с тарифами.
Нажмите «Обновить» для загрузки прогноза.
P&L (по данным)
Чистая прибыль
{{ Math.round(pnlData.net).toLocaleString('ru-RU') }} ₽
{{ pnlData.orders }} заказов · GMV {{ Math.round(pnlData.gmv).toLocaleString('ru-RU') }} ₽ · {{ pnlData.days }} дн
Комиссия ({{ (pnlData.assumptions.commissionRate * 100).toFixed(0) }}%)+{{ Math.round(pnlData.revenue.commission).toLocaleString('ru-RU') }} ₽
Доставка (от клиента)+{{ Math.round(pnlData.revenue.deliveryFees).toLocaleString('ru-RU') }} ₽
Итого доход+{{ Math.round(pnlData.revenue.total).toLocaleString('ru-RU') }} ₽
Курьеры (макс из факта/гарантии)−{{ Math.round(pnlData.costs.courier).toLocaleString('ru-RU') }} ₽
Эквайринг ({{ (pnlData.assumptions.acquiringFeeRate * 100).toFixed(1) }}%)−{{ Math.round(pnlData.costs.acquiring).toLocaleString('ru-RU') }} ₽
Фикс. расходы (пропорция)−{{ Math.round(pnlData.costs.fixed).toLocaleString('ru-RU') }} ₽
Итого расходы−{{ Math.round(pnlData.costs.total).toLocaleString('ru-RU') }} ₽
Смены: {{ pnlData.shifts.count }} (оплачено {{ pnlData.shifts.paid }}, к выплате {{ pnlData.shifts.unpaid }} = {{ Math.round(pnlData.shifts.unpaidAmount).toLocaleString('ru-RU') }} ₽)

Настройки

Ценообразование доставки
Базовая стоимость
Фиксированная плата независимо от расстояния
Бесплатный радиус
Дистанция, за которую доп. плата не берётся
км
Цена за километр
Доп. плата за каждый км сверх бесплатного радиуса
₽/км
Правила диспетчеризации
Размер волны
Макс. курьеров, оповещаемых за одну волну (dispatchWaveSize)
чел.
Макс. батч
Заказов в одном попутном рейсе (maxBatchSize)
шт.
Удлинение маршрута
На сколько допустимо удлинить маршрут при батчинге
мин
Задержка SLA
Предел задержки уже назначенного заказа при добавлении попутного
мин
Время еды в пути
Максимум от забора еды до доставки клиенту
мин
GPS считается старым
Через сколько секунд без апдейта GPS курьер считается устаревшим
сек
Cooldown уведомлений
Мин. интервал между повторными пушами одному курьеру
сек
Cooldown повтора
Пауза перед повторной попыткой назначить нераспределённый заказ
сек
Параметры курьеров
Одновременные заказы
Сколько активных заказов курьер ведёт параллельно
шт.
Напоминание о смене
За сколько минут до начала смены бот пинганёт курьера
мин
Длительность перерыва
Стандартное время паузы (курьер уходит с радара)
мин
Вместимость
Слотов у курьера по умолчанию (если не задано индивидуально)
слотов
Финансы и часовой пояс
Часовой пояс
Например, Europe/Moscow. Влияет на отчёты и аналитику
Комиссия сервиса
Доля от суммы заказа в выручку (0.1 = 10%)
Гарантия курьера
Минимум за смену; недобор доплачивается
₽/смена
Аренда сервера
Хостинг и инфраструктура
₽/мес
Бухгалтерия
Бухгалтерское сопровождение
₽/мес
Карты / OSRM
Картографический сервис и маршрутизация
₽/мес
Страховка
Ответственность и груз
₽/мес
Уведомления
Пуш админам
Слать админам уведомление о каждом новом заказе
Шаблон предложения курьеру
Текст при предложении нового заказа
Шаблон назначения курьеру
Текст при жёстком назначении заказа
Шаблон сводки диспетчера
Итоговая сводка смены
Системное
Admin token
Сбросьте, если сервер отклоняет запросы или нужно перелогиниться

Пользователи

Период
Сортировка
С
По
Загрузка...
👥
Нет данных за выбранный период
{{ u.customerFullName || maskPhone(u.phone) }} Постоянный
{{ maskPhone(u.phone) }}
{{ u.orderCount }} заказов
Выручка: {{ (u.totalRevenue || 0).toLocaleString('ru-RU') }} ₽
Чек: {{ u.avgOrderValue ? Math.round(u.avgOrderValue).toLocaleString('ru-RU') + ' ₽' : '—' }}
Последний: {{ formatUserLastOrder(u.lastOrderAt, u.daysSinceLast) }}
Первый заказ: {{ u.firstOrderAt ? formatDateTime(u.firstOrderAt).slice(0,10) : '—' }} | {{ u.cityKeys.join(', ') }}
Любимые рестораны: {{ c.name || c.cafeId }} ×{{ c.count }}
Часы заказов: {{ formatHourBucket(h.hour) }} ×{{ h.count }}
Дни недели: {{ formatWeekday(w.weekday) }} ×{{ w.count }}
Показано {{ usersList.length }} из {{ usersPagination.total }}

Прогноз

Расчёт прогноза...
📊
Недостаточно данных
Прогноз появится после 28 дней работы сервиса.
Ожидаемое число заказов
{{ day.expected !== null ? day.expected : '?' }}
{{ forecastDayOfWeek(day.date) }}
{{ forecastShortDate(day.date) }}
{{ forecastShortDate(forecastData[forecastActiveDay].date) }} — по часам
0:006:0012:0018:0023:00
Почасовой прогноз недоступен для этого дня
Прогноз строится по последним 4 одинаковым дням недели + тренд за 14 дней. Минимум 28 дней истории. Обновлён: {{ formatDateTime(forecastGeneratedAt) }}.

SLA-инбокс

Загрузка...
Алёртов нет — всё в порядке.
{{ alert.message }}
{{ alert.orderId }} {{ alert.courierName }} {{ alert.cafe }} {{ alert.ageMin }} мин +{{ alert.overdueMin }} мин {{ Math.round(alert.ageSec/60) }} мин
Обновлено: {{ formatDateTime(slaGeneratedAt) }}

Журнал действий

CSV
Загрузка...
Журнал пуст.
{{ formatDateTime(item.createdAt) }} · {{ item.statusCode }}
{{ item.action }}
{{ item.actor?.role || 'unknown' }}#{{ item.actor.userId }} · {{ item.resource.type }}/{{ item.resource.id }}
{{ JSON.stringify(item.payload, null, 2) }}
Чат с {{ chatCourierName || ('курьер ' + chatCourierId) }}
Пока нет сообщений. Напишите курьеру — оно придёт ему в Telegram, ответ вернётся сюда.
Загрузка...
{{ m.text }}
{{ formatDateTime(m.createdAt) }}{{ m.fromRole === 'dispatcher' && m.deliveredAt ? ' • доставлено' : '' }}
Переназначить заказ #{{ reassignOrderId }}
Расчёт рекомендаций...
Нет подходящих курьеров.
{{ c.name }} текущий
ETA до кафе: {{ c.etaToPickupMin }} мин · +{{ c.addedRouteMin }} мин к маршруту · {{ c.distanceKm }} км
Активных заказов: {{ c.activeOrdersCount }}
Admin token
Значение переменной COURIER_ADMIN_TOKEN из .env бэкенда.
Не путать с ADMIN_TOKEN (это JWT для основного API).
Сохраним в браузере на этом устройстве.
{{ tokenInputError }}
Введите минимум 2 символа.
Ищу...
Ничего не найдено.

Батчинг

Не удалось загрузить статистику
{{ batchError }}

Ключевые метрики

Динамика заказов

Нет данных для графика

Топ-кафе по батчингу

Нет данных по кафе
Рассылка курьерам
Сообщение получат все активные курьеры (онлайн прямо сейчас).
{{ broadcastError }}
Настроить вкладки
Перетащите строки или используйте ↑↓ для изменения порядка. Нажмите иконку видимости чтобы скрыть вкладку.
{{ tab.emoji }} {{ tab.label }}

Новые заказы

{{ orders.length }} доступно
{{ banner.text }}
💤

Нет заказов

В вашем городе пока тишина.

{{ order.orderDetails.cafeName }}
+{{ order.orderDetails.deliveryPrice }} ₽
{{ badge }}
🏬
{{ order.orderDetails.cafeAddress.fullAddress }}
Забрать
👤
{{ order.orderDetails.address.fullAddress }}
Доставить
Посмотреть детали

В работе

{{ activeOrders.length }} шт.
GPS: {{ courierGeoStatus==='live' ? 'активен' : courierGeoStatus==='denied' ? 'нет доступа' : 'ожидание' }}
{{ banner.text }}
🚀

Пусто

У вас нет активных заказов.

{{ order.orderDetails.cafeName }}
{{ getOrderStatusLabel(order.status) }}
+{{ order.orderDetails.deliveryPrice }} ₽
🏬
{{ order.orderDetails.cafeAddress.fullAddress }}
👤
{{ order.orderDetails.address.fullAddress }}

Мой кошелёк

💰

Нет данных

За выбранный период доставок нет.

Доставок
{{ courierWallet.totalOrders }}
Оплата за доставки
{{ Math.round(courierWallet.totalDeliveryFees).toLocaleString('ru-RU') }} ₽
Гарантия по сменам
{{ Math.round(courierWallet.totalShiftPay).toLocaleString('ru-RU') }} ₽
Итого к оплате
{{ Math.round(courierWallet.effective).toLocaleString('ru-RU') }} ₽
По дням
{{ d.date }} {{ d.orders }} · {{ Math.round(d.deliveryFees).toLocaleString('ru-RU') }} ₽
Смены
{{ new Date(s.startTime).toLocaleDateString('ru-RU') }} {{ new Date(s.startTime).toLocaleTimeString('ru-RU',{hour:'2-digit',minute:'2-digit'}) }}–{{ new Date(s.endTime).toLocaleTimeString('ru-RU',{hour:'2-digit',minute:'2-digit'}) }} {{ Math.round(s.price).toLocaleString('ru-RU') }} ₽

Диспетчер

Чат с операторами
💬

Сообщений пока нет.

{{ m.fromName || (m.fromRole === 'courier' ? 'Вы' : 'Диспетчер') }} · {{ new Date(m.createdAt).toLocaleTimeString('ru-RU',{hour:'2-digit',minute:'2-digit'}) }}
{{ m.text }}

Профиль

{{ banner.text }}
🚴‍♂️

{{ courierName || 'Курьер' }}

{{ courierPhone || '+7...' }}

Текущая смена
До {{ new Date(shiftState.activeShift.endTime).toLocaleString('ru-RU') }}

Статистика

{{ stats.dayStats.earnings }} ₽
За сегодня
{{ stats.dayStats.count }}
Заказов сегодня
{{ stats.monthStats.earnings }} ₽
За месяц
{{ stats.monthStats.count }}
Заказов за месяц

☕ Вы на перерыве

{{ breakTimeLeft }}

Моя статистика (МСК)

Начало:
Конец:
Выполнено заказов: {{ courierCustomResult.count }}
Заработано: {{ courierCustomResult.earnings }} ₽