dfb41751c8
Task 3.3b — три экрана Фазы 1 показывают живой earned_rub вместо заглушки «—»: - «Мои клиенты»: колонка «Заработал» = комиссия по клиенту (или «—» без привязки). - Карточка клиента: KPI «Вы заработали (период)». - Сводка: KPI «Я заработал» = суммарная комиссия за период. Тип earned_rub расширен до number|null. Vitest-моки/ассерты обновлены под реальные значения. Фронт-набор 1052 зелёных, ESLint чист. Фаза 3 завершена: доход менеджера считается по тарифу каждого клиента и виден во всех экранах. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
623 lines
25 KiB
Vue
623 lines
25 KiB
Vue
<script setup lang="ts">
|
||
/**
|
||
* Портал продаж → Карточка клиента (Task 1.4).
|
||
*
|
||
* Отрисовывает полную карточку клиента по данным GET /api/sales/clients/{tenantId}.
|
||
* Реализует #page-client-card из v8_sales.html с Vuetify + Forest-палитрой.
|
||
*
|
||
* Данные: getSalesClientCard(tenantId, salesPeriod.queryParams)
|
||
* При смене периода данные перегружаются (watch queryParams).
|
||
* 403 → inline-сообщение «Этот клиент не закреплён за вами».
|
||
*/
|
||
import { onMounted, ref, watch } from 'vue';
|
||
import { useRoute, useRouter } from 'vue-router';
|
||
import axios from 'axios';
|
||
import { getSalesClientCard, type SalesClientCard } from '../../api/sales';
|
||
import { useSalesPeriodStore } from '../../stores/salesPeriod';
|
||
import HelpHint from '../../components/sales/HelpHint.vue';
|
||
|
||
// ─── props ────────────────────────────────────────────────────────────────────
|
||
|
||
// `props: true` in router passes route params as props
|
||
defineProps<{ id?: string }>();
|
||
|
||
const route = useRoute();
|
||
const router = useRouter();
|
||
const periodStore = useSalesPeriodStore();
|
||
|
||
// ─── state ────────────────────────────────────────────────────────────────────
|
||
|
||
const card = ref<SalesClientCard | null>(null);
|
||
const loading = ref(false);
|
||
const fetchError = ref<string | null>(null);
|
||
const is403 = ref(false);
|
||
|
||
// ─── formatters ───────────────────────────────────────────────────────────────
|
||
|
||
function fmtMoney(val: string | number | null | undefined): string {
|
||
if (val === null || val === undefined) return '—';
|
||
const n = typeof val === 'string' ? parseFloat(val) : val;
|
||
if (isNaN(n)) return '—';
|
||
return n.toLocaleString('ru-RU', { minimumFractionDigits: 0, maximumFractionDigits: 0 }) + ' ₽';
|
||
}
|
||
|
||
function fmtMoneyDecimal(val: number | null | undefined): string {
|
||
if (val === null || val === undefined) return '—';
|
||
if (isNaN(val)) return '—';
|
||
return val.toLocaleString('ru-RU', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' ₽';
|
||
}
|
||
|
||
function fmtDate(iso: string | null | undefined): string {
|
||
if (!iso) return '—';
|
||
const d = new Date(iso);
|
||
if (isNaN(d.getTime())) return iso;
|
||
const dd = String(d.getDate()).padStart(2, '0');
|
||
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
||
const yyyy = d.getFullYear();
|
||
return `${dd}.${mm}.${yyyy}`;
|
||
}
|
||
|
||
function fmtDateTime(iso: string | null | undefined): string {
|
||
if (!iso) return '—';
|
||
const d = new Date(iso);
|
||
if (isNaN(d.getTime())) return iso;
|
||
const dd = String(d.getDate()).padStart(2, '0');
|
||
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
||
const hh = String(d.getHours()).padStart(2, '0');
|
||
const min = String(d.getMinutes()).padStart(2, '0');
|
||
return `${dd}.${mm} ${hh}:${min}`;
|
||
}
|
||
|
||
function fmtActivity(iso: string | null | undefined): string {
|
||
if (!iso) return '—';
|
||
const d = new Date(iso);
|
||
if (isNaN(d.getTime())) return iso;
|
||
const now = new Date();
|
||
const diffMs = now.getTime() - d.getTime();
|
||
const diffMin = Math.floor(diffMs / 60000);
|
||
if (diffMin < 1) return 'только что';
|
||
if (diffMin < 60) return `${diffMin} мин назад`;
|
||
const diffH = Math.floor(diffMin / 60);
|
||
if (diffH < 24) return `${diffH} ч назад`;
|
||
const diffD = Math.floor(diffH / 24);
|
||
if (diffD < 7) return `${diffD} дн назад`;
|
||
return fmtDate(iso);
|
||
}
|
||
|
||
function fmtDayLabel(dateStr: string): string {
|
||
// YYYY-MM-DD → DD.MM
|
||
const parts = dateStr.split('-');
|
||
if (parts.length !== 3) return dateStr;
|
||
return `${parts[2]}.${parts[1]}`;
|
||
}
|
||
|
||
// ─── subject_type labels ──────────────────────────────────────────────────────
|
||
|
||
const SUBJECT_TYPE_LABELS: Record<string, string> = {
|
||
individual: 'Физическое лицо',
|
||
sole_proprietor: 'ИП',
|
||
legal_entity: 'Юридическое лицо',
|
||
};
|
||
|
||
function subjectLabel(type: string | null | undefined): string {
|
||
if (!type) return '—';
|
||
return SUBJECT_TYPE_LABELS[type] ?? type;
|
||
}
|
||
|
||
// ─── signal_type labels ───────────────────────────────────────────────────────
|
||
|
||
const SIGNAL_LABELS: Record<string, string> = {
|
||
site: 'Сайт',
|
||
call: 'Звонок',
|
||
sms: 'SMS',
|
||
};
|
||
|
||
function signalLabel(type: string): string {
|
||
return SIGNAL_LABELS[type] ?? type;
|
||
}
|
||
|
||
// ─── project status ───────────────────────────────────────────────────────────
|
||
|
||
function projectStatusColor(status: string): string {
|
||
return status === 'active' ? 'success' : 'grey';
|
||
}
|
||
|
||
function projectStatusLabel(status: string): string {
|
||
return status === 'active' ? 'Активен' : 'Пауза';
|
||
}
|
||
|
||
// ─── region formatting ────────────────────────────────────────────────────────
|
||
|
||
function fmtRegions(regions: string[]): string {
|
||
if (!regions || regions.length === 0) return '—';
|
||
if (regions.length <= 2) return regions.join(', ');
|
||
return `${regions[0]} + ${regions.length - 1}`;
|
||
}
|
||
|
||
// ─── data loading ─────────────────────────────────────────────────────────────
|
||
|
||
async function load() {
|
||
const tenantId = route.params.id as string;
|
||
if (!tenantId) return;
|
||
|
||
loading.value = true;
|
||
fetchError.value = null;
|
||
is403.value = false;
|
||
|
||
try {
|
||
card.value = await getSalesClientCard(tenantId, periodStore.queryParams);
|
||
} catch (err: unknown) {
|
||
if (axios.isAxiosError(err) && err.response?.status === 403) {
|
||
is403.value = true;
|
||
} else {
|
||
fetchError.value = 'Не удалось загрузить данные клиента. Попробуйте обновить страницу.';
|
||
}
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
}
|
||
|
||
// Reload when period changes
|
||
watch(() => periodStore.queryParams, load, { deep: true });
|
||
|
||
onMounted(load);
|
||
|
||
// ─── navigation ───────────────────────────────────────────────────────────────
|
||
|
||
function goBack() {
|
||
void router.push('/sales/clients');
|
||
}
|
||
|
||
defineExpose({ card, loading, fetchError, is403, load });
|
||
</script>
|
||
|
||
<template>
|
||
<v-container fluid class="scc-wrap pa-6">
|
||
<!-- Back link + Title -->
|
||
<div class="mb-4">
|
||
<div class="mb-2">
|
||
<a
|
||
class="scc-back"
|
||
role="button"
|
||
tabindex="0"
|
||
data-testid="back-link"
|
||
@click.prevent="goBack"
|
||
@keydown.enter.prevent="goBack"
|
||
>
|
||
← Мои клиенты
|
||
</a>
|
||
</div>
|
||
<h1 class="scc-page-title" data-testid="org-name">
|
||
{{ card?.profile.organization_name ?? '…' }}
|
||
</h1>
|
||
</div>
|
||
|
||
<!-- Loading bar -->
|
||
<v-progress-linear v-if="loading" indeterminate color="primary" class="mb-4" />
|
||
|
||
<!-- 403 error -->
|
||
<v-alert v-if="is403" type="warning" variant="tonal" density="compact" class="mb-4" data-testid="error-403">
|
||
Этот клиент не закреплён за вами.
|
||
</v-alert>
|
||
|
||
<!-- Generic error -->
|
||
<v-alert
|
||
v-else-if="fetchError"
|
||
type="warning"
|
||
variant="tonal"
|
||
density="compact"
|
||
closable
|
||
class="mb-4"
|
||
data-testid="error-generic"
|
||
>
|
||
{{ fetchError }}
|
||
</v-alert>
|
||
|
||
<!-- Content — only when card loaded -->
|
||
<template v-if="card">
|
||
<!-- KPI tiles -->
|
||
<div class="scc-kpi-row mb-6" data-testid="kpi-row">
|
||
<!-- Баланс -->
|
||
<div class="scc-kpi" data-testid="kpi-balance">
|
||
<div class="scc-k-label">Баланс клиента</div>
|
||
<div class="scc-k-val scc-accent scc-mono">{{ fmtMoney(card.kpi.balance_rub) }}</div>
|
||
<div class="scc-k-sub">
|
||
запас
|
||
{{
|
||
card.kpi.runway_days !== null && card.kpi.runway_days !== undefined
|
||
? `~${card.kpi.runway_days} дней`
|
||
: '—'
|
||
}}
|
||
<HelpHint text="На сколько дней хватит денег при текущем расходе на лиды" />
|
||
</div>
|
||
</div>
|
||
<!-- Проектов -->
|
||
<div class="scc-kpi" data-testid="kpi-projects">
|
||
<div class="scc-k-label">Проектов</div>
|
||
<div class="scc-k-val scc-mono">{{ card.kpi.projects_count }}</div>
|
||
<div class="scc-k-sub">
|
||
{{ card.projects.filter((p) => p.status === 'active').length }}
|
||
активных
|
||
</div>
|
||
</div>
|
||
<!-- Пришло / цель -->
|
||
<div class="scc-kpi" data-testid="kpi-leads">
|
||
<div class="scc-k-label">Пришло / цель (период)</div>
|
||
<div class="scc-k-val scc-mono">
|
||
{{ card.kpi.leads_delivered }}
|
||
<span class="scc-slash">/</span>
|
||
<span class="scc-accent">{{ card.kpi.leads_target }}</span>
|
||
</div>
|
||
<div class="scc-k-sub">доставлено за период</div>
|
||
</div>
|
||
<!-- Средняя цена лида -->
|
||
<div class="scc-kpi" data-testid="kpi-avg-price">
|
||
<div class="scc-k-label">
|
||
Средняя цена лида
|
||
<HelpHint text="Сколько в среднем стоит клиенту один лид за выбранный период" />
|
||
</div>
|
||
<div class="scc-k-val scc-mono">{{ fmtMoneyDecimal(card.kpi.avg_lead_price_rub) }}</div>
|
||
<div class="scc-k-sub">за период</div>
|
||
</div>
|
||
<!-- Заработано — комиссия менеджера с этого клиента за период -->
|
||
<div class="scc-kpi" data-testid="kpi-earned">
|
||
<div class="scc-k-label">
|
||
Вы заработали (период)
|
||
<HelpHint
|
||
text="Ваша комиссия с этого клиента за период — по тарифу, закреплённому за клиентом"
|
||
/>
|
||
</div>
|
||
<div class="scc-k-val scc-mono" data-testid="earned-value">
|
||
{{ fmtMoneyDecimal(card.kpi.earned_rub) }}
|
||
</div>
|
||
<div class="scc-k-sub">по тарифу клиента</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Two-column layout -->
|
||
<div class="scc-cols">
|
||
<!-- LEFT column -->
|
||
<div class="scc-col-main">
|
||
<!-- Projects table -->
|
||
<v-card variant="outlined" class="mb-4">
|
||
<div class="scc-section-head px-4 pt-4 pb-2">
|
||
<h2 class="scc-h2">Проекты клиента</h2>
|
||
</div>
|
||
<v-table density="compact" data-testid="projects-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Проект</th>
|
||
<th>Тип</th>
|
||
<th>Регион</th>
|
||
<th class="text-right scc-num">Лимит/день</th>
|
||
<th class="text-right scc-num">Пришло сегодня</th>
|
||
<th>Статус</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="proj in card.projects" :key="proj.id" data-testid="project-row">
|
||
<td class="scc-proj-name">{{ proj.name }}</td>
|
||
<td>
|
||
<span class="scc-signal-badge">{{ signalLabel(proj.signal_type) }}</span>
|
||
</td>
|
||
<td class="text-medium-emphasis">{{ fmtRegions(proj.region) }}</td>
|
||
<td class="text-right scc-num scc-mono">{{ proj.daily_limit_target }}</td>
|
||
<td class="text-right scc-num scc-mono">{{ proj.delivered_today }}</td>
|
||
<td>
|
||
<v-chip :color="projectStatusColor(proj.status)" variant="tonal" size="x-small">
|
||
{{ projectStatusLabel(proj.status) }}
|
||
</v-chip>
|
||
</td>
|
||
</tr>
|
||
<tr v-if="card.projects.length === 0">
|
||
<td colspan="6" class="text-center text-medium-emphasis pa-4">Проектов нет</td>
|
||
</tr>
|
||
</tbody>
|
||
</v-table>
|
||
</v-card>
|
||
|
||
<!-- Leads by day -->
|
||
<v-card variant="outlined" class="mb-4">
|
||
<div class="scc-section-head px-4 pt-4 pb-2">
|
||
<h2 class="scc-h2">Лиды за последние дни</h2>
|
||
</div>
|
||
<v-table density="compact" data-testid="leads-by-day-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Дата</th>
|
||
<th class="text-right scc-num">Пришло</th>
|
||
<th class="text-right scc-num">Потрачено клиентом</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="day in card.leads_by_day" :key="day.date" data-testid="leads-day-row">
|
||
<td class="scc-mono">{{ fmtDayLabel(day.date) }}</td>
|
||
<td class="text-right scc-num scc-mono">{{ day.count }}</td>
|
||
<td class="text-right scc-num scc-mono">{{ fmtMoney(day.oborot_rub) }}</td>
|
||
</tr>
|
||
<tr v-if="card.leads_by_day.length === 0">
|
||
<td colspan="3" class="text-center text-medium-emphasis pa-4">Нет данных</td>
|
||
</tr>
|
||
</tbody>
|
||
</v-table>
|
||
</v-card>
|
||
|
||
<!-- Recent leads -->
|
||
<v-card variant="outlined">
|
||
<div class="scc-section-head px-4 pt-4 pb-2">
|
||
<h2 class="scc-h2">Последние лиды</h2>
|
||
</div>
|
||
<v-table density="compact" data-testid="recent-leads-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Время</th>
|
||
<th>Телефон</th>
|
||
<th>Регион</th>
|
||
<th>Источник</th>
|
||
<th>Проект</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="(lead, idx) in card.recent_leads" :key="idx" data-testid="recent-lead-row">
|
||
<td class="scc-mono">{{ fmtDateTime(lead.received_at) }}</td>
|
||
<td class="scc-mono" data-testid="lead-phone">{{ lead.phone_masked }}</td>
|
||
<td>{{ lead.region }}</td>
|
||
<td>{{ lead.source }}</td>
|
||
<td>{{ lead.project }}</td>
|
||
</tr>
|
||
<tr v-if="card.recent_leads.length === 0">
|
||
<td colspan="5" class="text-center text-medium-emphasis pa-4">Лидов нет</td>
|
||
</tr>
|
||
</tbody>
|
||
</v-table>
|
||
</v-card>
|
||
</div>
|
||
|
||
<!-- RIGHT column (aside) -->
|
||
<div class="scc-col-aside">
|
||
<!-- Profile -->
|
||
<v-card variant="outlined" class="mb-4">
|
||
<div class="scc-section-head px-4 pt-4 pb-2">
|
||
<h2 class="scc-h2">Профиль клиента</h2>
|
||
</div>
|
||
<div class="scc-kv-grid px-4 pb-4">
|
||
<span class="scc-k">Логин (e-mail)</span>
|
||
<span class="scc-v scc-mono">{{ card.profile.contact_email ?? '—' }}</span>
|
||
|
||
<span class="scc-k">Контактное лицо</span>
|
||
<span class="scc-v">{{ card.profile.contact_name ?? '—' }}</span>
|
||
|
||
<span class="scc-k">Телефон</span>
|
||
<span class="scc-v scc-mono">{{ card.profile.contact_phone ?? '—' }}</span>
|
||
|
||
<span class="scc-k">Тип лица</span>
|
||
<span class="scc-v">{{ subjectLabel(card.profile.subject_type) }}</span>
|
||
|
||
<span class="scc-k">ИНН</span>
|
||
<span class="scc-v scc-mono">{{ card.profile.inn ?? '—' }}</span>
|
||
|
||
<span class="scc-k">Клиент с</span>
|
||
<span class="scc-v scc-mono">{{ fmtDate(card.profile.created_at) }}</span>
|
||
|
||
<span class="scc-k">Желаемый объём</span>
|
||
<span class="scc-v">
|
||
{{
|
||
card.profile.desired_daily_numbers !== null &&
|
||
card.profile.desired_daily_numbers !== undefined
|
||
? `~${card.profile.desired_daily_numbers} лидов/день`
|
||
: '—'
|
||
}}
|
||
</span>
|
||
|
||
<span class="scc-k">Последняя активность</span>
|
||
<span class="scc-v">{{ fmtActivity(card.profile.last_activity_at) }}</span>
|
||
</div>
|
||
</v-card>
|
||
|
||
<!-- Activity -->
|
||
<v-card variant="outlined">
|
||
<div class="scc-section-head px-4 pt-4 pb-2">
|
||
<h2 class="scc-h2">Активность</h2>
|
||
</div>
|
||
<div class="scc-timeline px-4 pb-4">
|
||
<div
|
||
v-for="(item, idx) in card.activity"
|
||
:key="idx"
|
||
class="scc-tm-item"
|
||
data-testid="activity-row"
|
||
>
|
||
<div class="scc-tm-when scc-mono">{{ fmtDateTime(item.created_at) }}</div>
|
||
<div class="scc-tm-text">{{ item.description }}</div>
|
||
</div>
|
||
<div v-if="card.activity.length === 0" class="text-medium-emphasis py-2">
|
||
Нет активности
|
||
</div>
|
||
</div>
|
||
</v-card>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</v-container>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.scc-wrap {
|
||
max-width: 1400px;
|
||
}
|
||
|
||
/* ─── Back link ─────────────────────────────────────────── */
|
||
.scc-back {
|
||
font-size: 13px;
|
||
color: #0f6e56;
|
||
cursor: pointer;
|
||
text-decoration: none;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.scc-back:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
/* ─── Title ─────────────────────────────────────────────── */
|
||
.scc-page-title {
|
||
font-size: 1.5rem;
|
||
font-weight: 700;
|
||
color: #081319;
|
||
letter-spacing: -0.02em;
|
||
}
|
||
|
||
/* ─── KPI row ───────────────────────────────────────────── */
|
||
.scc-kpi-row {
|
||
display: grid;
|
||
grid-template-columns: repeat(5, 1fr);
|
||
gap: 12px;
|
||
}
|
||
|
||
@media (max-width: 1200px) {
|
||
.scc-kpi-row {
|
||
grid-template-columns: repeat(3, 1fr);
|
||
}
|
||
}
|
||
|
||
@media (max-width: 700px) {
|
||
.scc-kpi-row {
|
||
grid-template-columns: repeat(2, 1fr);
|
||
}
|
||
}
|
||
|
||
.scc-kpi {
|
||
background: #fffdfa;
|
||
border: 1px solid #d9d5cd;
|
||
border-radius: 10px;
|
||
padding: 14px 16px;
|
||
}
|
||
|
||
.scc-k-label {
|
||
font-size: 11.5px;
|
||
color: #66635c;
|
||
font-weight: 500;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.scc-k-val {
|
||
font-size: 1.35rem;
|
||
font-weight: 700;
|
||
color: #081319;
|
||
line-height: 1.2;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.scc-k-sub {
|
||
font-size: 11.5px;
|
||
color: #66635c;
|
||
}
|
||
|
||
.scc-accent {
|
||
color: #0f6e56 !important;
|
||
}
|
||
|
||
.scc-slash {
|
||
color: #92907b;
|
||
font-size: 1rem;
|
||
font-weight: 400;
|
||
}
|
||
|
||
/* ─── Two-column layout ─────────────────────────────────── */
|
||
.scc-cols {
|
||
display: grid;
|
||
grid-template-columns: 1fr 340px;
|
||
gap: 20px;
|
||
align-items: start;
|
||
}
|
||
|
||
@media (max-width: 960px) {
|
||
.scc-cols {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
|
||
/* ─── Section heading ───────────────────────────────────── */
|
||
.scc-h2 {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: #081319;
|
||
letter-spacing: -0.01em;
|
||
margin: 0;
|
||
}
|
||
|
||
/* ─── Tables ────────────────────────────────────────────── */
|
||
.scc-num {
|
||
font-family: 'JetBrains Mono', 'Consolas', monospace;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.scc-mono {
|
||
font-family: 'JetBrains Mono', 'Consolas', monospace;
|
||
font-variant-numeric: tabular-nums;
|
||
font-size: 12.5px;
|
||
}
|
||
|
||
.scc-proj-name {
|
||
font-weight: 500;
|
||
color: #081319;
|
||
}
|
||
|
||
.scc-signal-badge {
|
||
display: inline-block;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.03em;
|
||
padding: 2px 7px;
|
||
border-radius: 4px;
|
||
background: #e1eeea;
|
||
color: #084635;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* ─── Profile kv grid ───────────────────────────────────── */
|
||
.scc-kv-grid {
|
||
display: grid;
|
||
grid-template-columns: auto 1fr;
|
||
gap: 6px 12px;
|
||
align-items: baseline;
|
||
}
|
||
|
||
.scc-k {
|
||
font-size: 12px;
|
||
color: #66635c;
|
||
white-space: nowrap;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.scc-v {
|
||
font-size: 13px;
|
||
color: #081319;
|
||
word-break: break-word;
|
||
}
|
||
|
||
/* ─── Activity timeline ─────────────────────────────────── */
|
||
.scc-timeline {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
}
|
||
|
||
.scc-tm-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
padding-left: 12px;
|
||
border-left: 2px solid #e1eeea;
|
||
}
|
||
|
||
.scc-tm-when {
|
||
font-size: 11px;
|
||
color: #66635c;
|
||
}
|
||
|
||
.scc-tm-text {
|
||
font-size: 13px;
|
||
color: #081319;
|
||
}
|
||
</style>
|