feat(external): фронт — плитка «Внешние сервисы» (баланс + живость)
Статус-текст для сервисов без денежного баланса (жив/не отвечает/выключено), метки и иконки почты/ЮKassa/Jivo/капчи, обновлённые подписи плитки и дрилла. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -103,11 +103,19 @@ const SERVICE_LABELS: Record<string, string> = {
|
||||
dadata: 'DaData',
|
||||
supplier: 'Поставщик',
|
||||
yandex_cloud: 'Yandex Cloud',
|
||||
email: 'Почта',
|
||||
yookassa: 'ЮKassa',
|
||||
jivosite: 'JivoSite',
|
||||
captcha: 'Капча',
|
||||
};
|
||||
const SERVICE_ICONS: Record<string, string> = {
|
||||
dadata: '🧭',
|
||||
supplier: '📦',
|
||||
yandex_cloud: '☁️',
|
||||
email: '✉️',
|
||||
yookassa: '💳',
|
||||
jivosite: '💬',
|
||||
captcha: '🛡',
|
||||
};
|
||||
|
||||
function serviceLabel(key: string): string {
|
||||
@@ -122,6 +130,17 @@ function daysLeftLabel(days: number | null): string {
|
||||
return days === null ? '—' : `~${days} дн.`;
|
||||
}
|
||||
|
||||
/** Значение в строке сервиса: деньги (если есть баланс) или статус живости. */
|
||||
function serviceValue(s: { balance_amount: string | null; light: string; ok: boolean }): string {
|
||||
if (s.balance_amount !== null) {
|
||||
return s.ok ? rub(s.balance_amount) : '—';
|
||||
}
|
||||
// Сервис без денег — показываем статус живости.
|
||||
if (s.light === 'green') return 'жив';
|
||||
if (s.light === 'red') return 'не отвечает';
|
||||
return 'выключено'; // grey
|
||||
}
|
||||
|
||||
/** Подпись светофора Клиентов на плитке. */
|
||||
function clientsLightLabel(): string {
|
||||
const d = summary.value?.clients.dormant ?? 0;
|
||||
@@ -542,7 +561,7 @@ defineExpose({ period, dateFrom, dateTo, showCustom, selected, summary, finance,
|
||||
<span
|
||||
class="num font-weight-bold"
|
||||
:class="{ 'text-error': s.light === 'red' }"
|
||||
>{{ s.ok ? rub(s.balance_amount) : 'нет данных' }}</span>
|
||||
>{{ serviceValue(s) }}</span>
|
||||
<v-icon :color="lightColor(s.light)" size="11" icon="mdi-circle" />
|
||||
</span>
|
||||
</div>
|
||||
@@ -870,12 +889,13 @@ v-for="g in supply?.groups ?? []" :key="g.signal_type + '|' + g.identifier"
|
||||
|
||||
<!-- DRILL: БАЛАНСЫ СЕРВИСОВ -->
|
||||
<v-card v-else-if="selected === 'balances'" variant="outlined" class="drill mt-5" data-testid="drill-balances">
|
||||
<v-card-title class="drill__head">💳 Балансы внешних сервисов — детали</v-card-title>
|
||||
<v-card-title class="drill__head">🌐 Внешние сервисы — баланс и доступность</v-card-title>
|
||||
<v-card-text>
|
||||
<v-alert variant="tonal" density="compact" class="mb-4" type="info">
|
||||
Баланс платных сервисов проверяется раз в сутки (06:30 МСК). Светофор: 🔴 мало денег
|
||||
или хватит меньше 3 дней, 🟡 меньше 7 дней, ⚪ не удалось обновить.
|
||||
Кнопка «Пополнить» открывает страницу оплаты сервиса.
|
||||
Внешние сервисы проверяются раз в сутки (06:30 МСК): у платных — остаток денег,
|
||||
у остальных — жив ли сервис. Светофор: 🔴 упал / мало денег / хватит меньше 3 дней,
|
||||
🟡 меньше 7 дней, ⚪ не удалось проверить или выключен. При переходе в 🔴 приходит
|
||||
письмо на ops-адрес.
|
||||
</v-alert>
|
||||
<v-table density="compact">
|
||||
<thead>
|
||||
@@ -891,9 +911,9 @@ v-for="g in supply?.groups ?? []" :key="g.signal_type + '|' + g.identifier"
|
||||
<tr v-for="s in balances?.services ?? []" :key="s.service_key">
|
||||
<td>{{ serviceIcon(s.service_key) }} {{ serviceLabel(s.service_key) }}</td>
|
||||
<td class="text-right num" :class="{ 'text-error': s.light === 'red' }">
|
||||
{{ s.ok ? rub(s.balance_amount) : '—' }}
|
||||
{{ serviceValue(s) }}
|
||||
</td>
|
||||
<td class="text-right num">{{ s.ok ? daysLeftLabel(s.days_left) : '—' }}</td>
|
||||
<td class="text-right num">{{ s.balance_amount !== null && s.ok ? daysLeftLabel(s.days_left) : '—' }}</td>
|
||||
<td class="text-center">
|
||||
<v-chip
|
||||
:color="lightColor(s.light)"
|
||||
|
||||
Reference in New Issue
Block a user