không còn ảnh hưởng
$element.css('position', 'relative');
const address = $parent.attr('address');
$element.attr('data-address', address);
// Lấy tên loại thẻ cho tooltip
const parentType = getParentTypeName($parent.prop('tagName').toLowerCase());
const $badge = $('Phân tích');
$element.append($badge);
}
// Xử lý các p con (nếu có sub-p)
attachPhanTichBadge($element);
}, 300); // Đợi 300ms để CTTD render xong
}
},
complete: function() {
$element.removeClass('loading-content');
}
})
);
processQueue();
}
});
} catch(e) {
console.error('Lỗi processVisibleParagraphs:', e);
}
}
$(window).on('scroll resize', function () {
processVisibleParagraphs();
});
console.log('Bắt đầu processVisibleParagraphs lần đầu...');
processVisibleParagraphs();
console.log('processVisibleParagraphs lần đầu hoàn thành');
// Chức năng phân tích điều luật (chỉ cho member_id = 4)
if (memberID === 4) {
// Hàm lấy tên tiếng Việt của thẻ
function getParentTypeName(tagName) {
const typeNames = {
'phan': 'Phần',
'chuong': 'Chương',
'muc': 'Mục',
'tieumuc': 'Tiểu mục',
'dieu': 'Điều',
'khoan': 'Khoản',
'diem': 'Điểm'
};
return typeNames[tagName] || 'Nội dung';
}
function attachPhanTichBadge($container) {
const validTags = 'phan, chuong, muc, tieumuc, dieu, khoan, diem';
$container.find('p').each(function() {
const $p = $(this);
const $parent = $p.closest(validTags);
if ($parent.length > 0) {
// Kiểm tra đã có badge chưa
if ($p.find('.badge-phan-tich').length === 0) {
// Set relative cho
(lúc này CTTD đã render xong)
$p.css('position', 'relative');
// Lưu address vào data attribute để dùng sau
const address = $parent.attr('address');
$p.attr('data-address', address);
// Lấy tên loại thẻ cho tooltip
const parentType = getParentTypeName($parent.prop('tagName').toLowerCase());
const $badge = $('Phân tích');
$p.append($badge);
}
}
});
}
// Helper: Escape HTML entities
function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return String(text).replace(/[&<>"']/g, function(m) { return map[m]; });
}
// Helper: Convert Markdown to HTML (đơn giản)
function markdownToHtml(markdown) {
if (!markdown) return '';
let html = markdown;
// Headers
html = html.replace(/^### (.*$)/gim, '
')) {
return para;
}
if (para) {
return '' + para.replace(/\n/g, '
') + '
';
}
return '';
}).join('\n');
// Clean up multiple line breaks
html = html.replace(/\n{3,}/g, '\n\n');
return html;
}
// Panel trượt đè lên #rightdocinfo để hiển thị phân tích điều luật
function closePhanTichPanel() {
const $panel = $('#phanTichPanel');
if ($panel.length) {
$panel.removeClass('show');
setTimeout(() => $panel.remove(), 300);
}
}
function openPhanTichPanel(address, vbID) {
const $container = $('#rightdocinfo');
if ($container.length === 0) {
// Fallback: nếu không có rightdocinfo, dùng modal cũ
return openPhanTichModal(address, vbID);
}
// Tạo panel nếu chưa có
if ($('#phanTichPanel').length === 0) {
const panelHTML = `
Đang phân tích...
Đang phân tích...
`;
// Đảm bảo container có position relative
if ($container.css('position') === 'static') {
$container.css('position', 'relative');
}
$container.append(panelHTML);
// Trigger slide-in
setTimeout(() => $('#phanTichPanel').addClass('show'), 10);
} else {
$('#phanTichPanelBody').html(`
Đang phân tích...
Đang phân tích...
`);
$('#phanTichPanel').addClass('show');
}
// Bind nút đóng và ESC
$(document).off('click.closePhanTich').on('click.closePhanTich', '.close-phan-tich', function() {
closePhanTichPanel();
});
$(document).off('keyup.closePhanTich').on('keyup.closePhanTich', function(e) {
if (e.key === 'Escape') closePhanTichPanel();
});
// Gọi API phân tích
const randomServer = Math.floor(Math.random() * 10) + 1;
$.ajax({
url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/phan.tich.dieu.luat.php',
type: 'POST',
contentType: 'application/json',
timeout: 300000, // 5 phút
data: JSON.stringify({
address: address,
vb_id: vbID
}),
success: function(response) {
if (response.ok) {
// Render kết quả phân tích
let html = '';
html += '';
html += '
' + escapeHtml(response.ten_van_ban) + '
';
if (response.so_hieu) {
html += 'Số hiệu: ' + escapeHtml(response.so_hieu) + '
';
}
html += 'Điều khoản: ' + escapeHtml(response.address) + '';
html += '';
html += '' + markdownToHtml(response.phan_tich) + '
';
if (response.usage) {
html += '';
html += 'Thống kê: ';
html += 'Input tokens: ' + (response.usage.promptTokenCount || 0) + ', ';
html += 'Output tokens: ' + (response.usage.candidatesTokenCount || 0);
html += '
';
}
$('#phanTichPanelBody').html(html);
} else {
$('#phanTichPanelBody').html(`
Lỗi! ${escapeHtml(response.error || 'Không thể phân tích điều luật.')}
Vui lòng thử lại sau.
`);
}
},
error: function(xhr, status, error) {
let errorMsg = error;
if (xhr.responseJSON && xhr.responseJSON.error) {
errorMsg = xhr.responseJSON.error;
}
$('#phanTichPanelBody').html(`
Lỗi! Không thể kết nối đến server phân tích.
Chi tiết: ${escapeHtml(errorMsg)}
`);
}
});
}
function openPhanTichModal(address, vbID) {
// Tạo modal nếu chưa có
if ($('#modalPhanTich').length === 0) {
const modalHTML = `
Đang phân tích...
Đang phân tích...
`;
$('body').append(modalHTML);
}
// Reset và hiển thị modal với loading
$('#modalPhanTichBody').html(`
Đang phân tích...
Đang phân tích...
`);
$('#modalPhanTich').modal('show');
// AJAX request
const randomServer = Math.floor(Math.random() * 10) + 1;
$.ajax({
url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/phan.tich.dieu.luat.php',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
address: address,
vb_id: vbID
}),
success: function(response) {
if (response.ok) {
// Render kết quả phân tích
let html = '';
// Header thông tin văn bản
html += '';
html += '
' + escapeHtml(response.ten_van_ban) + '
';
if (response.so_hieu) {
html += 'Số hiệu: ' + escapeHtml(response.so_hieu) + '
';
}
html += 'Điều khoản: ' + escapeHtml(response.address) + '';
html += '';
// Nội dung phân tích (Markdown -> HTML)
html += '';
html += markdownToHtml(response.phan_tich);
html += '
';
// Thông tin usage (nếu có)
if (response.usage) {
html += '';
html += 'Thống kê: ';
html += 'Input tokens: ' + (response.usage.promptTokenCount || 0) + ', ';
html += 'Output tokens: ' + (response.usage.candidatesTokenCount || 0);
html += '
';
}
$('#modalPhanTichBody').html(html);
} else {
$('#modalPhanTichBody').html(`
Lỗi! ${escapeHtml(response.error || 'Không thể phân tích điều luật.')}
Vui lòng thử lại sau.
`);
}
},
error: function(xhr, status, error) {
let errorMsg = error;
if (xhr.responseJSON && xhr.responseJSON.error) {
errorMsg = xhr.responseJSON.error;
}
$('#modalPhanTichBody').html(`
Lỗi! Không thể kết nối đến server phân tích.
Chi tiết: ${escapeHtml(errorMsg)}
`);
}
});
}
// Helpers: show/hide badge cho một - ĐƠN GIẢN
function showPhanTichBadgeForP($p) {
const $badge = $p.find('.badge-phan-tich');
if ($badge.length === 0) return;
$badge.stop(true, true).fadeIn(200);
const $parent = $p.closest('phan, chuong, muc, tieumuc, dieu, khoan, diem');
if ($parent.length > 0) {
$parent.addClass('highlight-border');
}
}
function hidePhanTichBadgeForP($p) {
const $badge = $p.find('.badge-phan-tich');
if ($badge.length === 0) return;
$badge.stop(true, true).fadeOut(200);
const $parent = $p.closest('phan, chuong, muc, tieumuc, dieu, khoan, diem');
if ($parent.length > 0) {
$parent.removeClass('highlight-border');
}
}
// Event delegation cho hover vào p (bao gồm cả khi hover vào bất kỳ element nào trong p)
$(document).on('mouseenter', '#tab_noi_dung_vb p[data-address], #tab_noi_dung_vb p[data-address] *', function(e) {
const $p = $(this).is('p') ? $(this) : $(this).closest('p[data-address]');
if ($p.length) {
showPhanTichBadgeForP($p);
}
});
// Event delegation cho hover ra khỏi p → ẩn badge và xóa viền thẻ cha
$(document).on('mouseleave', '#tab_noi_dung_vb p[data-address]', function(e) {
// Chỉ ẩn khi thực sự rời khỏi p, không phải chỉ di chuyển giữa các child
const $p = $(this);
setTimeout(() => {
if (!$p.is(':hover')) {
hidePhanTichBadgeForP($p);
}
}, 50);
});
// Event delegation cho hover vào badge (cả gốc và fixed) → hiện tooltip
$(document).on('mouseenter', '.badge-phan-tich, .badge-phan-tich-fixed', function() {
const $badge = $(this);
const parentType = $badge.attr('data-parent-type') || 'Nội dung';
if ($badge.find('.badge-tooltip').length === 0) {
const $tooltip = $('Phân tích chi tiết nội dung ' + parentType + ' này');
$badge.append($tooltip);
setTimeout(() => $tooltip.addClass('show'), 10);
}
});
// Event delegation cho hover ra khỏi badge (cả gốc và fixed) → ẩn tooltip
$(document).on('mouseleave', '.badge-phan-tich, .badge-phan-tich-fixed', function() {
const $tooltip = $(this).find('.badge-tooltip');
if ($tooltip.length > 0) {
$tooltip.removeClass('show');
setTimeout(() => $tooltip.remove(), 300);
}
});
// Event delegation cho click badge (cả gốc và fixed) → mở modal
$(document).on('click', '.badge-phan-tich, .badge-phan-tich-fixed', function(e) {
e.stopPropagation();
let address;
if ($(this).hasClass('badge-phan-tich-fixed')) {
// Badge fixed: lấy address từ data-for
address = $(this).attr('data-for');
} else {
// Badge gốc: lấy từ
cha
const $p = $(this).closest('p');
address = $p.attr('data-address');
}
if (address && vbID) {
openPhanTichPanel(address, vbID);
} else {
alert('Không tìm thấy địa chỉ điều luật hoặc ID văn bản!');
}
});
// Attach cho các p đã có sẵn khi hover lần đầu
$(document).on('mouseenter', '#tab_noi_dung_vb p', function() {
const $p = $(this);
if ($p.find('.badge-phan-tich').length === 0 && !$p.attr('data-address')) {
const $parent = $p.closest('phan, chuong, muc, tieumuc, dieu, khoan, diem');
if ($parent.length > 0) {
attachPhanTichBadge($p.parent());
}
}
});
}
});