ỦY BAN NHÂN DÂN TỈNH BẮC KẠN -------
CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM Độc lập - Tự do - Hạnh phúc ---------------
Số: 506/KH-UBND
Bắc Kạn, ngày 28 tháng 7 năm 2023
KẾ HOẠCH
TRIỂN KHAI CHƯƠNG TRÌNH HỖ TRỢ PHỔ CẬP ĐIỆN THOẠI THÔNG MINH CHO NGƯỜI DÂN TRƯỞNG THÀNH TẠI 08 XÃ/PHƯỜNG THỰC HIỆN THÍ ĐIỂM CHUYỂN ĐỔI SỐ NĂM 2023
I. CĂN CỨ XÂY DỰNG KẾ HOẠCH
Nghị định số 07/2021/NĐ-CP ngày 27/01/2021 của Chính phủ quy định chuẩn nghèo đa chiều gia đoạn 2021 - 2025;
Quyết định số 861/QĐ-TTg ngày 04/6/2021 của Thủ tướng Chính phủ phê duyệt danh sách các xã khu vực III, khu vực II, khu vực I thuộc vùng đồng bào dân tộc thiểu số và miền núi giai đoạn 2021 - 2025;
Quyết định số 2269/QĐ-TTg ngày 31/12/2021 của Thủ tướng Chính phủ phê duyệt Chương trình cung cấp dịch vụ viễn thông công ích đến năm 2025;
Thông tư số 14/2022/TT-BTTTT ngày 28/10/2022 của Bộ trưởng Bộ Thông tin và Truyền thông quy định danh mục, chất lượng dịch vụ viễn thông công ích và hướng dẫn thực hiện Chương trình cung cấp dịch vụ viễn thông công ích đến năm 2025;
Quyết định số 1506/QĐ-BTTTT ngày 12/8/2022 của Bộ trưởng Bộ Thông tin và Truyền thông phân bổ máy tính bảng thuộc Chương trình cung cấp dịch vụ viễn thông công ích đến năm 2025 cho các tỉnh, thành phố trực thuộc Trung ương;
Thông báo số 1085-TB/TU ngày 29/6/2023 của Ban Thường vụ Tỉnh ủy về nội dung Hội nghị Ban Thường vụ Tỉnh ủy lần thứ 56 (khóa XII), nhiệm kỳ 2020 - 2025;
Kế hoạch số 369/KH-UBND ngày 14/6/2023 của UBND tỉnh Bắc Kạn về thí điểm triển khai thực hiện chuyển đổi số tại 08 xã/phường/thị trấn trên địa bàn tỉnh Bắc Kạn năm 2023.
II. MỤC ĐÍCH, YÊU CẦU
1. Giúp người dân trưởng thành nói chung và các hộ gia đình nói riêng đang sinh sống tại 8 xã/phường thực hiện thí điểm chuyển đổi số có cơ hội tìm hiểu, tiếp cận với các ứng dụng về thông tin và khoa học công nghệ, các dịch vụ công trực tuyến, qua đó góp phần nâng cao trình độ hiểu biết, kịp thời cập nhật các thông tin tuyên truyền, thực hiện tốt các chủ trương, đường lối của Đảng, chính sách, pháp luật của Nhà nước; nâng cao tỷ lệ sử dụng dịch vụ công trực tuyến, thanh toán không dùng tiền mặt, định danh điện tử… từng bước hình thành “xã hội số”, “công dân số”; nâng cao tỷ lệ dân số trưởng thành có điện thoại thông minh và tỷ lệ hộ gia đình có người có điện thoại thông minh trên địa bàn tỉnh, từ đó thực hiện thành công Chương trình chuyển đổi số quốc gia, Đề án phát triển ứng dụng dữ liệu về dân cư, định danh và xác thực điện tử phục vụ chuyển đổi số quốc gia (Đề án 06) tại địa phương.
2. Phấn đấu 100% người dân trưởng thành3. Điện thoại được hỗ trợ đảm bảo đúng đối tượng, không trùng lặp, không để xảy ra tình trạng tiêu cực, lãng phí trong quá trình thực hiện; cài đặt đầy đủ các ứng dụng, đáp ứng tra cứu thông tin, liên lạc nhanh chóng và trực quan; sử dụng làm phương tiện thanh toán trực tuyến tiện lợi, làm phương tiện học tập và làm việc từ xa hiệu quả...
III. NỘI DUNG
1. Phạm vi thực hiện
Tại 08 đơn vị cấp xã được UBND các huyện, thành phố lựa chọn là đơn vị triển khai thí điểm chuyển đổi số (phường Sông Cầu, thành phố Bắc Kạn; xã Quang Thuận, huyện Bạch Thông; xã Thượng Giáo, huyện Ba Bể; xã Nghĩa Tá, huyện Chợ Đồn; xã Như Cố, huyện Chợ Mới; xã Đức Vân, huyện Ngân Sơn; xã Côn Minh, huyện Na Rì; xã Giáo Hiệu, huyện Pác Nặm).
2. Đối tượng hỗ trợ
Người dân trưởng thành sinh sống tại 8 xã/phường thí điểm chuyển đổi số.
3. Hình thức hỗ trợ
- Hỗ trợ nguyên chiếc điện thoại thông minh từ nguồn tiếp nhận được đối với người dân trưởng thành thuộc hộ nghèo, hộ cận nghèo chưa có điện thoại thông minh theo thứ tự ưu tiên như sau:
Người dân trưởng thành thuộc hộ nghèo, hộ cận nghèo đồng thời là gia đình chính sách người có công với cách mạng.
Người dân trưởng thành thuộc hộ nghèo, hộ cận nghèo đồng thời gia đình chính sách xã hội.
Người dân trưởng thành thuộc hộ nghèo khác
Người dân trưởng thành thuộc hộ cận nghèo khác.
- Hỗ trợ một phần kinh phí từ các nguồn kinh phí huy động được đối với người dân trưởng thành chưa có điện thoại thông minh thuộc các đối tượng theo thứ tự ưu tiên như sau:
Người dân trưởng thành thuộc hộ nghèo chưa có điện thoại thông minh.
Người dân trưởng thành thuộc hộ nghèo có thành viên khác của gia đình đó đã được hỗ trợ nguyên chiếc điện thoại thông minh.
Người dân trưởng thành thuộc hộ cận nghèo chưa có điện thoại thông minh.
Người dân trưởng thành thuộc hộ cận nghèo có thành viên khác của gia đình đó đã được hỗ trợ nguyên chiếc điện thoại thông minh.
- Hỗ trợ của doanh nghiệp, cửa hàng bán điện thoại thông minh (tặng máy điện thoại, giảm giá thành điện thoại, bán điện thoại trả góp hoặc các hình thức hỗ trợ khác): Các đối tượng được hỗ trợ do đơn vị kinh doanh xác định (tỉnh khuyến khích ưu tiên hỗ trợ người dân thuộc hộ nghèo, hộ cận nghèo).
- Hỗ trợ trực tiếp từ các cơ quan, đơn vị, tổ chức, doanh nghiệp, cá nhân: Các đối tượng được hỗ trợ do đơn vị, cá nhân xác định (tỉnh khuyến khích ưu tiên hỗ trợ người dân thuộc hộ nghèo, hộ cận nghèo).
4. Phương thức tiếp nhận hỗ trợ
Có thể lựa chọn một trong các hình thức sau:
- Tại cấp tỉnh: Sở Thông tin và Truyền thông làm đầu mối tiếp nhận hỗ trợ thông qua hình thức hỗ trợ bằng hiện vật điện thoại hoặc bằng tiền mặt từ các cơ quan, đơn vị, tổ chức, doanh nghiệp, cá nhân trong và ngoài tỉnh có nhu cầu hỗ trợ Chương trình; xây dựng phương án phân bổ nguồn hỗ trợ cho các huyện/thành phố, xã/phường thí điểm chuyển đổi số.
- Tại cấp huyện, cấp xã: UBND các huyện/thành phố, UBND các xã/phường thí điểm chuyển đổi số làm đầu mối tiếp nhận hỗ trợ thông qua hình thức hỗ trợ bằng hiện vật điện thoại hoặc bằng tiền mặt từ các đơn vị, tổ chức, doanh nghiệp, cá nhân trong và ngoài tỉnh có nhu cầu hỗ trợ Chương trình. Trên cơ sở nguồn hỗ trợ tiếp nhận hoặc được phân bổ, UBND xã/phường lựa chọn, lập danh sách người dân được hỗ trợ theo thứ tự ưu tiên tại tiểu mục 3, mục III của Kế hoạch này.
- Các đối tượng được hỗ trợ có thể tiếp nhận trực tiếp từ các các đơn vị, tổ chức, doanh nghiệp, cá nhân trong và ngoài tỉnh.
5. Tính năng của điện thoại thông minh
Điện thoại thông minh được hỗ trợ phải được cài đặt, cập nhật đầy đủ các tính năng, ứng dụng cơ bản, đáp ứng tra cứu thông tin liên lạc nhanh chóng và trực quan; cập nhật thông tin nhanh chóng, sử dụng làm phương tiện thanh toán trực tuyến tiện lợi, làm phương tiện học tập và làm việc từ xa hiệu quả và sử dụng được dịch vụ 3G/4G…
IV. KINH PHÍ THỰC HIỆN
Kinh phí triển khai Chương trình hỗ trợ phổ cập điện thoại thông minh cho các hộ nghèo, hộ cận nghèo tại 08 xã/phường thực hiện thí điểm chuyển đổi số năm 2023 chủ yếu từ nguồn huy động xã hội hóa, hỗ trợ của các cơ quan, đơn vị, tổ chức, doanh nghiệp, cá nhân và nguồn ngân sách Trung ương, địa phương (nếu có).
V. TIẾN ĐỘ THỰC HIỆN
- Triển khai công tác tuyên truyền: Ngay khi Kế hoạch được ban hành.
- Tổ chức đợt cao điểm quyên góp, ủng hộ cho Chương trình: Bắt đầu từ tháng 8/2023 đến hết năm 2023.
VI. TỔ CHỨC THỰC HIỆN
1. Sở Thông tin và Truyền thông
- Chủ trì, phối hợp với Ủy ban Mặt trận Tổ quốc Việt Nam tỉnh, các tổ chức đoàn thể, chính trị - xã hội và các đơn vị liên quan tham mưu cho UBND tỉnh tổ chức đợt cao điểm quyên góp, ủng hộ cho Chương trình hỗ trợ phổ cập điện thoại thông minh cho người dân tại 08 xã/phường thực hiện thí điểm chuyển đổi số năm 2023; văn bản trình UBND tỉnh ban hành trước ngày 31/7/2023.
- Tham mưu cho UBND tỉnh mời các địa phương, cơ quan, tổ chức, đơn vị liên quan, doanh nghiệp, cửa hàng kinh doanh điện thoại thông minh trên địa bàn tỉnh tham dự Hội nghị tuyên truyền, phổ biến, quán triệt, trao đổi, thống nhất phương thức tổ chức thực hiện Chương trình.
- Làm đầu mối tiếp nhận hỗ trợ thông qua hình thức hỗ trợ bằng hiện vật điện thoại hoặc bằng tiền mặt từ các đơn vị, tổ chức, doanh nghiệp, cá nhân trong và ngoài tỉnh ủng hộ Chương trình; xây dựng phương án phân bổ nguồn hỗ trợ cho các huyện/thành phố, xã/phường thí điểm chuyển đổi số đảm bảo đúng đối tượng, đúng mục đích, công khai, minh bạch.
- Có trách nhiệm hướng dẫn, hỗ trợ các huyện/thành phố, xã/phường về cách thức tiếp nhận, phân bổ và triển khai; tổng hợp báo cáo tình hình tiếp nhận và phân bổ theo tháng (trước 20 hàng tháng) và tham mưu tổng kết việc thực hiện Chương trình, đánh giá, rút kinh nghiệm để nhân rộng việc phổ cập điện thoại thông minh trên địa bàn tỉnh.
- Chỉ đạo các cơ quan báo chí của tỉnh tăng cường công tác tuyên truyền về mục đích, ý nghĩa của Chương trình đến các tổ chức, doanh nghiệp và Nhân dân được biết, tích cực tham gia ủng hộ.
2. UBND các huyện, thành phố; UBND các xã, phường thí điểm
- Lập và duyệt danh sách người dân thuộc đối tượng hỗ trợ; làm đầu mối tiếp nhận tại cấp huyện, cấp xã và thực hiện việc phân bổ, bàn giao cho các đối tượng được hưởng hỗ trợ đảm bảo đúng đối tượng, đúng mục đích, công khai, minh bạch. Đồng thời tổng hợp số liệu trao tặng, phân bổ, bàn giao gửi Sở Thông tin và Truyền thông tổng hợp báo cáo UBND tỉnh theo quy định.
- UBND các huyện, thành phố chủ động cân đối, bố trí kinh phí hỗ trợ ban đầu cho Chương trình; chỉ đạo UBND tại 08 xã/phường thực hiện thí điểm chuyển đổi số năm 2023 khuyến khích người dân chủ động mua và sử dụng điện thoại thông minh; tổ chức tuyên truyền, vận động người dân/người thân của các hộ dân sinh sống tại địa bàn và các nhà hảo tâm tham gia ủng hộ Chương trình, tặng điện thoại thông minh hoặc hỗ trợ mua điện thoại thông minh cho người dân sống trên địa bàn.
- Tổ chức tuyên truyền hướng dẫn người dân quản lý và sử dụng thiết bị điện thoại thông minh đảm bảo hiệu quả.
3. Các sở, ban, ngành tỉnh
Theo chức năng, nhiệm vụ, triển khai, phối hợp thực hiện Chương trình đảm bảo phù hợp, hiệu quả; vận động, kêu gọi trong toàn ngành ủng hộ, hỗ trợ để thực hiện Chương trình, góp phần hướng tới mục tiêu người dân sinh sống tại địa bàn 8 xã/phường triển khai thí điểm chuyển đổi số có điện thoại thông minh để sử dụng.
4. Đề nghị Ủy ban Mặt trận Tổ quốc Việt Nam tỉnh và các đoàn thể tỉnh
Phối hợp với Sở Thông tin và Truyền thông phát động, ủng hộ Chương trình đến Ủy ban Mặt trận Tổ quốc các cấp và các tổ chức thành viên; phối hợp với các cơ quan, đơn vị liên quan tổ chức quyên góp, vận động, ủng hộ Chương trình.
5. Đề nghị Hiệp hội Doanh nghiệp tỉnh, Hội Doanh nhân trẻ tỉnh
Tổ chức tuyên truyền, vận động các doanh nghiệp trên địa bàn tỉnh hưởng ứng tham gia ủng hộ Chương trình (bằng kinh phí hoặc tặng máy điện thoại thông minh) để giúp người dân sinh sống tại địa bàn 8 xã/phường triển khai thí điểm chuyển đổi số có điện thoại thông minh để sử dụng.
6. Đề nghị các doanh nghiệp viễn thông - CNTT, cửa hàng bán điện thoại thông minh trên địa bàn tỉnh
- Tiếp tục phủ sóng di động băng rộng tại các thôn, bản vùng “lõm” sóng; triển khai hạ tầng băng rộng cố định (cáp quang) để phổ cập mạng băng rộng cáp quang đến 100% các thôn trên địa bàn tỉnh; phối hợp cùng với tỉnh nâng cao tỷ lệ hộ gia đình có kết nối internet.
- Hỗ trợ các gói cước Internet cho đối tượng được hỗ trợ thuộc Chương trình.
- Tham gia ủng hộ nguồn lực (máy điện thoại thông minh, kinh phí...) cho
Chương trình; triển khai các chính sách hỗ trợ giảm giá thành điện thoại, hỗ trợ mua điện thoại trả góp với lãi suất thấp hoặc các hình thức hỗ trợ khác cho các đối tượng được hưởng hỗ trợ tại Kế hoạch này.
- Hỗ trợ cài đặt các ứng dụng trên điện thoại thông minh.
7. Đề nghị các đơn vị, tổ chức, doanh nghiệp, cá nhân, nhà hảo tâm, nhà tài trợ: Quan tâm, tích cực tham gia ủng hộ Chương trình, đồng hành cùng với tỉnh Bắc Kạn đẩy nhanh quá trình chuyển đổi số cho người dân trên địa bàn tỉnh.
Trên đây là Kế hoạch triển khai Chương trình hỗ trợ phổ cập điện thoại thông minh cho người dân tại 08 xã/phường thực hiện thí điểm chuyển đổi số năm 2023. Trong quá trình thực hiện, nếu có khó khăn, vướng mắc, các cơ quan, đơn vị kịp thời báo cáo Ủy ban nhân dân tỉnh (qua Sở Thông tin và Truyền thông) để giải quyết./.
Nơi nhận: - Bộ TT&TT (b/c); - TT Tỉnh ủy (b/c); - CT, các PCT UBND tỉnh; - Ủy ban MTTQ Việt Nam tỉnh; - Các cơ quan tham mưu, giúp việc TU; - Các sở, ban, ngành, đoàn thể tỉnh; - Cơ quan TƯ trên địa bàn tỉnh; - Hiệp hội DN tỉnh; Hội Doanh nhân trẻ; - Các doanh nghiệp viễn thông CNTT trên địa bàn tỉnh; - Cấp uỷ, UBND huyện, thành phố; - Cấp uỷ, UBND 8 xã/phường thuộc Chương trình; - LĐVP; - Phòng HCTC-QTTV; - Lưu: VT, NCTH, Nhung VX
TM. ỦY BAN NHÂN DÂN CHỦ TỊCH Nguyễn Đăng Bình
lồng nhau (bên trong) hay không
const memberID = 0;
const vbID = '0de40be3e37b16357cb388abcd1516d2';
// 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, '');
// 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 = `
Đ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(`
Lỗi! Không thể xóa cache. Vui lòng thử lại.
`);
$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(`
Lỗi! ${escapeHtml(response.error || 'Không thể phân tích điều luật.')}
Vui lòng thử lại sau.
`);
}
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(`
Lỗi! Không thể kết nối đến server phân tích.
Chi tiết: ${escapeHtml(errorMsg)}
`);
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 = `
Đ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 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);
}
});
Tra cứu thuật ngữ với từ hoặc cụm từ đã chọn?
×
Kế hoạch 506/KH-UBND triển khai Chương trình hỗ trợ phổ cập điện thoại thông minh cho người dân trưởng thành tại 08 xã/phường thực hiện thí điểm chuyển đổi số năm 2023 do tỉnh Bắc Kạn ban hành