@@ -4833,17 +4895,18 @@ var STAMP_SIZES = {
triangle: { w: 189, h: 135, label: 'Треугольная 35×50 мм' },
};
-function _getRequisiteImages() {
- var sig = localStorage.getItem('zashita_sig') || null;
- var stamp = localStorage.getItem('zashita_stamp') || null;
- var stampType = (document.getElementById('stamp-type-sel') || {}).value
- || localStorage.getItem('zashita_stamp_type') || 'round';
- return { sig: sig, stamp: stamp, stampType: stampType };
+function _getRequisiteImages(role) {
+ // Используем библиотеку с привязкой по роли
+ var sigImage = _getSigForRole(role);
+ var stampData = _getStampForRole(role);
+ return { sig: sigImage, stamp: stampData.image, stampType: stampData.type };
}
-function _buildSignatureBlock(req, forPrint) {
+function _buildSignatureBlock(req, forPrint, fromName, toName) {
// req = {sig, stamp, stampType}
if (!req.sig && !req.stamp) return '';
+ fromName = fromName || ((_tplCurrent && _tplCurrent.parties && _tplCurrent.parties.from_name) || '');
+ toName = toName || ((_tplCurrent && _tplCurrent.parties && _tplCurrent.parties.to_name) || '');
var stampSize = STAMP_SIZES[req.stampType] || STAMP_SIZES.round;
// При печати: px → mm (96dpi: 1mm ≈ 3.78px)
@@ -4856,20 +4919,19 @@ function _buildSignatureBlock(req, forPrint) {
'padding-top:' + (forPrint ? '6mm' : '16px') + ';' +
'border-top:1px solid ' + (forPrint ? '#ccc' : 'var(--line)') + '">';
- // Подпись слева
+ // Подпись + печать — наша сторона (слева)
+ html += '
';
- // Печать справа
+ // Печать — отдельный блок по центру-справа
if (req.stamp) {
- html += '
' +
- '
М.П.
' +
+ html += '
' +
+ '
М.П.
' +
'

' +
'
';
}
@@ -7965,7 +8027,11 @@ function tab(name){
document.querySelectorAll('.tabpane').forEach(p=>p.classList.toggle('on',p.id==='p-'+name));
if(name==='sroki' && typeof renderDeadlines==='function') renderDeadlines();
if(name==='shab' && typeof renderContextTemplates==='function') renderContextTemplates();
- if(name==='requisites' && typeof _loadRequisites==='function') _loadRequisites();
+ if(name==='requisites') {
+ if(typeof _loadRequisites==='function') _loadRequisites();
+ if(typeof _renderSigLibrary==='function') _renderSigLibrary();
+ if(typeof _renderStampLibrary==='function') _renderStampLibrary();
+ }
if(name==='casemap' && typeof renderCaseMap==='function') renderCaseMap();
if(name==='team' && typeof renderTeamDashboard==='function') renderTeamDashboard();
if(name==='docs') {
@@ -9567,6 +9633,249 @@ function _toggleDocCheck(key, docId, checked) {
} catch(e){}
}
+// ── БИБЛИОТЕКА ПОДПИСЕЙ И ПЕЧАТЕЙ ────────────────────────────────────────────
+
+var _SIG_LIB_KEY = 'zashita_sig_library';
+var _STAMP_LIB_KEY = 'zashita_stamp_library';
+
+function _getSigLib() { try { return JSON.parse(localStorage.getItem(_SIG_LIB_KEY) || '[]'); } catch(e){ return []; } }
+function _getStampLib() { try { return JSON.parse(localStorage.getItem(_STAMP_LIB_KEY) || '[]'); } catch(e){ return []; } }
+
+function _saveSigLib(lib) { try { localStorage.setItem(_SIG_LIB_KEY, JSON.stringify(lib)); } catch(e){} }
+function _saveStampLib(lib) { try { localStorage.setItem(_STAMP_LIB_KEY, JSON.stringify(lib)); } catch(e){} }
+
+// Рендер библиотеки подписей
+function _renderSigLibrary() {
+ var el = document.getElementById('sig-library'); if (!el) return;
+ var lib = _getSigLib();
+ if (!lib.length) {
+ el.innerHTML = '
Нет сохранённых подписей. Нажмите «+ Добавить».
';
+ return;
+ }
+ el.innerHTML = lib.map(function(s, i) {
+ return '
' +
+ '

' +
+ '
' +
+ '
' + s.label + '
' +
+ '
' + (s.role || 'Без привязки к роли') + '
' +
+ '
' +
+ '
' +
+ (!s.isDefault ? '' : '✓ По умолч.') +
+ '' +
+ '
' +
+ '
';
+ }).join('');
+}
+
+// Рендер библиотеки печатей
+function _renderStampLibrary() {
+ var el = document.getElementById('stamp-library'); if (!el) return;
+ var lib = _getStampLib();
+ if (!lib.length) {
+ el.innerHTML = '
Нет сохранённых печатей. Нажмите «+ Добавить».
';
+ return;
+ }
+ el.innerHTML = lib.map(function(s, i) {
+ var sz = STAMP_SIZES[s.stampType] || STAMP_SIZES.round;
+ return '
' +
+ '

' +
+ '
' +
+ '
' + s.label + '
' +
+ '
' + sz.label + ' · ' + (s.role || 'Без привязки') + '
' +
+ '
' +
+ '
' +
+ (!s.isDefault ? '' : '✓ По умолч.') +
+ '' +
+ '
' +
+ '
';
+ }).join('');
+}
+
+// Модал добавления подписи/печати
+function _addSignatureModal() {
+ var old = document.getElementById('add-sig-modal'); if (old) old.remove();
+ var modal = document.createElement('div');
+ modal.id = 'add-sig-modal';
+ modal.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1000;display:flex;align-items:flex-end;justify-content:center';
+ modal.innerHTML =
+ '
' +
+ '
Добавить подпись или печать
' +
+ '
' +
+ '' +
+ '' +
+ '' +
+ '
' +
+ '
' +
+ '' +
+ '' +
+ '' +
+ '
' +
+ '
' +
+ '
![]()
' +
+ '
' +
+ '
' +
+ '
';
+ document.body.appendChild(modal);
+ setTimeout(function(){ var i=document.getElementById('add-sig-label'); if(i) i.focus(); }, 200);
+}
+
+var _pendingItemImage = null;
+
+function _addFromFile(input) {
+ var file = input.files[0]; if (!file) return;
+ var reader = new FileReader();
+ reader.onload = function(e) {
+ var img = new Image();
+ img.onload = function() {
+ var canvas = document.createElement('canvas');
+ canvas.width = img.width; canvas.height = img.height;
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(img, 0, 0);
+ var d = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ for (var i = 0; i < d.data.length; i += 4) {
+ if (d.data[i] > 220 && d.data[i+1] > 220 && d.data[i+2] > 220) d.data[i+3] = 0;
+ }
+ ctx.putImageData(d, 0, 0);
+ _pendingItemImage = canvas.toDataURL('image/png');
+ var prev = document.getElementById('add-sig-preview');
+ var img2 = document.getElementById('add-sig-img');
+ var btn = document.getElementById('add-sig-save-btn');
+ if (prev) prev.style.display = '';
+ if (img2) img2.src = _pendingItemImage;
+ if (btn) btn.style.display = '';
+ };
+ img.src = e.target.result;
+ };
+ reader.readAsDataURL(file);
+}
+
+function _addFromDraw() {
+ document.getElementById('add-sig-modal').remove();
+ var drawModal = document.getElementById('sig-draw-modal');
+ if (drawModal) { drawModal.style.display = 'flex'; _initSigCanvas(); }
+}
+
+function _saveSigCanvasToLib() {
+ var c = document.getElementById('sig-canvas');
+ if (!c) return;
+ _pendingItemImage = c.toDataURL('image/png');
+ var drawModal = document.getElementById('sig-draw-modal');
+ if (drawModal) drawModal.style.display = 'none';
+ _addSignatureModal();
+ setTimeout(function(){
+ var prev = document.getElementById('add-sig-preview');
+ var img2 = document.getElementById('add-sig-img');
+ var btn = document.getElementById('add-sig-save-btn');
+ if (prev) prev.style.display = '';
+ if (img2) img2.src = _pendingItemImage;
+ if (btn) btn.style.display = '';
+ }, 100);
+}
+
+function _saveNewItem() {
+ if (!_pendingItemImage) { toast('Загрузите или нарисуйте изображение'); return; }
+ var label = (document.getElementById('add-sig-label') || {}).value || 'Без названия';
+ var role = (document.getElementById('add-sig-role') || {}).value || '';
+ var type = (document.getElementById('add-sig-type') || {}).value || 'signature';
+ var isStamp = type.startsWith('stamp_');
+ var stampType = isStamp ? type.replace('stamp_', '') : null;
+
+ if (isStamp) {
+ var lib = _getStampLib();
+ lib.push({ label: label, role: role, stampType: stampType, image: _pendingItemImage, isDefault: lib.length === 0 });
+ _saveStampLib(lib);
+ // Обратная совместимость — первый штамп → legacy key
+ if (lib.length === 1) { localStorage.setItem('zashita_stamp', _pendingItemImage); localStorage.setItem('zashita_stamp_type', stampType); }
+ } else {
+ var lib2 = _getSigLib();
+ lib2.push({ label: label, role: role, image: _pendingItemImage, isDefault: lib2.length === 0 });
+ _saveSigLib(lib2);
+ // Обратная совместимость
+ if (lib2.length === 1) localStorage.setItem('zashita_sig', _pendingItemImage);
+ }
+
+ _pendingItemImage = null;
+ document.getElementById('add-sig-modal').remove();
+ _renderSigLibrary();
+ _renderStampLibrary();
+ toast('✅ Сохранено');
+}
+
+function _setSigDefault(idx) {
+ var lib = _getSigLib();
+ lib.forEach(function(s,i){ s.isDefault = (i===idx); });
+ _saveSigLib(lib);
+ // Обновляем legacy key
+ if (lib[idx]) localStorage.setItem('zashita_sig', lib[idx].image);
+ _renderSigLibrary();
+}
+
+function _setStampDefault(idx) {
+ var lib = _getStampLib();
+ lib.forEach(function(s,i){ s.isDefault = (i===idx); });
+ _saveStampLib(lib);
+ if (lib[idx]) {
+ localStorage.setItem('zashita_stamp', lib[idx].image);
+ localStorage.setItem('zashita_stamp_type', lib[idx].stampType || 'round');
+ }
+ _renderStampLibrary();
+}
+
+function _deleteSig(idx) {
+ var lib = _getSigLib(); lib.splice(idx, 1);
+ if (lib.length && !lib.some(function(s){ return s.isDefault; })) lib[0].isDefault = true;
+ _saveSigLib(lib);
+ if (lib[0]) localStorage.setItem('zashita_sig', lib[0].image); else localStorage.removeItem('zashita_sig');
+ _renderSigLibrary();
+}
+
+function _deleteStamp(idx) {
+ var lib = _getStampLib(); lib.splice(idx, 1);
+ if (lib.length && !lib.some(function(s){ return s.isDefault; })) lib[0].isDefault = true;
+ _saveStampLib(lib);
+ if (lib[0]) localStorage.setItem('zashita_stamp', lib[0].image); else localStorage.removeItem('zashita_stamp');
+ _renderStampLibrary();
+}
+
+// Получить подпись/печать для конкретной стороны документа
+function _getSigForRole(role) {
+ var lib = _getSigLib();
+ if (!lib.length) return localStorage.getItem('zashita_sig') || null;
+ // Ищем по роли
+ if (role) {
+ var byRole = lib.find(function(s){ return s.role && s.role.toLowerCase().includes(role.toLowerCase()); });
+ if (byRole) return byRole.image;
+ }
+ // По умолчанию
+ var def = lib.find(function(s){ return s.isDefault; });
+ return def ? def.image : lib[0].image;
+}
+
+function _getStampForRole(role) {
+ var lib = _getStampLib();
+ if (!lib.length) return { image: localStorage.getItem('zashita_stamp'), type: localStorage.getItem('zashita_stamp_type') || 'round' };
+ if (role) {
+ var byRole = lib.find(function(s){ return s.role && s.role.toLowerCase().includes(role.toLowerCase()); });
+ if (byRole) return { image: byRole.image, type: byRole.stampType || 'round' };
+ }
+ var def = lib.find(function(s){ return s.isDefault; });
+ var item = def || lib[0];
+ return { image: item.image, type: item.stampType || 'round' };
+}
+
// ── РЕКВИЗИТЫ — ПОДПИСЬ И ПЕЧАТЬ ────────────────────────────────────────────
function _uploadRequisite(type, input) {