mirror of
https://github.com/wasrusgen/zashita-brandbook.git
synced 2026-06-03 15:04:49 +00:00
feat: damage estimate shown inline in audit gaps + doc checklist + Sokolov ready
This commit is contained in:
parent
f4136f6d31
commit
383c74f706
135
mockup.html
135
mockup.html
@ -8076,6 +8076,55 @@ function _initOrgUser() {
|
|||||||
_updateSidebarUser();
|
_updateSidebarUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── ИЗВЛЕЧЕНИЕ ПАРАМЕТРОВ ДОГОВОРА ───────────────────────────────────────────
|
||||||
|
|
||||||
|
function _extractContractParams(contractType) {
|
||||||
|
var params = {};
|
||||||
|
// 1. Из загруженного договора (_DEADLINES и contracts store)
|
||||||
|
var contracts = _getContracts();
|
||||||
|
if (contracts.length) {
|
||||||
|
var c = contracts.find(function(x){ return (x.type||'').toLowerCase().includes(contractType); }) || contracts[0];
|
||||||
|
if (c) {
|
||||||
|
// Пробуем вытащить суммы из preview
|
||||||
|
var text = (c.preview || '') + ' ' + (c.type || '');
|
||||||
|
var amtMatch = text.match(/(\d[\d\s]{3,})\s*(?:руб|₽)/i);
|
||||||
|
if (amtMatch) params.amount = parseInt(amtMatch[1].replace(/\s/g,''));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Из истории чата — ищем суммы
|
||||||
|
var history = _chatHistory.slice(-10).map(function(m){ return m.content||''; }).join(' ');
|
||||||
|
var deposits = history.match(/депозит[а-я\s]*(\d[\d\s]+)\s*(?:руб|₽|тыс|к₽)/i);
|
||||||
|
if (deposits) params.deposit = parseInt(deposits[1].replace(/\s/g,'')) * (history.match(/тыс|к₽/) ? 1000 : 1);
|
||||||
|
|
||||||
|
var days_match = history.match(/(\d+)\s*(?:день|дней|дня)/i);
|
||||||
|
if (days_match) params.days = parseInt(days_match[1]);
|
||||||
|
|
||||||
|
// 3. Из активных дедлайнов
|
||||||
|
if (typeof _DEADLINES !== 'undefined' && _DEADLINES.length) {
|
||||||
|
var dl = _DEADLINES[0];
|
||||||
|
if (dl && dl.date) {
|
||||||
|
var diff = Math.round((new Date(dl.date) - new Date()) / 86400000);
|
||||||
|
params.days = Math.abs(diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Из b2b-реквизитов
|
||||||
|
try {
|
||||||
|
var b2b = JSON.parse(localStorage.getItem('zashita_b2b') || 'null');
|
||||||
|
if (b2b && b2b.amount) params.amount = b2b.amount;
|
||||||
|
} catch(e){}
|
||||||
|
|
||||||
|
// Дефолты по типу
|
||||||
|
if (!params.amount) {
|
||||||
|
var defaults = { аренда: 80000, подряд: 500000, 'купля-продажа': 300000, трудовой: 60000, займ: 100000, дду: 5000000 };
|
||||||
|
params.amount = defaults[contractType] || 100000;
|
||||||
|
}
|
||||||
|
if (!params.deposit && contractType === 'аренда') params.deposit = params.amount;
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
// ── КАРТА ДЕЛА ───────────────────────────────────────────────────────────────
|
// ── КАРТА ДЕЛА ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
var _CASE_NOTES_KEY = 'zashita_case_notes';
|
var _CASE_NOTES_KEY = 'zashita_case_notes';
|
||||||
@ -8722,6 +8771,54 @@ function _showAuditGaps(contractType, intent) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── РАСЧЁТ УЩЕРБА INLINE ──
|
||||||
|
// Запускаем /api/estimate чтобы показать финансовый риск прямо в блоке
|
||||||
|
var _contractParams = _extractContractParams(contractType);
|
||||||
|
var _situationText = _chatHistory.slice(-6).map(function(m){ return m.content||''; }).join(' ');
|
||||||
|
|
||||||
|
fetch(API_BASE + '/api/estimate', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type':'application/json'},
|
||||||
|
body: JSON.stringify({
|
||||||
|
situation: _situationText,
|
||||||
|
contract_type: contractType,
|
||||||
|
contract_params: _contractParams,
|
||||||
|
history: _chatHistory.slice(-4)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(function(r){ return r.json(); })
|
||||||
|
.then(function(est) {
|
||||||
|
if (!est.damage_min && !est.damage_max) return;
|
||||||
|
var dmgDiv = document.getElementById('audit-damage');
|
||||||
|
if (dmgDiv) dmgDiv.remove();
|
||||||
|
var dmg = document.createElement('div');
|
||||||
|
dmg.id = 'audit-damage';
|
||||||
|
dmg.className = 'hc-msg hc-elena';
|
||||||
|
var minF = (est.damage_min||0).toLocaleString('ru');
|
||||||
|
var maxF = (est.damage_max||0).toLocaleString('ru');
|
||||||
|
dmg.innerHTML =
|
||||||
|
'<img class="hc-av" src="logos/elena-photo.jpg">' +
|
||||||
|
'<div class="hc-bubble" style="max-width:480px">' +
|
||||||
|
'<div style="font-size:12px;color:var(--mut);margin-bottom:6px">Финансовый риск при текущем состоянии документов:</div>' +
|
||||||
|
'<div style="background:#fef2f2;border:1.5px solid #fca5a5;border-radius:10px;padding:12px 16px;margin-bottom:10px">' +
|
||||||
|
'<div style="font-size:12px;color:#6b7280;margin-bottom:2px">Примерный ущерб</div>' +
|
||||||
|
'<div style="font-family:var(--font-logo,\'Montserrat\');font-size:22px;font-weight:900;color:#dc2626">' +
|
||||||
|
minF + ' — ' + maxF + ' ₽' +
|
||||||
|
'</div>' +
|
||||||
|
(est.damage_comment ? '<div style="font-size:11px;color:#6b7280;margin-top:4px">' + est.damage_comment + '</div>' : '') +
|
||||||
|
(est.damage_formula ? '<div style="font-size:11px;color:#9ca3af;margin-top:2px">Формула: ' + est.damage_formula + '</div>' : '') +
|
||||||
|
'</div>' +
|
||||||
|
(est.summary ? '<div style="font-size:13px;color:#374151">' + est.summary + '</div>' : '') +
|
||||||
|
'</div>';
|
||||||
|
var msgs2 = document.getElementById('rchat-msgs');
|
||||||
|
if (msgs2) { msgs2.appendChild(dmg); dmg.scrollIntoView({behavior:'smooth'}); }
|
||||||
|
// Сохраняем в карту дела
|
||||||
|
_addCaseNote('risk', 'Расчётный ущерб: ' + minF + '–' + maxF + '₽ · ' + (est.damage_comment||''), {contractType: contractType});
|
||||||
|
// После показа ущерба — оффер услуги
|
||||||
|
setTimeout(function(){ _checkAndOfferService(msgs2); }, 1500);
|
||||||
|
})
|
||||||
|
.catch(function(){});
|
||||||
|
|
||||||
// Кнопки: исправить + ПРИНЯТЬ РИСКИ И ПРОДОЛЖИТЬ
|
// Кнопки: исправить + ПРИНЯТЬ РИСКИ И ПРОДОЛЖИТЬ
|
||||||
gapsHtml += '<div style="margin-top:14px">';
|
gapsHtml += '<div style="margin-top:14px">';
|
||||||
|
|
||||||
@ -8787,11 +8884,16 @@ function _acknowledgeRisksAndProceed(contractType, intent) {
|
|||||||
_rcAddBubble(reply, false);
|
_rcAddBubble(reply, false);
|
||||||
if (apiActions && apiActions.length) _renderElenaActions(apiActions, msgs);
|
if (apiActions && apiActions.length) _renderElenaActions(apiActions, msgs);
|
||||||
|
|
||||||
// Небольшая пауза → запускаем оффер услуги
|
// Небольшая пауза → аудит документов (Блок Д) → потом оффер
|
||||||
|
var detectedType = _detectContractType(ctx + ' ' + reply);
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
var wrap = document.querySelector('.chatwrap') || msgs;
|
if (detectedType) {
|
||||||
_checkAndOfferService(wrap);
|
_showDocAuditInChat(detectedType, intent);
|
||||||
}, 1500);
|
} else {
|
||||||
|
var wrap2 = document.querySelector('.chatwrap') || msgs;
|
||||||
|
_checkAndOfferService(wrap2);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
_rcShowControls();
|
_rcShowControls();
|
||||||
});
|
});
|
||||||
@ -8972,6 +9074,31 @@ function renderDocChecklist(contractType) {
|
|||||||
});
|
});
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
|
// Расчёт ущерба по пробелам
|
||||||
|
if (missing.length && _apiAvailable) {
|
||||||
|
var params = _extractContractParams(key);
|
||||||
|
var situation = 'Договор ' + key + '. Отсутствуют документы: ' + missing.map(function(d){ return d.label; }).join(', ');
|
||||||
|
fetch(API_BASE + '/api/estimate', {
|
||||||
|
method: 'POST', headers: {'Content-Type':'application/json'},
|
||||||
|
body: JSON.stringify({ situation: situation, contract_type: key, contract_params: params, history: [] })
|
||||||
|
})
|
||||||
|
.then(function(r){ return r.json(); })
|
||||||
|
.then(function(est) {
|
||||||
|
if (!est.damage_min) return;
|
||||||
|
var dmgEl = document.getElementById('checklist-damage');
|
||||||
|
if (!dmgEl) return;
|
||||||
|
var minF = (est.damage_min||0).toLocaleString('ru');
|
||||||
|
var maxF = (est.damage_max||0).toLocaleString('ru');
|
||||||
|
dmgEl.innerHTML =
|
||||||
|
'<div style="background:#fef2f2;border:1.5px solid #fca5a5;border-radius:10px;padding:12px 16px;margin-top:12px">' +
|
||||||
|
'<div style="font-size:11px;color:#6b7280;margin-bottom:3px">Примерный ущерб при текущих пробелах</div>' +
|
||||||
|
'<div style="font-size:20px;font-weight:900;color:#dc2626;font-family:inherit">' + minF + ' — ' + maxF + ' ₽</div>' +
|
||||||
|
(est.damage_comment ? '<div style="font-size:11px;color:#6b7280;margin-top:3px">' + est.damage_comment + '</div>' : '') +
|
||||||
|
'</div>';
|
||||||
|
}).catch(function(){});
|
||||||
|
}
|
||||||
|
html += '<div id="checklist-damage"></div>';
|
||||||
|
|
||||||
// Кнопка загрузить недостающие
|
// Кнопка загрузить недостающие
|
||||||
if (missing.length) {
|
if (missing.length) {
|
||||||
html += '<div style="margin-top:16px;padding:12px;background:#fffbeb;border:1.5px solid #fcd34d;border-radius:10px;font-size:13px">' +
|
html += '<div style="margin-top:16px;padding:12px;background:#fffbeb;border:1.5px solid #fcd34d;border-radius:10px;font-size:13px">' +
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user