Hệ thống pháp luật

VĂN PHÒNG CHÍNH PHỦ
-------

CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM
Độc lập - Tự do - Hạnh phúc
---------------

Số: 8575/BC-VPCP

Hà Nội, ngày 01 tháng 11 năm 2023

 

BÁO CÁO

Ý KIẾN CỦA VĂN PHÒNG CHÍNH PHỦ VỀ CHỦ TRƯƠNG, NGUYÊN TẮC SỬA ĐỔI, BỔ SUNG QUYẾT ĐỊNH SỐ 12/2018/QĐ-TTG NGÀY 06 THÁNG 3 NĂM 2018 CỦA THỦ TƯỚNG CHÍNH PHỦ VỀ TIÊU CHÍ LỰA CHỌN, CÔNG NHẬN NGƯỜI CÓ UY TÍN VÀ CHÍNH SÁCH ĐỐI VỚI NGƯỜI CÓ UY TÍN TRONG ĐỒNG BÀO DÂN TỘC THIỂU SỐ

Kính gửi: Chính phủ

Thực hiện Quy chế làm việc của Chính phủ ban hành kèm theo Nghị định số 39/2022/NĐ-CP ngày 18 tháng 6 năm 2022 và ý kiến chỉ đạo của Thủ tướng Chính phủ, Văn phòng Chính phủ (VPCP) xin báo cáo về chủ trương, nguyên tắc sửa đổi, bổ sung Quyết định số 12/2018/QĐ-TTg ngày 06 tháng 3 năm 2018 của Thủ tướng Chính phủ về tiêu chí lựa chọn, công nhận người có uy tín và chính sách đối với người có uy tín trong đồng bào dân tộc thiểu số (sau đây gọi tắt là Quyết định số 12/2018/QĐ-TTg) theo đề xuất của Ủy ban Dân tộc tại Tờ trình số 1909/TTr-UBDT ngày 19 tháng 10 năm 2023 như sau:

I. VỀ CƠ SỞ CHÍNH TRỊ, CƠ SỞ PHÁP LÝ, TRÌNH TỰ, THỦ TỤC, HỒ SƠ

Thực hiện quy định của Luật Ban hành văn bản quy phạm pháp luật (sửa đổi, bổ sung) năm 2020 và Chương trình công tác năm 2023 của Thủ tướng Chính phủ (ban hành kèm theo Quyết định số 48/QĐ-TTg ngày 03 tháng 02 năm 2023 của Thủ tướng Chính phủ), Ủy ban Dân tộc đã xây dựng hồ sơ, tiếp thu ý kiến thẩm định của Bộ Tư pháp (tại Báo cáo thẩm định số 149/BCTĐ-BTP ngày 16 tháng 8 năm 2023 của Bộ Tư pháp), có Tờ trình số 1676/TTr-UBDT ngày 22 tháng 9 năm 2023 trình Thủ tướng Chính phủ ban hành Quyết định sửa đổi, bổ sung một số điều của Quyết định số 12/2018/QĐ-TTg.

Thực hiện Quy chế làm việc của Chính phủ và ý kiến chỉ đạo của Thủ tướng Chính phủ tại Thông báo số 405/TB-VPCP ngày 07 tháng 10 năm 2023 của Văn phòng Chính phủ, Ủy ban Dân tộc đã tiếp thu ý kiến của các Bộ, cơ quan tại cuộc họp ngày 04 tháng 10 năm 2023, hoàn thiện hồ sơ, có Tờ trình số 1909/TTr-UBDT ngày 19 tháng 10 năm 2023 trình Chính phủ về chủ trương, nguyên tắc sửa đổi, bổ sung Quyết định số 12/2018/QĐ-TTg.

VPCP xin báo cáo: Hồ sơ báo cáo Chính phủ của Ủy ban Dân tộc nêu trên đã bảo đảm đúng trình tự, thủ tục và đầy đủ hồ sơ theo quy định của Luật ban hành văn bản quy phạm pháp luật và Quy chế làm việc của Chính phủThẩm quyền cho ý kiến về chủ trương, nguyên tắc sửa đổi, bổ sung một số điều của Quyết định số 12/2018/QĐ-TTg thuộc Chính phủ theo quy định tại khoản 4 Điều 3 Nghị định số 39/2022/NĐ-CP ngày 18 tháng 6 năm 2022 của Chính phủ, phù hợp với ý kiến kết luận của Phó Thủ tướng Chính phủ Trần Lưu Quang và ý kiến của các Bộ, ngành (trong đó có Bộ Tư pháp) tại cuộc họp ngày 04 tháng 10 năm 2023 nêu trên.

II. VỀ CƠ SỞ THỰC TIỄN VÀ SỰ CẦN THIẾT

Về cơ bản, VPCP thống nhất với Ủy ban Dân tộc về sự cần thiết sửa đổi, bổ sung Quyết định số 12/2018/QĐ-TTg tiếp tục thể chế hóa các quan điểm, chủ trương của ĐảngIII. VỀ CÁC NỘI DUNG CHÍNH SÁCH DỰ KIẾN SỬA ĐỔI

Ủy ban Dân tộc đề xuất 05 nhóm nội dung dự kiến sửa đổi, bổ sung Quyết định số 12/2018/QĐ-TTg, gồm:

1. Về đối tượng, điều kiện, số lượng công nhận người có uy tín

a) Sửa đổi đối tượng lựa chọn người có uy tín tại khoản 2 Điều 4 Quyết định số 12/2018/QĐ-TTg: “Là công dân Việt Nam, đang cư trú ở các thôn có đồng bào dân tộc thiểu số sinh sống thành cộng đồng, đáp ứng các tiêu chí theo quy định, được xem xét để lựa chọn người có uy tín” để bảo đảm không bỏ sót đối tượng.

b) Sửa đổi, bổ sung điều kiện, số lượng lựa chọn người có uy tín để phù hợp quy định về phân định vùng đồng bào DTTS và MN- Mỗi thôn thuộc xã, phường, thị trấn (sau đây gọi chung là xã) vùng đồng bào DTTS và MN; Thôn đáp ứng tiêu chí thôn thuộc vùng đồng bào DTTS và MN theo quy định của Thủ tướng Chính phủ được lựa chọn, công nhận 01 (một) người có uy tín.

- Thôn không thuộc vùng đồng bào dân tộc thiểu số nhưng có đông đồng bào dân tộc thiểu số sinh sống thành cộng đồng, Chủ tịch Ủy ban nhân dân cấp huyện xem xét, quyết định công nhận 01 người có uy tín/thôn phù hợp với tình hình thực tiễn của địa phương;

- Trường hợp thôn thành lập mới do sáp nhập các thôn theo quy định của cấp có thẩm quyền, Chủ tịch Ủy ban nhân dân huyện, quận, thị xã, thành phố trực thuộc tỉnh (sau đây gọi chung là huyện) xem xét, quyết định số lượng người có uy tín được lựa chọn, công nhận nhưng không quá tổng số lượng thôn được sáp nhập.

2. Về chế độ, chính sách đối với người có uy tín

a) Về chế độ cung cấp thông tin, sửa đổi điểm b khoản 1 Điều 5 Quyết định số 12/2018/QĐ-TTg về chế độ cấp ấn phẩm báo cho người có uy tín bảo đảm khách quan, minh bạch, tiết kiệm, hiệu quả; bổ sung điểm c khoản 1 Điều 4 Quyết định số 12/2018/QĐ-TTg về cung cấp thông tin, kỹ năng khai thác, sử dụng, xử lý thông tin trên internet, mạng xã hội bảo đảm phù hợp tình hình thực tiễn và xu thế chuyển đổi số.

b) Về chế độ hỗ trợ vật chất, động viên tinh thần, sửa đổi, bổ sung khoản 2 Điều 5 của Quyết định số 12/2018/QĐ-TTg bảo đảm phù hợp thực tiễn triển khai ở các cấp từ TW đến địa phương và không tăng định mức chi.

c) Về biểu dương, tôn vinh, khen thưởng người có uy tín, bổ sung quy định: “Định kỳ tổ chức Hội nghị biểu dương, khen thưởng, tôn vinh người có uy tín tiêu biểu trong vùng đồng bào dân tộc thiểu số 5 năm/lần đối với cấp Trung ương và cấp tỉnh. Riêng đối với cấp huyện sẽ phân cấp cho các địa phương lựa chọn, quyết định hình thức, thời gian để tổ chức thực hiện bảo đảm phù hợp với số lượng người có uy tín và tình hình thực tiễn trên địa bàn” để tăng cường phân cấp và tăng tính chủ động cho cấp huyện trong thực hiện công tác thi đua, khen thưởng đối với người có uy tín theo tình hình thực tiễn của địa phương.

d) Bổ sung mức chi thăm hỏi, hỗ trợ người có uy tín khi các đồng chí Lãnh đạo Đảng, Nhà nước và Ủy ban Dân tộc đi thăm, làm việc tại các địa phương để phù hợp thực tiễn triển khai.

3. Về quy trình, thủ tục công nhận, đưa ra và thay thế, bổ sung người có uy tín: Sửa đổi quy trình, thủ tục và thực hiện phân cấp, giao thẩm quyền quyết định công nhận, đưa ra và thay thế, bổ sung người có uy tín cho Chủ tịch UBND cấp huyện theo quy định tại Quyết định số 1015/QĐ-TTg ngày 30/8/2022 của Thủ tướng Chính phủ.

4. Về kinh phí và nguồn kinh phí thực hiện

- Sửa đổi quy định về kinh phí thực hiện theo cơ chế hỗ trợ có mục tiêu ngân sách Trung ương cho ngân sách địa phương đối với các địa phương khó khăn hoặc chưa tự cân đối được ngân sách thực hiện các chính sách an sinh xã hội trong từng thời kỳ ổn định ngân sách được cấp có thẩm quyền phê duyệt để thực hiện các chế độ, chính sách cung cấp thông tin và hỗ trợ vật chất, động viên tinh thần đối với người có uy tín (đối với khoản 1 và khoản 2 của Quyết định số 12/2018/QĐ-TTg).

- Sửa đổi quy định về trách nhiệm của các địa phương trong việc bố trí, cân đối trong dự toán ngân sách hằng năm của các tỉnh, thành phố trực thuộc trung ương theo phân cấp quy định của Luật Ngân sách nhà nước để thực hiện các chế độ, chính sách quy định tại Quyết định này, các cơ chế, chính sách khác do địa phương ban hành để hỗ trợ phát huy vai trò của người có uy tín và các hoạt động quản lý, tổ chức triển khai thực hiện Quyết định

5. Về trách nhiệm của Ủy ban Dân tộc và các địa phương

a) Đối với Ủy ban Dân tộc

- Nội dung sửa đổi, bổ sung: Giao Ủy ban Dân tộc có trách nhiệm hướng dẫn và thực hiện cấp ấn phẩm báo theo các quy định hiện hành, đảm bảo phù hợp với tình hình thực tiễn và khả năng tiếp cận của đối tượng thụ hưởng; tổ chức thăm hỏi, thực hiện các chế độ, chính sách theo trách nhiệm được giao tại Quyết định này.

b) Đối với các tỉnh, thành phố trực thuộc Trung ương

- Nội dung sửa đổi, bổ sung: Giao các tỉnh, thành phố có trách nhiệm chỉ đạo, hướng dẫn, phân công quản lý, giao nhiệm vụ cho các cơ quan, đơn vị trực thuộc tổ chức thực hiện đầy đủ, kịp thời các chế độ, chính sách đối với người có uy tín trên địa bàn theo quy định tại Quyết định này; Ban hành theo thẩm quyền cơ chế, chính sách khác để phát huy vai trò của người có uy tín trong việc thực hiện chính sách dân tộc ở địa bàn dân cư bảo đảm phù hợp với điều kiện kinh tế - xã hội của địa phương.

VPCP xin báo cáo: 05 nhóm nội dung chính sách dự kiến sửa đổi, bổ sung đã bảo đảm tiếp thu đầy đủ ý kiến chỉ đạo của Phó Thủ tướng Chính phủ Trần Lưu Quang và ý kiến của các Bộ, cơ quan: Tài chính, Tư pháp, Nội vụ, VPCP tại cuộc họp ngày 04 tháng 10 năm 2023 (Thông báo kết luận số 405/TB- VPCP ngày 07 tháng 10 năm 2023 của Văn phòng Chính phủ), phù hợp quy định tại Điều 12 Nghị định số 05/2011/NĐ-CP ngày 14 tháng 01 năm 2011 của Chính phủ “Người có uy tín ở vùng dân tộc thiểu số được bồi dưỡng, tập huấn, được hưởng chế độ đãi ngộ và các ưu đãi khác để phát huy vai trò trong việc thực hiện chính sách dân tộc ở địa bàn dân cư, phù hợp với điều kiện kinh tế - xã hội của địa phương”, có đánh giá tác động cụ thể đối với từng nội dung chính sách và phù hợp tình hình thực tiễnViệc sửa đổi, bổ sung 05 nhóm nội dung chính sách nêu trên không làm phát sinh thêm chính sách dân tộc mới, bảo đảm quyền lợi chính đáng, hợp pháp cho người có uy tín trong đồng bào dân tộc thiểu số để phát huy vai trò trong việc thực hiện chính sách dân tộc ở địa bàn dân cư và phù hợp tình hình thực tiễn của các địa phương; đẩy mạnh cải cách thủ tục hành chính và tăng cường phân cấp, phân quyền cho các cấp cơ sở.

IV. VỀ DỰ KIẾN NGUỒN LỰC THI HÀNH

Ủy ban Dân tộc đã đánh giá nguồn lực ngân sách nhà nước cần bổ sung để thực hiện các chính sách sau khi sửa đổi, bổ sung là không lớn do số lượng đối tượng thụ hưởng thay đổi không đáng kể (khoảng 1.500 người) và mức chi tối đa của các chính sách không thay đổi. Tuy nhiên, có thể có sự điều chỉnh cơ cấu nguồn vốn thực hiện chính sách giữa ngân sách trung ương và ngân sách địa phương do thực hiện cơ chế hỗ trợ có mục tiêu từ ngân sách trung ương cho ngân sách địa phương để thực hiện các chính sách an sinh xã hội trong từng thời kỳ ổn định ngân sách được cấp có thẩm quyền phê duyệt.

Trên đây là ý kiến về chủ trương, nguyên tắc sửa đổi, bổ sung Quyết định số 12/2018/QĐ-TTg ngày 06 tháng 3 năm 2018 của Thủ tướng Chính phủ về tiêu chí lựa chọn, công nhận người có uy tín và chính sách đối với người có uy tín trong đồng bào dân tộc thiểu số (sau đây gọi tắt là Quyết định số 12/2018/QĐ-TTg) theo đề xuất của Ủy ban Dân tộc tại Tờ trình số 1909/TTr-UBDT ngày 19 tháng 10 năm 2023, Văn phòng Chính phủ xin báo cáo Chính phủ xem xét, quyết nghị./.

 


Nơi nhận:
- Như trên;
- Các thành viên Chính phủ;
- VPCP: BTCN, các PCN, các Vụ: KTTH, PL, KGVX, TCCV, NC, TH; Cục KSTTHC;
- Lưu: VT, QHĐP(2) S.Tùng.

KT. BỘ TRƯỞNG, CHỦ NHIỆM
PHÓ CHỦ NHIỆM




Cao Huy

 



lồng nhau (bên trong) hay không const memberID = 0; const vbID = '0b35b84e0f566bdd7f52946f7f67e1bf'; // State management cho phân tích let isAnalyzing = false; // Có đang phân tích không let currentAnalyzingAddress = null; // Address đang được phân tích let currentAnalyzingElement = null; // Element đang được phân tích let currentAnalyzingBadge = null; // Badge của element đang phân tích let isPanelOpen = false; // Panel phân tích có đang mở không console.log('Tiện ích loaded - memberID:', memberID, 'vbID:', vbID); function isInViewportAndTabNoiDung(element) { const rect = element.getBoundingClientRect(); const buffer = 1500; // Buffer to preload content below the viewport (approx. 50+ lines) const viewHeight = window.innerHeight || document.documentElement.clientHeight; const isInViewport = rect.top < viewHeight + buffer && rect.bottom >= 0; const isInTabNoiDung = $(element).closest('#tab_noi_dung_vb').length > 0; return isInViewport && isInTabNoiDung; } function getAddress(element) { const validTags = ['trichyeu', 'cancu', 'phan', 'chuong', 'muc', 'tieumuc', 'dieu', 'khoan', 'diem']; const $parent = $(element).closest(validTags.join(',')); if (!$parent.length) { return null; } let addr = $parent.attr('address'); if (!addr && $parent.prop('tagName').toLowerCase() === 'trichyeu') { addr = 'trichyeu'; $parent.attr('address', addr); } return addr || null; } function processTnplClasses($element) { const tnplKeysInLine = new Set(); // key = slug hoặc text (thường là slug) $element.find('tnpl').each(function () { const $tnpl = $(this); const tnplSlug = ($tnpl.attr('slug') || '').trim().toLowerCase(); const tnplKey = tnplSlug || $tnpl.text().trim().toLowerCase(); // Đã xử lý trong cùng dòng => bỏ if (tnplKeysInLine.has(tnplKey)) { return; } tnplKeysInLine.add(tnplKey); let tnplExists = false; // Chỉ duyệt các tnpl đã được tô màu (class on) $('tnpl.on').each(function () { const $existingTnpl = $(this); const existingSlug = ($existingTnpl.attr('slug') || '').trim().toLowerCase(); const existingKey = existingSlug || $existingTnpl.text().trim().toLowerCase(); if ( existingKey === tnplKey && isInViewportAndTabNoiDung($existingTnpl[0]) ) { tnplExists = true; return false; // break each } }); if (!tnplExists) { $tnpl.addClass('on'); } }); } function processQueue() { while (pendingRequests < maxConcurrentRequests && requestQueue.length > 0) { const task = requestQueue.shift(); pendingRequests++; task() .always(() => { pendingRequests--; processQueue(); }); } } function processVisibleParagraphs() { try { $('#tab_noi_dung_vb p:not([is-posted="1"])').each(function () { let $element = $(this); if (isInViewportAndTabNoiDung(this)) { $element.attr('is-posted', '1'); $element.addClass('loading-content'); let p_innerHTML = $element.html(); let address = null; if (cac_cau_hinh.loai_noi_dung.includes('docs')) { address = getAddress($element); } const isSubP = $element.parents('p').length > 0; if (isSubP && !allow_sub_p) { $element.removeClass('loading-content'); return; // Không gửi nếu không cho phép } const postData = { p_content: p_innerHTML, cac_cau_hinh, address }; if (isSubP && allow_sub_p) { postData.sub_p = 1; } requestQueue.push(() => $.ajax({ url: '//tnpl' + (Math.floor(Math.random() * 10) + 1) + '.hethongphapluat.com/tien-ich/tim.tien.ich.php', type: 'POST', data: postData, success: function(response) { $element.html(response); processTnplClasses($element); // Đợi CTTD và các tiện ích load xong rồi mới attach badge if (memberID === 4 && typeof attachPhanTichBadge === 'function') { setTimeout(function() { // $element chính là thẻ p, kiểm tra và attach badge trực tiếp const $parent = $element.closest('phan, chuong, muc, tieumuc, dieu, khoan, diem'); if ($parent.length > 0 && $parent.find('.badge-phan-tich[data-for="' + $parent.attr('address') + '"]').length === 0) { 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()); // Append badge VÀO PARENT (dieu, khoan,...) thay vì vào

để tránh xung đột CTTD const $badge = $('Phân tích'); $parent.append($badge); // Thêm class để CSS set position: relative CHỈ cho element có badge $parent.addClass('has-phan-tich-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) { // Modal cảnh báo function showWarningModal(message) { // Tạo modal nếu chưa có if ($('#warningModal').length === 0) { const modalHTML = `

`; $('body').append(modalHTML); } $('#warningModalBody').html('

' + message + '

'); $('#warningModal').modal('show'); } // 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) { const address = $parent.attr('address'); // Kiểm tra đã có badge cho parent này chưa if ($parent.find('.badge-phan-tich[data-for="' + address + '"]').length === 0) { // Lưu address vào data attribute $p.attr('data-address', address); // Lấy tên loại thẻ cho tooltip const parentType = getParentTypeName($parent.prop('tagName').toLowerCase()); // Append badge vào PARENT, không vào

const $badge = $('Phân tích'); $parent.append($badge); // Thêm class để CSS set position: relative CHỈ cho element có badge $parent.addClass('has-phan-tich-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, '

$1
'); html = html.replace(/^## (.*$)/gim, '

$1

'); html = html.replace(/^# (.*$)/gim, '

$1

'); // Bold html = html.replace(/\*\*(.*?)\*\*/g, '$1'); // Italic html = html.replace(/\*(.*?)\*/g, '$1'); // Blockquote html = html.replace(/^> (.*$)/gim, '
$1
'); html = html.replace(/^> (.*$)/gim, '
$1
'); // Lists (unordered) html = html.replace(/^\- (.*$)/gim, '
  • $1
  • '); html = html.replace(/(
  • .*<\/li>)/s, '
      $1
    '); // Lists (ordered) html = html.replace(/^\d+\. (.*$)/gim, '
  • $1
  • '); // Line breaks và paragraphs html = html.split('\n\n').map(para => { para = para.trim(); if (para.startsWith('')) { 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 fixed position function closePhanTichPanel() { const $panel = $('#phanTichPanel'); if ($panel.length) { $panel.removeClass('show'); setTimeout(() => { $panel.remove(); }, 300); } // Reset highlight và badge khi đóng panel if (currentAnalyzingElement) { currentAnalyzingElement.removeClass('highlight-border-persistent'); } if (currentAnalyzingBadge) { currentAnalyzingBadge.text('Phân tích').removeClass('analyzing'); currentAnalyzingBadge.data('analyzing', false); currentAnalyzingBadge.data('hovering', false); currentAnalyzingBadge.css({display: 'none'}); // Ẩn badge khi đóng } // Reset tất cả các element khác (trong trường hợp có nhiều) $('#tab_noi_dung_vb .highlight-border-persistent').removeClass('highlight-border-persistent'); $('#tab_noi_dung_vb .badge-phan-tich-container.analyzing').each(function() { $(this).text('Phân tích').removeClass('analyzing').data('analyzing', false); }); // Check: có CTTD pointer đang mở không? const $visiblePointers = $('.pointer:visible'); const hadCTTDOpen = $visiblePointers.length > 0; if (hadCTTDOpen) { // CÓ CTTD đang mở → giữ rightdocinfo ẩn console.log('ℹ️ CTTD pointer is visible, keeping rightdocinfo hidden'); } else { // KHÔNG có CTTD → SHOW lại rightdocinfo const $rightdocinfo = $('#rightdocinfo'); if ($rightdocinfo.length > 0) { $rightdocinfo.show(); console.log('✅ Showing rightdocinfo back (no CTTD pointer)'); } } // Reset state isAnalyzing = false; currentAnalyzingAddress = null; currentAnalyzingElement = null; currentAnalyzingBadge = null; isPanelOpen = false; // Đánh dấu panel đã đóng console.log('✅ Panel closed, state reset, isPanelOpen = false'); } // Panel đã song song với rightdocinfo → không cần MutationObserver nữa console.log('✅ Panel running in standalone mode (parallel to rightdocinfo)'); // Resize event để update panel dimensions khi browser resize let resizeTimer; $(window).on('resize', function() { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { if (isPanelOpen && $('#phanTichPanel').length > 0) { updatePanelDimensions(); console.log('✅ Panel dimensions updated on window resize'); } }, 250); // Debounce 250ms }); // Function để detect và áp dụng dimensions từ rightdocinfo function updatePanelDimensions() { const $panel = $('#phanTichPanel'); const $rightdocinfo = $('#rightdocinfo'); const $docRightCol = $('#doc-right-col'); if ($panel.length === 0) return; // Ưu tiên: doc-right-col > rightdocinfo let $reference = $docRightCol.length > 0 ? $docRightCol : $rightdocinfo; // Nếu reference bị ẩn (display:none), tạm show để get dimensions let wasHidden = false; if ($reference.length > 0 && !$reference.is(':visible')) { wasHidden = true; $reference.css('visibility', 'hidden').show(); } if ($reference.length > 0) { const refWidth = $reference.outerWidth(); const refOffset = $reference.offset(); if (refWidth && refOffset) { // Tính vị trí right từ edge màn hình const windowWidth = $(window).width(); const rightPosition = windowWidth - (refOffset.left + refWidth); $panel.css({ 'width': refWidth + 'px', 'right': rightPosition + 'px' }); console.log('✅ Panel dimensions updated:', { width: refWidth + 'px', right: rightPosition + 'px', reference: $reference.attr('id') }); } else { console.warn('⚠️ Could not get dimensions from reference element'); } // Restore trạng thái hidden nếu cần if (wasHidden) { $reference.hide().css('visibility', ''); } } else { console.warn('⚠️ No reference element found for panel dimensions'); } } function openPhanTichPanel(address, vbID) { console.log('openPhanTichPanel called with address:', address); console.log('Current state - isAnalyzing:', isAnalyzing, 'currentAnalyzingAddress:', currentAnalyzingAddress); // Kiểm tra nếu đang phân tích element khác if (isAnalyzing && currentAnalyzingAddress && currentAnalyzingAddress !== address) { const currentName = getElementDisplayName(currentAnalyzingAddress); console.warn('Already analyzing:', currentAnalyzingAddress, 'Cannot analyze:', address); showWarningModal('Vui lòng chờ phân tích ' + currentName + ' hoàn tất...'); return; } // Nếu đang phân tích cùng element → không làm gì if (isAnalyzing && currentAnalyzingAddress === address) { console.log('Already analyzing this element, ignoring duplicate request'); return; } // Panel sẽ fixed position append vào body const $rightdocinfo = $('#rightdocinfo'); // KHÔNG ẨN CTTD pointer - cho phép CTTD và panel cùng tồn tại console.log('Panel opening, CTTD pointer can stay visible'); // ẨN rightdocinfo để tiết kiệm không gian if ($rightdocinfo.length > 0) { $rightdocinfo.hide(); console.log('Hidden rightdocinfo to save space'); } // XÓA highlight persistent của TẤT CẢ elements cũ trước $('#tab_noi_dung_vb .highlight-border-persistent').removeClass('highlight-border-persistent'); console.log('Removed all previous highlight-border-persistent'); // Tìm element đang được phân tích và badge của nó const $element = $('[address="' + address + '"]'); const $badge = $element.find('.badge-phan-tich-container[data-for="' + address + '"]').first(); // Set state isAnalyzing = true; currentAnalyzingAddress = address; currentAnalyzingElement = $element; currentAnalyzingBadge = $badge; console.log('State set:', { isAnalyzing: isAnalyzing, currentAnalyzingAddress: currentAnalyzingAddress, elementFound: $element.length > 0, badgeFound: $badge.length > 0 }); // Thêm highlight persistent cho element MỚI này $element.addClass('highlight-border-persistent'); // Thay đổi badge thành "Đang phân tích..." và giữ hiển thị if ($badge.length > 0) { $badge.text('Đang phân tích...').addClass('analyzing'); // Giữ badge hiển thị và ở đúng vị trí $badge.data('analyzing', true); $badge.data('hovering', true); // Prevent auto-hide console.log('Badge set to analyzing state'); // Đảm bảo badge hiển thị ở đúng vị trí (vì dùng position: fixed) showPhanTichBadgeForParent($element); } // Tạo panel nếu chưa có - fixed position append vào body if ($('#phanTichPanel').length === 0) { const panelHTML = `
    Phân tích điều luật
    Đang phân tích...

    Đang phân tích...

    `; // Append vào body (fixed position không cần container cụ thể) $('body').append(panelHTML); // Detect width từ rightdocinfo và áp dụng cho panel updatePanelDimensions(); // Trigger show và set flag setTimeout(() => { $('#phanTichPanel').addClass('show'); isPanelOpen = true; console.log('✅ Panel opened (fixed position), isPanelOpen = true'); }, 10); } else { $('#phanTichPanelBody').html(`
    Đang phân tích...

    Đang phân tích...

    `); // Update dimensions khi re-open updatePanelDimensions(); $('#phanTichPanel').addClass('show'); isPanelOpen = true; console.log('✅ Panel re-opened (fixed position), isPanelOpen = true'); } // 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(); }); // Bind nút refresh - phân tích lại $(document).off('click.refreshPhanTich').on('click.refreshPhanTich', '.btn-refresh-phan-tich', function(e) { e.preventDefault(); e.stopPropagation(); const $btn = $(this); const $icon = $btn.find('i'); // Disable button và thêm animation $btn.prop('disabled', true); $icon.addClass('fa-spin'); console.log('🔄 Refresh: Phân tích lại address:', address); // Show loading trong panel $('#phanTichPanelBody').html(`
    Đang phân tích lại...

    Đang xóa cache và phân tích lại...

    `); // Gọi API xóa cache trước deletePhanTichCache(address, vbID, function(deleteSuccess) { if (deleteSuccess) { console.log('✅ Cache deleted, now re-analyzing...'); // Sau khi xóa cache, gọi lại API phân tích callPhanTichAPI(address, vbID, function() { // Enable lại button $btn.prop('disabled', false); $icon.removeClass('fa-spin'); }); } else { console.error('❌ Failed to delete cache'); $('#phanTichPanelBody').html(` `); $btn.prop('disabled', false); $icon.removeClass('fa-spin'); } }); }); // Gọi API phân tích (dùng function helper) callPhanTichAPI(address, vbID); } // Helper: Gọi API phân tích (tách riêng để dùng lại) function callPhanTichAPI(address, vbID, callback) { 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) { console.log('Analysis complete for:', address, response); // Reset badge về trạng thái bình thường (nhưng vẫn hiển thị) if (currentAnalyzingBadge) { currentAnalyzingBadge.text('Phân tích').removeClass('analyzing'); currentAnalyzingBadge.data('analyzing', false); console.log('Badge reset to normal state'); } // Reset state analyzing để có thể phân tích element khác isAnalyzing = false; console.log('State reset: isAnalyzing = false, can analyze other elements now'); 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) + ''; if (response.from_cache) { html += ' Cache'; } 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(` `); } if (callback) callback(); }, error: function(xhr, status, error) { console.error('Analysis error:', error); // Reset badge về trạng thái bình thường if (currentAnalyzingBadge) { currentAnalyzingBadge.text('Phân tích').removeClass('analyzing'); currentAnalyzingBadge.data('analyzing', false); } // Reset state analyzing isAnalyzing = false; let errorMsg = error; if (xhr.responseJSON && xhr.responseJSON.error) { errorMsg = xhr.responseJSON.error; } $('#phanTichPanelBody').html(` `); if (callback) callback(); } }); } // Helper: Xóa cache phân tích function deletePhanTichCache(address, vbID, callback) { const randomServer = Math.floor(Math.random() * 10) + 1; $.ajax({ url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/delete.phan.tich.cache.php', type: 'POST', contentType: 'application/json', timeout: 10000, data: JSON.stringify({ address: address, vb_id: vbID }), success: function(response) { console.log('Delete cache response:', response); if (callback) callback(response.ok || false); }, error: function(xhr, status, error) { console.error('Delete cache error:', error); if (callback) callback(false); } }); } // Helper: Lấy tên hiển thị của element từ address function getElementDisplayName(address) { if (!address) return 'nội dung'; const $element = $('[address="' + address + '"]'); if ($element.length === 0) return address; // Parse address: vd "dieu_3_khoan_29" -> "Khoản 29 Điều 3" // Address format: lớn đến nhỏ (phan > chuong > muc > dieu > khoan > diem) const parts = address.split('_'); const displayParts = []; for (let i = 0; i < parts.length; i += 2) { if (i + 1 < parts.length) { const type = getParentTypeName(parts[i]); const num = parts[i + 1]; displayParts.push(type + ' ' + num); } } // Reverse để hiển thị từ nhỏ đến lớn: "Khoản 29 Điều 3" (thay vì "Điều 3 Khoản 29") return displayParts.reverse().join(' '); } function openPhanTichModal(address, vbID) { // Tạo modal nếu chưa có if ($('#modalPhanTich').length === 0) { const modalHTML = ` `; $('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(` `); } }, error: function(xhr, status, error) { let errorMsg = error; if (xhr.responseJSON && xhr.responseJSON.error) { errorMsg = xhr.responseJSON.error; } $('#modalPhanTichBody').html(` `); } }); } // Helpers: show/hide badge cho parent element (dieu, khoan,...) với position: fixed function showPhanTichBadgeForParent($parent) { // Lấy badge CỦA CHÍNH parent này (match data-for với address của parent) const parentAddress = $parent.attr('address'); const $badge = $parent.find('.badge-phan-tich-container[data-for="' + parentAddress + '"]').first(); if ($badge.length === 0) { console.warn('No badge found for parent:', parentAddress); return; } // Ẩn TẤT CẢ các badge khác để tránh overlap $('.badge-phan-tich-container').not($badge).each(function() { const $otherBadge = $(this); // Chỉ ẩn badge KHÔNG đang analyzing if (!$otherBadge.data('analyzing')) { $otherBadge.css({display: 'none'}); } }); // Show badge tạm để tính width $badge.css({display: 'inline-block', opacity: 0, visibility: 'hidden'}); const badgeWidth = $badge.outerWidth(); // Tính toán vị trí fixed dựa trên offset của parent const offset = $parent.offset(); const scrollTop = $(window).scrollTop(); const scrollLeft = $(window).scrollLeft(); // Position badge top-right của parent và show $badge.css({ display: 'inline-block', visibility: 'visible', opacity: 1, top: (offset.top - scrollTop) + 'px', left: (offset.left + $parent.outerWidth() - badgeWidth - scrollLeft - 5) + 'px' // -5px padding }); console.log('Showing badge for:', parentAddress, 'at position:', $badge.css('top'), $badge.css('left')); $parent.addClass('highlight-border'); } function hidePhanTichBadgeForParent($parent) { const $badge = $parent.find('.badge-phan-tich-container').first(); if ($badge.length === 0) return; $badge.css({display: 'none', opacity: 0}); $parent.removeClass('highlight-border'); } // Biến lưu element đang hover let currentHoveredElement = null; let hoverDebounceTimer = null; // Dùng mousemove để track chính xác element nào đang được hover $(document).on('mousemove', '#tab_noi_dung_vb', function(e) { // Tìm element gần nhất (phan, chuong, muc, dieu, khoan, diem) tại vị trí chuột const $target = $(e.target).closest('phan, chuong, muc, tieumuc, dieu, khoan, diem'); if ($target.length === 0) { // Không hover vào element nào return; } const address = $target.attr('address'); // Nếu đang hover vào cùng element → skip if (currentHoveredElement && currentHoveredElement[0] === $target[0]) { return; } // Clear debounce timer cũ if (hoverDebounceTimer) { clearTimeout(hoverDebounceTimer); } // Debounce để tránh trigger quá nhiều hoverDebounceTimer = setTimeout(function() { // Element thay đổi console.log('Hover changed to:', address); // Set flag hovering cho element mới $target.data('hovering', true); // Cancel timeout nếu có const timeoutId = $target.data('hideTimeout'); if (timeoutId) { clearTimeout(timeoutId); } // Ẩn badge của TẤT CẢ elements khác $('#tab_noi_dung_vb phan, #tab_noi_dung_vb chuong, #tab_noi_dung_vb muc, #tab_noi_dung_vb tieumuc, #tab_noi_dung_vb dieu, #tab_noi_dung_vb khoan, #tab_noi_dung_vb diem') .not($target) .each(function() { const $el = $(this); // Chỉ xóa highlight-border, KHÔNG xóa highlight-border-persistent $el.removeClass('highlight-border'); // Ẩn badge nếu KHÔNG đang analyzing const $badge = $el.find('.badge-phan-tich-container'); if ($badge.length && !$badge.data('analyzing')) { $badge.css({display: 'none'}); } }); // Attach badge nếu chưa có if (address && $target.find('.badge-phan-tich-container[data-for="' + address + '"]').length === 0) { const parentType = getParentTypeName($target.prop('tagName').toLowerCase()); const $badge = $('Phân tích'); console.log('Creating badge for address:', address, 'parentType:', parentType); $target.append($badge); $target.addClass('has-phan-tich-badge'); } // Show badge cho element này if ($target.find('.badge-phan-tich-container').length > 0) { showPhanTichBadgeForParent($target); } // Update current hovered element currentHoveredElement = $target; }, 50); // Debounce 50ms }); // Event delegation cho hover ra khỏi #tab_noi_dung_vb $(document).on('mouseleave', '#tab_noi_dung_vb', function(e) { // Clear current hovered element currentHoveredElement = null; // Ẩn tất cả badge không đang analyzing sau một khoảng thời gian setTimeout(function() { if (currentHoveredElement === null) { // Chỉ ẩn nếu thực sự không hover vào element nào $('#tab_noi_dung_vb phan, #tab_noi_dung_vb chuong, #tab_noi_dung_vb muc, #tab_noi_dung_vb tieumuc, #tab_noi_dung_vb dieu, #tab_noi_dung_vb khoan, #tab_noi_dung_vb diem') .each(function() { const $el = $(this); const $badge = $el.find('.badge-phan-tich-container'); if ($badge.length && !$badge.data('analyzing')) { $badge.css({display: 'none'}); } }); console.log('Mouse left tab_noi_dung_vb, hiding all badges'); } }, 300); }); // Event delegation cho hover ra khỏi parent (giữ lại cho badge behavior) $(document).on('mouseleave', '#tab_noi_dung_vb phan, #tab_noi_dung_vb chuong, #tab_noi_dung_vb muc, #tab_noi_dung_vb tieumuc, #tab_noi_dung_vb dieu, #tab_noi_dung_vb khoan, #tab_noi_dung_vb diem', function(e) { const $parent = $(this); const parentAddress = $parent.attr('address'); const $badge = $parent.find('.badge-phan-tich-container[data-for="' + parentAddress + '"]').first(); // Set flag parent not hovering $parent.data('hovering', false); // Nếu badge đang analyzing thì KHÔNG ẩn, GIỮ hiển thị if ($badge.length > 0 && $badge.data('analyzing')) { console.log('Badge is analyzing, keep visible'); return; } // Delay để có thời gian di chuột vào badge const timeoutId = setTimeout(() => { // Chỉ ẩn nếu cả parent và badge đều không hover và không analyzing if ($badge.length > 0 && !$parent.data('hovering') && !$badge.data('hovering') && !$badge.data('analyzing')) { hidePhanTichBadgeForParent($parent); } }, 300); // Tăng lên 300ms $parent.data('hideTimeout', timeoutId); }); // Hover vào badge → giữ hiển thị $(document).on('mouseenter', '.badge-phan-tich-container', function(e) { e.stopPropagation(); const $badge = $(this); const $parent = $badge.parent(); $badge.data('hovering', true); // Cancel timeout của parent const timeoutId = $parent.data('hideTimeout'); if (timeoutId) { clearTimeout(timeoutId); } }); // Hover ra khỏi badge → ẩn nếu không hover parent $(document).on('mouseleave', '.badge-phan-tich-container', function(e) { const $badge = $(this); $badge.data('hovering', false); const $parent = $badge.parent(); // Nếu badge đang analyzing thì KHÔNG ẩn, GIỮ hiển thị if ($badge.data('analyzing') || $badge.hasClass('analyzing')) { console.log('Badge is analyzing on mouseleave, keep visible'); return; } setTimeout(() => { // Chỉ ẩn nếu cả parent và badge đều không hover và không analyzing if (!$parent.data('hovering') && !$badge.data('hovering') && !$badge.data('analyzing') && !$badge.hasClass('analyzing')) { hidePhanTichBadgeForParent($parent); } }, 300); }); // Event delegation cho hover vào badge → hiện tooltip $(document).on('mouseenter', '.badge-phan-tich, .badge-phan-tich-container, .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 → ẩn tooltip $(document).on('mouseleave', '.badge-phan-tich, .badge-phan-tich-container, .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 → mở panel $(document).on('click', '.badge-phan-tich, .badge-phan-tich-container, .badge-phan-tich-fixed', function(e) { e.preventDefault(); e.stopPropagation(); const $badge = $(this); console.log('Badge clicked! Element:', $badge[0]); console.log('Badge parent:', $badge.parent().prop('tagName'), $badge.parent().attr('address')); console.log('Badge data-for:', $badge.attr('data-for')); console.log('Badge data-parent-type:', $badge.attr('data-parent-type')); // Nếu badge đang analyzing thì không cho click if ($badge.hasClass('analyzing') || $badge.data('analyzing')) { console.log('Badge is analyzing, click ignored'); return; } // Lấy address từ data-for attribute const address = $badge.attr('data-for'); console.log('Will analyze address:', address, 'vbID:', vbID); if (address && vbID) { openPhanTichPanel(address, vbID); } else { console.error('Missing address or vbID', {address, vbID}); showWarningModal('Không tìm thấy địa chỉ điều luật hoặc ID văn bản!'); } }); // Ẩn badge khi click vào CTTD $(document).on('click', 'cttd.chuthichtudong span, dctk span, dctd span', function(e) { console.log('CTTD clicked'); // Ẩn TẤT CẢ badge KHÔNG đang analyzing $('.badge-phan-tich-container').each(function() { const $badge = $(this); if (!$badge.data('analyzing') && !$badge.hasClass('analyzing')) { $badge.css({display: 'none'}); console.log('Hiding badge:', $badge.attr('data-for')); } }); }); // Update badge position khi scroll hoặc resize (vì dùng position: fixed) function updateBadgePositions() { $('.badge-phan-tich-container:visible').each(function() { const $badge = $(this); const $parent = $badge.parent(); // Cập nhật position nếu parent đang hover HOẶC badge đang analyzing if ($parent.length && ($parent.is(':hover') || $badge.data('analyzing'))) { // Re-calculate position const offset = $parent.offset(); const scrollTop = $(window).scrollTop(); const scrollLeft = $(window).scrollLeft(); const badgeWidth = $badge.outerWidth(); $badge.css({ top: (offset.top - scrollTop) + 'px', left: (offset.left + $parent.outerWidth() - badgeWidth - scrollLeft - 5) + 'px' }); } }); } $(window).on('scroll', updateBadgePositions); $(window).on('resize', updateBadgePositions); } });