ii-reshenie-dlya-protsessa-2/index.html

298 lines
24 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- Дизайн: Стандартный дизайн. Все пять CSS ДС сохранить (design.md). -->
<html lang="ru" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ИИ-решение для процесса — Свод отчётности</title>
<link rel="stylesheet" href="design-system/kt-ai-fonts.css">
<link rel="stylesheet" href="design-system/kt-ai-tokens.css">
<link rel="stylesheet" href="design-system/kt-ai-components.css">
<link rel="stylesheet" href="design-system/kt-ai-page.css">
<link rel="stylesheet" href="design-system/vibe-theme.css">
<link rel="stylesheet" href="style.css">
<style>
a.kt-ai-btn { text-decoration: none; }
.app-grid { display: grid; grid-template-columns: minmax(232px, 272px) minmax(0, 1fr); min-height: 100vh; }
.app-side { border-right: 1px solid var(--kt-ai-border); padding: var(--kt-ai-space-6) var(--kt-ai-space-4); display: flex; flex-direction: column; gap: var(--kt-ai-space-3); background: var(--kt-ai-bg-soft); }
.app-brand { display: flex; align-items: center; gap: var(--kt-ai-space-4); padding: 0 var(--kt-ai-space-3) var(--kt-ai-space-6); }
.app-brand img { width: 28px; height: 28px; border-radius: 8px; flex-shrink: 0; }
.app-brand .nm { font-size: var(--kt-ai-text-sm); font-weight: var(--kt-ai-weight-semibold); line-height: 1.3; display: flex; flex-direction: column; }
.app-brand .nm span { font-size: var(--kt-ai-text-xs); font-weight: var(--kt-ai-font-weight, var(--kt-ai-weight-regular,400)); color: var(--kt-ai-fg-muted); }
.app-nav { display: flex; flex-direction: column; gap: 2px; }
.app-nav button { display: flex; align-items: center; gap: var(--kt-ai-space-3); width: 100%; border: 0; background: transparent; font: inherit; font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-muted); padding: 8px var(--kt-ai-space-3); border-radius: var(--kt-ai-radius-lg); cursor: pointer; text-align: left; }
.app-nav button .ct { margin-left: auto; font-family: var(--kt-ai-font-mono); font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-faint); }
.app-nav button:hover { background: var(--kt-ai-bg-hover); color: var(--kt-ai-fg); }
.app-nav button[data-active="true"] { background: var(--kt-ai-bg-active); color: var(--kt-ai-fg); font-weight: var(--kt-ai-weight-medium); box-shadow: inset 2px 0 0 var(--kt-ai-primary); border-radius: 0 var(--kt-ai-radius-lg) var(--kt-ai-radius-lg) 0; }
.app-foot { margin-top: auto; font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-faint); padding: var(--kt-ai-space-3); }
.app-main { padding: var(--kt-ai-space-8) var(--kt-ai-space-10); max-width: 1240px; width: 100%; margin: 0 auto; }
.page { display: block; }
.page[hidden] { display: none; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--kt-ai-space-6); flex-wrap: wrap; margin-bottom: var(--kt-ai-space-8); }
.page-head h1 { margin: 0 0 4px; font-size: var(--kt-ai-text-2xl); font-weight: 400; letter-spacing: -.02em; }
.page-head .sub { margin: 0; color: var(--kt-ai-fg-muted); font-size: var(--kt-ai-text-sm); }
.page-head .head-actions { display: flex; gap: var(--kt-ai-space-3); }
/* паспорт */
.passport-grid { display: grid; grid-template-columns: 1.2fr .8fr; gap: var(--kt-ai-space-8); align-items: start; }
.kv { display: flex; flex-direction: column; gap: var(--kt-ai-space-1); margin-bottom: var(--kt-ai-space-5); }
.kv .k { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); }
.kv .v { font-size: var(--kt-ai-text-sm); font-weight: var(--kt-ai-weight-medium); }
.risk-row { display: flex; gap: var(--kt-ai-space-4); padding: var(--kt-ai-space-4) 0; border-bottom: 1px solid var(--kt-ai-divider); }
.risk-row:last-child { border-bottom: none; }
.risk-row .kt-icon { width: 16px; height: 16px; color: var(--kt-ai-status-warn-fg); flex-shrink: 0; margin-top: 2px; }
.risk-row .t { font-size: var(--kt-ai-text-sm); font-weight: var(--kt-ai-weight-medium); }
.risk-row .d { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); margin-top: 2px; }
/* схема процесса */
.flow { display: flex; flex-direction: column; }
.flow-step { display: flex; gap: var(--kt-ai-space-5); position: relative; }
.flow-step .line { position: absolute; left: 17px; top: 38px; bottom: -2px; width: 2px; background: var(--kt-ai-border); }
.flow-step:last-child .line { display: none; }
.flow-step .n { flex-shrink: 0; }
.flow-step .body { padding-bottom: var(--kt-ai-space-7); }
.flow-step .t { font-size: var(--kt-ai-text-sm); font-weight: var(--kt-ai-weight-semibold); }
.flow-step .d { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); margin-top: 2px; max-width: 56ch; }
.flow-step .meta { display: flex; gap: var(--kt-ai-space-3); margin-top: var(--kt-ai-space-3); flex-wrap: wrap; }
.flow-step[data-ai="true"] .line { background: var(--kt-ai-primary); }
/* входящие */
.mail-row { display: flex; align-items: center; gap: var(--kt-ai-space-4); width: 100%; text-align: left; }
.mail-file { flex-shrink: 0; }
.mail-file .doc-ic { width: 32px; height: 32px; display: inline-grid; place-items: center; border-radius: var(--kt-ai-radius-lg); background: var(--kt-ai-bg-soft); color: var(--kt-ai-fg-muted); }
.mail-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mail-from { font-size: var(--kt-ai-text-sm); font-weight: var(--kt-ai-weight-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mail-subj { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mail-meta { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); font-family: var(--kt-ai-font-mono); white-space: nowrap; }
.mail-meta .warn { color: var(--kt-ai-status-warn-fg); }
/* свод */
.sum-table td.row-click, .sum-table tr.row-click { cursor: pointer; }
.sum-table tbody tr.row-click:hover { background: var(--kt-ai-bg-hover); }
/* график */
.chart-card { display: grid; grid-template-columns: 1fr 260px; gap: var(--kt-ai-space-6); align-items: center; }
.chart-svg { width: 100%; height: 210px; }
.cc-bar { fill: var(--kt-ai-chart-blue); }
.cc-bar[data-hover="true"] { fill: var(--kt-ai-chart-orange); }
.cc-lbl { font-size: 10px; fill: var(--kt-ai-fg-muted); }
.cc-val { font-size: 10px; fill: var(--kt-ai-fg-muted); font-family: var(--kt-ai-font-mono); }
.chart-legend { display: flex; flex-direction: column; gap: var(--kt-ai-space-4); }
.insight { display: flex; gap: var(--kt-ai-space-4); padding: var(--kt-ai-space-4) 0; border-bottom: 1px solid var(--kt-ai-divider); }
.insight:last-child { border-bottom: none; }
.insight .kt-icon { width: 16px; height: 16px; flex-shrink: 0; margin-top: 2px; }
.insight[data-tone="warn"] .kt-icon { color: var(--kt-ai-status-warn-fg); }
.insight[data-tone="ok"] .kt-icon { color: var(--kt-ai-status-ok-fg); }
.insight[data-tone="info"] .kt-icon { color: var(--kt-ai-primary); }
.insight .t { font-size: var(--kt-ai-text-sm); font-weight: var(--kt-ai-weight-medium); }
.insight .d { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); margin-top: 2px; max-width: 64ch; }
@media (max-width: 900px) { .app-grid { grid-template-columns: 1fr; } .app-side { flex-direction: row; flex-wrap: wrap; align-items: center; position: sticky; top: 0; z-index: 5; } .app-brand { width: 100%; padding-bottom: var(--kt-ai-space-2); } .app-brand .nm span { display: none; } .app-nav { flex-direction: row; flex-wrap: wrap; } .app-nav button { box-shadow: none !important; border-radius: var(--kt-ai-radius-lg) !important; } .app-foot { display: none; } .app-main { padding: var(--kt-ai-space-6); } .passport-grid, .chart-card { grid-template-columns: 1fr; } }
</style>
</head>
<body class="kt-ai-app">
<div class="app-grid">
<aside class="app-side">
<div class="app-brand">
<img src="https://code.vibe42.kz/tore/aitu/kt-logo.svg" alt="Казахтелеком" onerror="this.style.display='none'">
<div class="nm">Свод отчётности<span>дочерние организации</span></div>
</div>
<nav class="app-nav" id="appNav">
<button data-page="passport"><svg class="kt-icon" aria-hidden="true"><use href="#file"></use></svg><span>Паспорт решения</span></button>
<button data-page="inbox"><svg class="kt-icon" aria-hidden="true"><use href="#inbox"></use></svg><span>Входящие</span><span class="ct" id="ctInbox">—</span></button>
<button data-page="summary"><svg class="kt-icon" aria-hidden="true"><use href="#spreadsheet"></use></svg><span>Свод</span></button>
<button data-page="analysis"><svg class="kt-icon" aria-hidden="true"><use href="#chart"></use></svg><span>Анализ</span></button>
</nav>
<div class="app-foot">Отчётная неделя 14–20.09.2026</div>
</aside>
<main class="app-main">
<!-- ================= ПАСПОРТ ================= -->
<section class="page" id="page-passport">
<div class="page-head">
<div>
<h1>ИИ-решение для процесса</h1>
<p class="sub">Автоматический сбор Excel-отчётов дочерних организаций и свод показателей в единый файл</p>
</div>
<div class="head-actions">
<span class="kt-ai-chip" data-tone="blue">Статус: согласование</span>
</div>
</div>
<div class="passport-grid">
<div class="kt-ai-v" data-gap="group">
<div class="kt-ai-card">
<div style="padding: var(--kt-ai-space-7)">
<div class="kv"><span class="k">Исполнитель</span><span class="v">Владелец процесса — сборка на платформе Vibe AI</span></div>
<div class="kv"><span class="k">Пользователь</span><span class="v">Владелец процесса</span></div>
<div class="kv"><span class="k">Дата внедрения</span><span class="v" style="color: var(--kt-ai-fg-muted)">—</span></div>
<div class="kv"><span class="k">Формат</span><span class="v">Веб-интерфейс: сначала статичный макет всего процесса, после согласования — рабочее решение</span></div>
</div>
</div>
<div class="kt-ai-card">
<div class="kt-ai-kpi-strip" data-cards="true">
<div class="kt-ai-kpi"><span class="value" data-long="true">15–20</span><span class="label">дочерних организаций</span><span class="hint">отправляют отчёты раз в неделю</span></div>
<div class="kt-ai-kpi"><span class="value" data-long="true">до 5</span><span class="label">файлов на организацию</span><span class="hint">выгрузки в Excel</span></div>
<div class="kt-ai-kpi"><span class="value" data-long="true">75–100</span><span class="label">файлов в неделю</span><span class="hint">приходится сводить вручную</span></div>
<div class="kt-ai-kpi"><span class="value" data-long="true">2–4 ч</span><span class="label">вручную на свод</span><span class="hint">раз в неделю</span></div>
</div>
</div>
<div class="kt-ai-card">
<div style="padding: var(--kt-ai-space-7)">
<h3 class="kt-ai-h3" style="margin:0 0 var(--kt-ai-space-5); font-size: var(--kt-ai-text-md); font-weight: var(--kt-ai-weight-semibold)">Ожидаемый эффект</h3>
<div class="insight" data-tone="ok"><svg class="kt-icon"><use href="#check-circle"></use></svg><div><div class="t">Быстрее и меньше ручной работы</div><div class="d">Сбор файлов из почты, разбор и обновление единого отчёта выполняется без ручного скачивания каждого файла.</div></div></div>
<div class="insight" data-tone="ok"><svg class="kt-icon"><use href="#check-circle"></use></svg><div><div class="t">Точный анализ</div><div class="d">Показатели сводятся по единым правилам, меньше риск арифметических ошибок при большом объёме цифр.</div></div></div>
<div class="insight" data-tone="info"><svg class="kt-icon"><use href="#clock"></use></svg><div><div class="t">Результат — единый Excel SWAT</div><div class="d">Свод по всем дочерним организациям и показателям плюс анализ по каждой.</div></div></div>
</div>
</div>
</div>
<div class="kt-ai-v" data-gap="group">
<div class="kt-ai-card">
<div style="padding: var(--kt-ai-space-7)">
<h3 class="kt-ai-h3" style="margin:0 0 var(--kt-ai-space-4); font-size: var(--kt-ai-text-md); font-weight: var(--kt-ai-weight-semibold)">Опасные места и меры</h3>
<div class="risk-row"><svg class="kt-icon"><use href="#warning"></use></svg><div><div class="t">Ошибки при своде показателей</div><div class="d">Много показателей в Excel-файлах разных дочерних организаций.</div></div></div>
<div class="risk-row"><svg class="kt-icon"><use href="#warning"></use></svg><div><div class="t">Ошибки в анализе</div><div class="d">Выводы по сводным данным требуют контроля.</div></div></div>
<div class="risk-row"><svg class="kt-icon" style="color: var(--kt-ai-status-ok-fg)"><use href="#check-circle"></use></svg><div><div class="t">Меры</div><div class="d">Проверка результата человеком перед использованием; журнал действий ИИ и возможность вернуться в ручной режим.</div></div></div>
</div>
</div>
<div class="kt-ai-card">
<div style="padding: var(--kt-ai-space-7)">
<h3 class="kt-ai-h3" style="margin:0 0 var(--kt-ai-space-5); font-size: var(--kt-ai-text-md); font-weight: var(--kt-ai-weight-semibold)">Как работает процесс</h3>
<div class="flow">
<div class="flow-step"><span class="kt-ai-num-badge" data-state="done">1</span><div class="body"><div class="t">Дочерние организации отправляют отчёты</div><div class="d">Раз в неделю каждая дочка готовит отчёты в Excel (до 5 файлов) и высылает по почте.</div><div class="meta"><span class="kt-ai-chip">15–20 организаций</span></div></div><span class="line"></span></div>
<div class="flow-step" data-ai="true"><span class="kt-ai-num-badge" data-state="done">2</span><div class="body"><div class="t">ИИ получает письма со вложениями</div><div class="d">Письма с выгрузками читаются автоматически, файлы классифицируются по организации.</div><div class="meta"><span class="kt-ai-chip" data-tone="blue">ИИ</span></div></div><span class="line"></span></div>
<div class="flow-step" data-ai="true"><span class="kt-ai-num-badge">3</span><div class="body"><div class="t">ИИ разгружает файлы и сверяет показатели</div><div class="d">Показатели извлекаются из каждого файла, дубли и расхождения отмечаются для проверки.</div><div class="meta"><span class="kt-ai-chip" data-tone="blue">ИИ</span></div></div><span class="line"></span></div>
<div class="flow-step" data-ai="true"><span class="kt-ai-num-badge">4</span><div class="body"><div class="t">Единый свод Excel SWAT</div><div class="d">Формируется единый файл по всем дочерним организациям и показателям.</div><div class="meta"><span class="kt-ai-chip" data-tone="blue">ИИ</span></div></div><span class="line"></span></div>
<div class="flow-step"><span class="kt-ai-num-badge">5</span><div class="body"><div class="t">Проверка человеком</div><div class="d">Владелец процесса проверяет результат перед использованием.</div><div class="meta"><span class="kt-ai-chip" data-tone="orange">человек</span></div></div></div>
<div class="flow-step"><span class="kt-ai-num-badge">6</span><div class="body"><div class="t">Анализ и отчёт</div><div class="d">Анализ по каждой дочерней организации, готовность к использованию.</div></div></div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ================= ВХОДЯЩИЕ ================= -->
<section class="page" id="page-inbox" hidden>
<div class="page-head">
<div>
<h1>Входящие</h1>
<p class="sub">Письма дочерних организаций со вложенными Excel-отчётами за неделю</p>
</div>
<div class="head-actions">
<button class="kt-ai-btn" id="btnRefresh"><svg class="kt-icon" aria-hidden="true"><use href="#refresh"></use></svg>Проверить почту</button>
<button class="kt-ai-btn" data-variant="primary" id="btnProcess">Свести файлы</button>
</div>
</div>
<div class="kt-ai-kpi-strip" data-cards="true" id="kpiInbox"></div>
<div class="kt-ai-tool" style="display:flex; align-items:center; justify-content:space-between; gap: var(--kt-ai-space-4)">
<div class="kt-ai-filterbar" id="mailFilters"></div>
<div class="kt-ai-filterbar">
<div class="kt-ai-field" style="margin-bottom:0">
<input class="kt-ai-input" id="mailSearch" style="width: 200px" placeholder="Организация или тема…">
</div>
</div>
</div>
<div class="kt-ai-table-wrap" data-framed="true" style="margin-top: var(--kt-ai-space-4)">
<table class="kt-ai-table" id="mailTable">
<thead><tr><th style="width:36px"><svg class="kt-icon" aria-hidden="true" style="width:16px;height:16px"><use href="#spreadsheet"></use></svg></th><th>Организация</th><th>Тема письма</th><th style="text-align:right">Файлов</th><th>Получено</th><th>Статус</th></tr></thead>
<tbody id="mailRows"></tbody>
</table>
<div class="kt-ai-empty" id="mailEmpty" hidden><div class="title">Ничего не найдено</div><div>Попробуйте изменить фильтр или поисковый запрос.</div><button class="kt-ai-btn" data-size="sm" data-variant="ghost" onclick="App.resetMailFilters()">Сбросить фильтры</button></div>
</div>
<div style="display:flex; justify-content:space-between; align-items:center; margin-top: var(--kt-ai-space-4); font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted)">
<span id="mailCount"></span>
<button class="kt-ai-btn" data-size="sm" id="btnDownload"><svg class="kt-icon" aria-hidden="true"><use href="#download"></use></svg>Скачать выбранные файлы</button>
</div>
</section>
<!-- ================= СВОД ================= -->
<section class="page" id="page-summary" hidden>
<div class="page-head">
<div>
<h1>Свод</h1>
<p class="sub">Показатели по дочерним организациям, обновлённые из отчётных файлов</p>
</div>
<div class="head-actions">
<button class="kt-ai-btn" id="btnExport"><svg class="kt-icon" aria-hidden="true"><use href="#download"></use></svg>Выгрузить Excel SWAT</button>
</div>
</div>
<div class="kt-ai-kpi-strip" data-cards="true" id="kpiSum"></div>
<div class="kt-ai-filterbar" id="sumFilters" style="margin-top: var(--kt-ai-space-4)"></div>
<div class="kt-ai-table-wrap" data-framed="true" style="margin-top: var(--kt-ai-space-4)">
<table class="kt-ai-table sum-table" id="sumTable">
<thead><tr><th>Организация</th><th>Файлов</th><th>Показателей</th><th style="text-align:right">Объём, млн</th><th>Обновлено</th><th>Статус</th></tr></thead>
<tbody id="sumRows"></tbody>
</table>
<div class="kt-ai-empty" id="sumEmpty" hidden><div class="title">Нет организаций по выбранному статусу</div><div>Смените фильтр, чтобы увидеть остальные.</div></div>
</div>
<div class="kt-ai-conclusion" style="margin-top: var(--kt-ai-space-8)">
<span class="title">Что требует внимания</span>
<span class="text">Организации со статусом «расхождение» — ИИ нашёл несовпадения между файлами или с предыдущей неделей; эти строки стоит проверить перед сводом.</span>
<span class="text">Строка «Всего» — сумма показателей по всем дочерним организациям с учётом выбранных фильтров.</span>
</div>
</section>
<!-- ================= АНАЛИЗ ================= -->
<section class="page" id="page-analysis" hidden>
<div class="page-head">
<div>
<h1>Анализ</h1>
<p class="sub">Динамика сводных показателей за восемь недель и выводы по каждой организации</p>
</div>
</div>
<div class="kt-ai-kpi-strip" data-cards="true" id="kpiAna"></div>
<div class="kt-ai-card chart-card" style="margin-top: var(--kt-ai-space-4)">
<div>
<div style="display:flex; justify-content:space-between; align-items:baseline; margin-bottom: var(--kt-ai-space-5)">
<h3 style="margin:0; font-size: var(--kt-ai-text-md); font-weight: var(--kt-ai-weight-semibold)">Динамика по объёму, млн</h3>
<span style="font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted)">8 недель</span>
</div>
<svg class="chart-svg" id="chartSvg" viewBox="0 0 640 210" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Столбчатая диаграмма сводного показателя за восемь недель"></svg>
</div>
<div class="chart-legend">
<div class="kt-ai-kpi"><span class="value" id="chMaxV">—</span><span class="label">пик недели</span><span class="hint" id="chMaxD"></span></div>
<div class="kt-ai-kpi"><span class="value" id="chAvgV">—</span><span class="label">среднее за период</span></div>
<div class="kt-ai-kpi"><span class="value" id="chDeltaV">—</span><span class="label">к предыдущей неделе</span></div>
</div>
</div>
<div class="kt-ai-v" data-gap="group" style="margin-top: var(--kt-ai-space-8)">
<div>
<h3 class="kt-ai-h3" style="margin:0 0 var(--kt-ai-space-4); font-size: var(--kt-ai-text-md); font-weight: var(--kt-ai-weight-semibold)">Выводы по организациям</h3>
<div class="kt-ai-filterbar" id="insFilter"></div>
</div>
<div class="kt-ai-card" style="padding: var(--kt-ai-space-3) var(--kt-ai-space-7)">
<div id="insightsList"></div>
</div>
</div>
</section>
</main>
</div>
<!-- drawer -->
<div style="position:fixed; inset:0; z-index:60; display:none" id="ovl">
<div style="position:absolute; inset:0; background: var(--kt-ai-overlay)" id="ovlBg"></div>
<aside class="kt-ai-drawer" id="drawer" style="position:fixed"></aside>
</div>
<div class="kt-ai-toast-stack" id="toasts"></div>
<div class="kt-ai-modal-overlay" id="modalOvl" style="display:none">
<div class="kt-ai-modal" id="modalBox"></div>
</div>
<script src="design-system/icons/kt-ai-icons.js"></script>
<script src="design-system/kt-ai-chart-tip.js"></script>
<script src="script.js"></script>
</body>
</html>