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ố: 475/TB-VPCP

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

 

THÔNG BÁO

KẾT LUẬN CỦA THỦ TƯỚNG CHÍNH PHỦ PHẠM MINH CHÍNH TẠI HỘI NGHỊ TRỰC TUYẾN TOÀN QUỐC ĐÁNH GIÁ KẾT QUẢ 10 THÁNG THỰC HIỆN CHỈ THỊ SỐ 01/CT-TTG NGÀY 03 THÁNG 01 NĂM 2023 VỀ TĂNG CƯỜNG CÔNG TÁC PHÒNG CHÁY, CHỮA CHÁY TRONG TÌNH HÌNH MỚI

Sáng ngày 05 tháng 11 năm 2023, tại trụ sở Chính phủ, Thủ tướng Chính phủ Phạm Minh Chính đã chủ trì Hội nghị trực tuyến toàn quốc đánh giá kết quả 10 tháng thực hiện Chỉ thị số 01/CT-TTg ngày 03 tháng 01 năm 2023 về tăng cường công tác phòng cháy, chữa cháy trong tình hình mới (Chỉ thị số 01/CT-TTg). Tham dự Hội nghị có Phó Thủ tướng Chính phủ Trần Lưu Quang, Bộ trưởng, Chủ nhiệm Văn phòng Chính phủ, đại diện lãnh đạo các Bộ, ngành, cơ quan Trung ương và Lãnh đạo Ủy ban nhân dân cấp tỉnh, cấp huyện, cấp xãI. Tình hình thực hiện nhiệm vụ

1. Đánh giá cao Bộ Công an và các cơ quan liên quan đã chủ động đề xuất tổ chức, chuẩn bị tốt nội dung, chương trình Hội nghị; báo cáo của Bộ Công an đã thẳng thắn đánh giá toàn diện về tình hình, kết quả, hạn chế, tồn tại, khó khăn, chỉ ra nguyên nhân, trên cơ sở đó đề ra nhiệm vụ, giải pháp nâng cao hiệu lực, hiệu quả công tác phòng cháy, chữa cháy và cứu nạn, cứu hộ (PCCC và CNCH).

2. Công tác PCCC và CNCH đặt dưới sự lãnh đạo, chỉ đạo thường xuyên, trực tiếp của cấp ủy Đảng, sự quản lý chặt chẽ của chính quyền các cấp, sự tham gia tích cực của người dân, doanh nghiệp. Xác định công tác PCCC và CNCH có vị trí, vai trò và là nhiệm vụ quan trọng trong quá trình phát triển kinh tế, xã hội của đất nước; phải huy động sức mạnh, nguồn lực của cả hệ thống chính trị và toàn dân, bảo đảm an toàn cho người dân và toàn xã hội ở mức cao nhất, hạn chế tối đa hậu quả, thiệt hại do cháy, nổ gây ra.

3. Thời gian qua, các cấp, các ngành, các địa phương, nòng cốt là lực lượng Công an đã nghiêm túc quán triệt, quyết liệt tổ chức triển khai chỉ đạo của Đảng, Quốc hội, Chính phủ, Thủ tướng Chính phủ, nhất là chỉ đạo của đồng chí Tổng Bí thư Nguyễn Phú Trọng về tăng cường công tác PCCC và CNCH, qua đó đã đạt được một số kết quả nổi bật như: Tham mưu, ban hành hệ thống văn bản quy phạm pháp luật, văn bản chỉ đạo; chủ động nghiên cứu, phân tích, dự báo tình hình xác định đối tượng có nguy cơ cao để tập trung quản lý, kiểm tra, xử lý vi phạm; đổi mới, tăng cường tuyên truyền, tập huấn, hướng dẫn về PCCC; nỗ lực triển khai có hiệu quả công tác CNCH.

Thủ tướng Chính phủ đánh giá cao sự nỗ lực, kết quả mà các Bộ, ngành, địa phương đã đạt được trong công tác PCCC và CNCH thời gian qua, góp phần bảo vệ tính mạng, sức khỏe, tài sản của người dân và doanh nghiệp, tạo môi trường an ninh, an toàn, sự bình yên cho cuộc sống.

4. Tuy nhiên, bên cạnh những kết quả đã đạt được, công tác PCCC và CNCH còn tồn tại, hạn chế, yếu kém cần khẩn trương, quyết liệt lãnh đạo, chỉ đạo, huy động các nguồn lực để tập trung khắc phục, cụ thể là:

a) Việc lãnh đạo, chỉ đạo, thực hiện công tác PCCC và CNCH có lúc, có nơi chưa hiệu quả, công tác thanh tra, kiểm tra, xử lý vi phạm PCCC, trật tự xây dựng ở nhiều địa phương chưa nghiêm để xảy ra xây dựng các công trình không tuân thủ quy định pháp luật về PCCC, chây ỳ, không kịp thời khắc phục vi phạm.

b) Công tác tuyên truyền, phổ biến pháp luật, nâng cao ý thức, kiến thức, kỹ năng của người dân trong PCCC và CNCH nhìn chung chưa được coi trọng. Việc thực tập, diễn tập PCCC và CNCH tại một số địa phương còn hạn chế, nặng về hình thức, chưa sát thực tế.

c) Một bộ phận người đứng đầu cơ sở, chủ hộ gia đình, người dân còn chủ quan, lơ là chưa nhận thức đầy đủ tầm quan trọng của công tác PCCC và CNCH và nguy cơ xảy ra cháy, nổ để chủ động bổ sung các giải pháp bảo đảm an toàn cần thiết; thiếu kỹ năng thoát nạn, thoát hiểm khi xảy ra cháy, nổ.

d) Một số Bộ, ngành thực hiện các nhiệm vụ được giao còn chậm, chưa bảo đảm tiến độ; việc ban hành tiêu chuẩn, quy chuẩn về PCCC còn chậm, chưa dự báo hết được tình hình, một số quy định còn chưa phù hợp với thực tiễn của Việt Nam.

Nguyên nhân của tồn tại, hạn chế: Cấp ủy các cấp ở nhiều địa phương chưa thật sự coi trọng công tác lãnh đạo, chỉ đạo, việc tổ chức thực hiện chưa nghiêm, chưa kịp thời cụ thể hóa các chỉ đạo của Trung ương, Chính phủ, Thủ tướng Chính phủ trong công tác PCCC và CNCH; sự phối hợp giữa các cơ quan chức năng chưa chặt chẽ, hệ thống văn bản quy pháp pháp luật lĩnh vực này thiếu đồng bộ; chưa huy động, tận dụng tối đa các nguồn lực xã hội cho công tác PCCC và CNCH.

Các đồng chí Bộ trưởng, Thủ trưởng cơ quan ngang Bộ, Chủ tịch Ủy ban nhân dân các tỉnh, thành phố trực thuộc trung ương cần nghiêm túc rút kinh nghiệm về những tồn tại, hạn chế, yếu kém nêu trên, từ đó chấn chỉnh trong lãnh đạo, chỉ đạo công tác PCCC và CNCH.

II. Các nhiệm vụ và giải pháp chủ yếu thời gian tới

Để kịp thời khắc phục những tồn tại, hạn chế nêu trên, trong thời gian tới, người đứng đầu các Bộ, ngành, địa phương phải thực sự trăn trở, trách nhiệm, tập trung thực hiện quyết liệt, hiệu quả các giải pháp, nhiệm vụ để nâng cao chất lượng công tác PCCC và CNCH, trong đó cần tập trung vào một số nhiệm vụ và giải pháp chủ yếu sau:

1. Tiếp tục quán triệt và triển khai thực hiện hiệu quả, thực chất các văn bản chỉ đạo của Đảng, Quốc hội, Chính phủ, Thủ tướng Chính phủ, đặc biệt là Chỉ thị số 47-CT/TW, Kết luận số 02-KL/TW của Ban Bí thư; Nghị quyết số 99/2019/QH14 của Quốc hội, Chỉ thị số 01/CT-TTg, Công điện số 825/CĐ-TTg của Thủ tướng Chính phủ và chỉ đạo của đồng chí Tổng Bí thư Nguyễn Phú Trọng về tăng cường công tác PCCC.

2. Tăng cường sự lãnh đạo, chỉ đạo của cấp ủy Đảng, siết chặt kỷ luật, kỷ cương, nâng cao hiệu lực, hiệu quả quản lý nhà nước của chính quyền các cấp về PCCC, xây dựng, điện lực, kịp thời khắc phục ngay những sơ hở, thiếu sót, nhất là ở cơ sở. Tiếp tục tổng rà soát, kiểm tra về công tác PCCC, nhất là đối với chung cư, nhà ở riêng lẻ có nhiều tầng, nhiều căn hộ, cơ sở cho thuê trọ có mật độ người ở cao, nhà ở kết hợp sản xuất, kinh doanh có nguy cơ cháy, nổ cao. Xác định rõ trách nhiệm của các tổ chức, cá nhân, xử lý nghiêm các hành vi vi phạm (nếu có) theo đúng quy định pháp luật, không có vùng cấm, không có ngoại lệ.

3. Huy động sức mạnh tổng hợp của cả hệ thống chính trị, nguồn lực xã hội cho việc phát triển cơ sở vật chất, hạ tầng, hậu cần đáp ứng yêu cầu, nhiệm vụ công tác PCCC và CNCH trong tình hình mới, trong đó tập trung nâng cao năng lực của lực lượng PCCC; củng cố các lực lượng tại khu dân cư, cơ sở; làm tốt công tác quy hoạch, nhất là quy hoạch hạ tầng (giao thông, nguồn nước...); xây dựng cơ chế phối hợp chặt chẽ, hiệu quả giữa các lực lượng làm nhiệm vụ chữa cháy và CNCH…

4. Đẩy mạnh hơn nữa công tác tuyên truyền, giáo dục kiến thức pháp luật, nâng cao nhận thức, ý thức, trách nhiệm, kiến thức, kỹ năng của người dân về PCCC và CNCH, nhân rộng các mô hình, cách làm hay, điển hình về PCCC. Các phương tiện thông tin đại chúng ở trung ương và địa phương dành thời lượng phù hợp, ưu tiên khung giờ nhiều người theo dõi để tuyên truyền về công tác này.

5. Coi trọng và tập trung thực hiện tốt công tác phòng ngừa từ sớm, từ xa, ngay từ cơ sở, xác định đây là nhiệm vụ chính, phải thực hiện thường xuyên, liên tục, bài bản; hoạt động chữa cháy, CNCH phải chuyên nghiệp, hiện đại.

6. Phối hợp chặt chẽ giữa các cơ quan, lực lượng đẩy mạnh việc xây dựng chính sách, pháp luật, hoàn thiện thể chế, hệ thống các tiêu chuẩn, quy chuẩn về PCCC phù hợp với điều kiện kinh tế, xã hội của Việt Nam; nghiêm cấm “cài cắm” lợi ích cá nhân, lợi ích nhóm trong xây dựng chính sách, pháp luật. Việc tổ chức thực hiện các quy định pháp luật về PCCC không được gây phiền hà, khó khăn, không hợp pháp hóa sai phạm nhưng phải có giải pháp tháo gỡ để bảo đảm quyền lợi của người dân và doanh nghiệp, nhất là khi “chuyển đổi trạng thái” phải có sự chuyển tiếp để người dân, doanh nghiệp có thời gian chuẩn bị, khắc phục. Tiếp tục hướng dẫn, tháo gỡ khó khăn, vướng mắc cho người dân và doanh nghiệp về PCCC theo chỉ đạo của Thủ tướng Chính phủ tại Công điện số 220/CĐ-TTg ngày 05 tháng 4 năm 2023.

III. Về các nhiệm vụ cụ thể

1. Bộ Công an:

a) Khẩn trương hoàn thiện hồ sơ đề nghị xây dựng Luật PCCC và CNCH; phối hợp chặt chẽ với các Bộ, ngành, nhất là Bộ Xây dựng rà soát, sửa đổi quy định về PCCC, tiêu chuẩn, quy chuẩn kỹ thuật để bảo đảm thống nhất, giảm tối đa chi phí không cần thiết cho người dân và doanh nghiệp.

b) Chỉ đạo thực hiện nghiêm quy trình, quy chế thẩm duyệt thiết kế, nghiệm thu về PCCC, kiểm tra an toàn về PCCC và CNCH trên tinh thần công khai, minh bạch, không gây phiền hà cho người dân và doanh nghiệp; nghiêm cấm các hành vi tiêu cực trong công tác này.

2. Bộ Xây dựng:

a) Khẩn trương hoàn thành tiêu chuẩn Nhà ở riêng lẻ - Yêu cầu chung về thiết kế (trước ngày 31 tháng 12 năm 2023).

b) Nghiên cứu, ban hành hoặc đề xuất cấp có thẩm quyền ban hành quy định cụ thể về cấp nước PCCC khi lập quy hoạch, dự án xây dựng mới hoặc cải tạo đô thị, khu dân cư, đặc khu kinh tế, khu công nghiệp, khu chế xuất, khu công nghệ cao; ưu tiên mọi nguồn nước sử dụng cho PCCC.

c) Nghiên cứu các quy định về nguồn nước phục vụ PCCC (tuân thủ pháp luật về PCCC) trong Dự thảo Luật Cấp, thoát nước và Nghị định hướng dẫn Luật Cấp, thoát nước thay thế Nghị định số 117/2007/NĐ-CP ngày 11 tháng 7 năm 2007 (theo tiến độ ban hành văn bản quy phạm pháp luật của Quốc hội).

d) Chỉ đạo các địa phương tăng cường quản lý quy hoạch xây dựng, quy hoạch đô thị, trật tự xây dựng; phối hợp với Ủy ban nhân dân cấp tỉnh tổ chức thanh tra toàn diện hoạt động quản lý xây dựng nhà ở riêng lẻ có nhiều tầng, nhiều căn hộ, kịp thời phát hiện, xử lý nghiêm vi phạm theo quy định của pháp luật (báo cáo Thủ tướng Chính phủ kết quả thực hiện trong tháng 12 năm 2023).

đ) Ban hành tài liệu hướng dẫn giải pháp kỹ thuật tháo gỡ khó khăn, vướng mắc đối với các công trình hiện hữu theo chỉ đạo của Thủ tướng Chính phủ tại Công điện số 825/CĐ-TTg ngày 15 tháng 9 năm 2023 (hoàn thành trước ngày 31 tháng 12 năm 2023).

3. Bộ Công Thương:

a) Khẩn trương hoàn thiện dự án Luật sửa đổi, bổ sung Luật Điện lực, trong đó nghiên cứu bổ sung quy định về sử dụng điện an toàn sau công tơ để làm rõ trách nhiệm của các cơ quan quản lý, tổ chức, cá nhân. Trong thời gian chưa ban hành Luật này, cần có giải pháp trước mắt để giảm thiểu nguy cơ cháy, nổ do hệ thống, thiết bị điện.

b) Tăng cường quản lý rủi ro, phối hợp rà soát các cơ sở kinh doanh, bảo quản hóa chất có nguy cơ cháy, nổ cao ở khu dân cư, nơi tập trung đông người và di dời, bảo đảm các điều kiện an toàn về PCCC và CNCH.

c) Chỉ đạo ngành điện tăng cường tuyên truyền, hướng dẫn về an toàn PCCC trong sử dụng điện; thực hiện tổng rà soát, kiểm tra, an toàn trong sử dụng điện đối với các công trình, cơ sở, hộ gia đình, xử lý nghiêm các trường hợp vi phạm theo quy định.

4. Bộ Giáo dục và Đào tạo:

a) Khẩn trương thực hiện việc lồng ghép kiến thức, kỹ năng về PCCC và CNCH vào chương trình giảng dạy, hoạt động ngoại khóa, trải nghiệm trong cơ sở giáo dục và đẩy mạnh tuyên truyền, tập huấn kiến thức, kỹ năng về PCCC và CNCH cho học sinh, sinh viên phù hợp với lứa tuổi.

b) Nghiên cứu, bổ sung kiến thức chuyên môn về PCCC và CNCH vào chương trình đào tạo của các trường kỹ thuật có chuyên ngành đào tạo công trình.

5. Bộ Nông nghiệp và Phát triển nông thôn: Xây dựng bổ sung quy chuẩn, tiêu chuẩn PCCC rừng; phối hợp với các Bộ, ngành, địa phương tăng cường công tác PCCC rừng; ứng dụng công nghệ trong cảnh báo, phát hiện sớm nguy cơ cháy rừng (hoàn thành trong tháng 12 năm 2023).

6. Bộ Thông tin và Truyền thông: Tiếp tục chỉ đạo các cơ quan thông tấn, báo chí tăng cường tuyên truyền rộng rãi trên các phương tiện thông tin đại chúng để người dân nâng cao cảnh giác, ứng phó kịp thời với các sự cố cháy, nổ.

7. Đài Truyền hình Việt Nam, Đài Tiếng nói Việt Nam, Thông tấn xã Việt Nam và các cơ quan báo chí ở trung ương, địa phương: Tăng thời lượng tuyên truyền, khuyến cáo cho người dân về kiến thức, kỹ năng phòng ngừa cháy, nổ, thoát nạn.

8. Bộ Kế hoạch và Đầu tư, Bộ Tài chính: Nghiên cứu, tổng hợp báo cáo cấp có thẩm quyền xem xét, bố trí nguồn vốn đầu tư công đảm bảo cho công tác PCCC và CNCH theo quy định của pháp luật; quan tâm cân đối để thực hiện Quy hoạch hạ tầng PCCC thời kỳ 2021 - 2030, tầm nhìn đến năm 2050.

9. Bộ Văn hóa, Thể thao và Du lịch: Khẩn trương hoàn thành việc rà soát, đánh giá để đề xuất sửa đổi, bổ sung theo trình tự, thủ tục rút gọn Nghị định số 54/2019/NĐ-CP ngày 19 tháng 6 năm 2019 về kinh doanh dịch vụ karaoke, dịch vụ vũ trường cho phù hợp, trong đó nghiên cứu sửa đổi quy định về cấp giấy phép kinh doanh dịch vụ karaoke, vũ trường (hoàn thành trong tháng 12 năm 2023).

10. Bộ Giao thông vận tải: Ban hành Thông tư sửa đổi, bổ sung liên quan lĩnh vực vận tải đường bộ, trong đó nghiên cứu lồng ghép nội dung hướng dẫn kỹ năng phòng, chống cháy, nổ, xử lý, ứng phó với các sự cố, tai nạn vào nội dung đào tạo lái xe (hoàn thành trong tháng 12 năm 2023).

11. Bộ Lao động - Thương binh và Xã hội: Nghiên cứu, ban hành Thông tư bổ sung danh mục ngành nghề, công việc nặng nhọc, độc hại, nguy hiểm và đặc biệt nặng nhọc, độc hại, nguy hiểm trong lực lượng Công an nhân dân, trong đó xem xét bổ sung công tác CNCH vào danh mục ngành nghề, công việc đặc biệt nặng nhọc, độc hại, nguy hiểm.

12. Ủy ban nhân dân các tỉnh, thành phố trực thuộc trung ương:

a) Coi trọng công tác PCCC và CNCH, xác định đây là nhiệm vụ thường xuyên, liên tục, phải quan tâm lãnh đạo, chỉ đạo tổ chức thực hiện nghiêm túc, có hiệu quả, thực chất các văn bản chỉ đạo của Đảng, Quốc hội, Chính phủ, Thủ tướng Chính phủ phù hợp với thực tiễn địa phương; tăng cường kiểm tra, đánh giá tình hình, kết quả triển khai thực hiện, nhất là ở cơ sở, không để tình trạng xảy ra vụ việc cháy, nổ mới quan tâm đến công tác này. Tổ chức quán triệt và thực hiện nghiêm túc Chỉ thị số 47-CT/TW, Kết luận số 02-KL/TW của Ban Bí thư. Các địa phương phải chỉ đạo triển khai và hoàn thành đầy đủ các nhiệm vụ về PCCC được giao trong Chỉ thị số 01/CT-TTg.

b) Đối với các cơ sở đã rà soát theo Công điện 825/CĐ-TTg ngày 15 tháng 9 năm 2023 của Thủ tướng Chính phủ, phải làm rõ sai phạm để xử lý kiên quyết, dứt điểm; trường hợp có dấu hiệu tội phạm phải chuyển cơ quan điều tra xử lý theo quy định; đồng chí Chủ tịch Ủy ban nhân dân tỉnh, thành phố trực thuộc trung ương chịu trách nhiệm trước Thủ tướng Chính phủ về việc xử lý này.

c) Chỉ đạo hoàn thành tổng rà soát, kiểm tra an toàn PCCC, đưa ra giải pháp trước mắt và lâu dài bảo đảm hạn chế cháy, nổ và giảm thiểu tối đa thiệt hại, hậu quả do cháy, nổ gây ra (hoàn thành trước ngày 31 tháng 12 năm 2023).

d) Tăng cường quản lý quy hoạch xây dựng, quy hoạch đô thị, trật tự xây dựng; phối hợp với Bộ Xây dựng tổ chức thanh tra toàn diện hoạt động quản lý xây dựng nhà ở riêng lẻ nhiều căn hộ có nhiều tầng, kịp thời phát hiện, xử lý nghiêm vi phạm theo quy định của pháp luật (báo cáo Thủ tướng Chính phủ kết quả thực hiện trong tháng 12 năm 2023).

đ) Tiếp tục triển khai quyết liệt công tác quản lý nhà nước về PCCC và CNCH nhằm ngăn chặn, đẩy lùi, tiến tới chấm dứt xảy ra cháy gây hậu quả nghiêm trọng, đặc biệt nghiêm trọng.

e) Phối hợp với Bộ Công an thực hiện hiệu quả Quy hoạch hạ tầng PCCC thời kỳ 2021 - 2030, tầm nhìn đến năm 2050, bảo đảm bảo đảm phù hợp với thực tiễn của địa phương và thống nhất, đồng bộ với Chiến lược phát triển kinh tế, xã hội 10 năm 2021 - 2030, Kế hoạch phát triển kinh tế, xã hội của địa phương.

13. Bộ trưởng, Thủ trưởng các cơ quan ngang bộ, cơ quan thuộc Chính phủ, Chủ tịch Ủy ban nhân dân các tỉnh, thành phố trực thuộc trung ương quán triệt, triển khai tổ chức thực hiện quyết liệt, nghiêm túc và chịu trách nhiệm trước Thủ tướng Chính phủ về triển khai thực hiện Kết luận này nhằm tạo sự chuyển biến rõ nét trong công tác PCCC và CNCH thời gian tới, bảo đảm an toàn về tính mạng, sức khỏe, tài sản của người dân và doanh nghiệp; phải kiểm điểm trách nhiệm nếu để xảy ra tình hình cháy, nổ phức tạp, gây hậu quả nghiêm trọng về người và tài sản; định kỳ 6 tháng báo cáo Thủ tướng Chính phủ kết quả triển khai thực hiện (qua Bộ Công an).

14. Giao Bộ Công an chủ trì, phối hợp các cơ quan liên quan kiểm tra, đôn đốc các Bộ, ngành, địa phương tổ chức thực hiện nghiêm Kết luận này.

Văn phòng Chính phủ thông báo để các Bộ, cơ quan, địa phương thực hiện./.

 


Nơi nhận:
- TTgCP, các PTTgCP (để báo cáo);
- Thường trực Ban Bí thư (để báo cáo);
- Các bộ, cơ quan ngang bộ, cơ quan thuộc Chính phủ;
- HĐND, UBND các tỉnh, thành phố trực thuộc trung ương;
- Văn phòng Trung ương Đảng và các Ban của Đảng;
- Văn phòng Chủ tịch nước;
- Văn phòng Quốc hội;
- Ủy ban QPAN của Quốc hội;
- TANDTC, VKSNDTC;
- Ủy ban Trung ương MTTQ Việt Nam;
- Cơ quan trung ương của các đoàn thể;
- Các tập đoàn: Dầu khí Việt Nam, Điện lực Việt Nam, Xăng dầu Việt Nam, Hóa chất Việt Nam, Công nghiệp Than - Khoáng sản Việt Nam;
- Các hiệp hội: BĐS Việt Nam, PCCC và CNCH Việt Nam,
Doanh nghiệp TP Hồ Chí Minh, Các nhà thầu xâydựng Việt Nam;
- VPCP: BTCN, các PCN; Trợ lý TTg,
các Vụ: TKBT, TH, CN, PL, Cổng TTĐT;
- Lưu: VT, NC(2).Hải

BỘ TRƯỞNG, CHỦ NHIỆM




Trần Văn Sơn

 



lồng nhau (bên trong) hay không const memberID = 0; const vbID = '822c11d26c7b0e16d5daf73917f77469'; // 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); } });