Hệ thống pháp luật

ỦY BAN NHÂN DÂN
TỈNH BẮC GIANG
-------

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

Số: 102/KH-UBND

Bắc Giang, ngày 09 tháng 6 năm 2023

 

KẾ HOẠCH

THỰC HIỆN KẾ HOẠCH SỐ 1265-KH/BCSĐ NGÀY 24/5/2023 CỦA BAN CÁN SỰ ĐẢNG UBND TỈNH VỀ TRIỂN KHAI THỰC HIỆN CHỈ THỊ SỐ 25-CT/TU NGÀY 10/5/2023 CỦA BAN THƯỜNG VỤ TỈNH ỦY

Thực hiện Kế hoạch số 1265-KH/BCSĐ ngày 24/5/2023 của Ban cán sự đảng UBND tỉnh về triển khai thực hiện Chỉ thị số 25-CT/TU ngày 10/5/2023 của Ban Thường vụ Tỉnh ủy về tăng cường vai trò, trách nhiệm của người đứng đầu cấp ủy, chính quyền trong công tác tiếp công dân, giải quyết khiếu nại, tố cáo; Chủ tịch UBND tỉnh ban hành Kế hoạch triển khai thực hiện như sau:

I. MỤC ĐÍCH, YÊU CẦU

1. Nhằm cụ thể hóa và triển khai thực hiện hiệu quả các mục tiêu, nhiệm vụ và giải pháp về công tác tiếp công dân, giải quyết khiếu nại, tố cáo tại Kế hoạch số 1265-KH/BCSĐ ngày 24/5/2023 của Ban cán sự đảng UBND tỉnh.

2. Tập trung khắc phục những tồn tại, hạn chế trong công tác tiếp công dân, giải quyết khiếu nại, tố cáo và xác định rõ các nội dung, nhiệm vụ trọng tâm phải thực hiện trong thời gian tới; xác định rõ trách nhiệm của các cấp, các ngành và địa phương; phát huy sức mạnh của hệ thống chính trị trong quá trình tổ chức thực hiện, góp phần đảm bảo an ninh, trật tự, phục vụ mục tiêu phát triển kinh tế - xã hội trên địa bàn tỉnh.

3. Quá trình tổ chức thực hiện phải bám sát Chỉ thị số 25-CT/TU ngày 10/5/2023 của Ban Thường vụ Tỉnh ủy và Kế hoạch số 1265-KH/BCSĐ ngày 24/5/2023 của Ban cán sự đảng UBND tỉnh.

II. NỘI DUNG THỰC HIỆN

1. Về công tác tiếp công dân, xử lý đơn

- Các cấp, các ngành quán triệt, triển khai thực hiện nghiêm túc Luật Tiếp công dân và các văn bản hướng dẫn thi hành; bám sát các văn bản chỉ đạo của cấp trên về thực hiện chế độ, trách nhiệm công tác tiếp dân- Chủ tịch UBND tỉnh tiếp công dân tại Trụ sở tiếp công dân UBND tỉnh theo quy định; phân công các Phó Chủ tịch UBND tỉnh về tiếp công dân tại các địa phương có tình hình khiếu kiện phức tạp, phát sinh nhiều đơn thư; lãnh đạo các sở, cơ quan thuộc UBND tỉnh và UBND các huyện, thành phố tham dự nghiêm túc các phiên tiếp công dân của Chủ tịch UBND tỉnh, Phó Chủ tịch UBND tỉnh để phối hợp tiếp, trả lời và kịp thời xử lý những ý kiến của công dân.

- Giám đốc các sở, cơ quan thuộc UBND tỉnh và Chủ tịch UBND các huyện, thành phố:

Bố trí trụ sở tiếp công dân, địa điểm tiếp công dân và chuẩn bị các điều kiện thuận lợi để phục vụ công tác tiếp công dân; rà soát, ban hành và công khai nội quy tiếp công dân, thực hiện đúng nội quy tiếp công dân đã ban hành; thông báo công khai lịch tiếp công dân. Phân công cán bộ, công chức làm công tác tiếp công dân có phẩm chất đạo đức tốt và phải được tập huấn, bồi dưỡng nghiệp vụ trước khi thực hiện nhiệm vụ.

Thực hiện quy trình, thủ tục tiếp công dân khoa học, phù hợp với tình hình đơn vị, địa phương; xử lý ngay, xử lý kịp thời các ý kiến của công dân tại phiên tiếp công dân; chỉ đạo thực hiện tiếp nhận, phân loại xử lý đơn chặt chẽ, đúng quy trình, đúng thẩm quyền và đảm bảo đúng thời hạn; sau các phiên tiếp công dân phải thông báo kết quả tiếp công dân và các ý kiến chỉ đạo của người tiếp công dân; gắn việc tiếp công dân với chỉ đạo giải quyết vụ việc ngay từ khi mới phát sinh, tập trung giải quyết các vụ việc đã được tiếp nhận tại phiên tiếp công dân.

Đối với Chủ tịch UBND các huyện, thành phố: Ngoài việc tiếp công dân định kỳ, cần tăng cường tổ chức tiếp công dân đột xuất (nhất là trong thời gian diễn ra các sự kiện chính trị quan trọng của đất nước, của tỉnh) để đối thoại, xử lý, giải quyết các vụ việc đông người, vụ việc phức tạp và các vụ việc công dân còn lên tỉnh và ra Trung ương khiếu kiện; phân công các Phó Chủ tịch UBND huyện về tiếp công dân tại cấp xã (trường hợp cần thiết về tại thôn, tổ dân phố…) phát sinh nhiều đơn thư, có tình hình khiếu kiện phức tạp; tiếp tục chỉ đạo Chủ tịch UBND cấp xã rà soát, bố trí địa điểm tiếp dân tiếp công dân riêng, thông báo công khai lịch tiếp công dân hằng tuần và vào ngày 15 hằng tháng, tăng cường hoạt động của các Tổ hòa giải ở cơ sở.

2. Về theo dõi tình hình khiếu kiện và giải quyết khiếu nại, tố cáo

- Các cấp, các ngành theo dõi, nắm chắc tình hình khiếu kiện theo lĩnh vực, địa bàn; thực hiện tốt việc đánh giá và dự báo tình hình khiếu kiện của công dân để chủ động đề ra giải pháp xử lý, giải quyết, không để bị động, bất ngờ; kịp thời xử lý, phối hợp xử lý liên quan đến các vụ việc, công dân khiếu kiện vượt cấp lên tỉnh, ra Trung ương- Giám đốc sở, thủ trưởng các cơ quan thuộc UBND tỉnh và Chủ tịch UBND các huyện, thành phố xem xét, giải quyết các vụ việc theo đúng thẩm quyền; giải quyết vụ việc ngay từ khi mới phát sinh và vụ việc do cấp trên chuyển về đảm bảo đúng quy trình, thủ tục, không để vụ việc kiến nghị, phản ánh chuyển thành vụ việc khiếu nại, tố cáo, với phương châm “Giải quyết dứt điểm, hết thẩm quyền, hết trách nhiệm, thấu tình, đạt lý vụ việc để yên dân và ổn định tình hình; xử lý nghiêm các sai phạm phát hiện qua giải quyết đơn, thư; chuyển ngay các vụ việc có dấu hiệu phạm tội sang cơ quan điều tra; thực hiện nghiêm túc việc công khai kết quả giải quyết theo quy định của pháp luật”; chịu trách nhiệm nếu để vụ việc bị cấp trên hủy bỏ, cải sửa, yêu cầu giải quyết lại; xây dựng kế hoạch để tổ chức thi hành các quyết định, kết luận giải quyết vụ việc (các quyết định, kết luận giải quyết vụ việc phải được thiết lập thành hồ sơ để theo dõi, đôn đốc và thi hành).

- Giám đốc các sở, thủ trưởng cơ quan thuộc UBND tỉnh nâng cao chất lượng công tác tham mưu giải quyết vụ việc; tập trung xác minh, kết luận và đề xuất Chủ tịch UBND tỉnh giải quyết các vụ việc đúng quy trình, thủ tục và đảm bảo thời hạn, chất lượng các vụ việc được giao.

Chủ tịch UBND các huyện, thành phố trực tiếp chỉ đạo trong công tác giải quyết khiếu nại, tố cáo; chịu trách nhiệm trước Chủ tịch UBND tỉnh về kết quả giải quyết đơn thuộc thẩm quyền và chất lượng giải quyết của Chủ tịch UBND cấp xã.

3. Rà soát, giải quyết và xử lý vụ việc đông người, phức tạp, kéo dài

- Người đứng đầu các cấp, các ngành tập trung giải quyết các vụ việc đông người, phức tạp, kéo dài theo chỉ đạo, hướng dẫn của cấp trên- Quá trình giải quyết phải thực hiện tốt nội dung sau: làm rõ nội dung, nguyên nhân phát sinh vụ việc; xem xét toàn diện các khía cạnh pháp lý, gắn với tuyên truyền, vận động, gặp gỡ, đối thoại và có phương án, biện pháp xử lý linh hoạt, phù hợp với thực tiễn, không để vụ việc phát sinh thành “điểm nóng”; thực hiện công khai kết quả kiểm tra, rà soát vụ việc tại nơi cư trú của công dân, tạo sự đồng thuận trong Nhân dân (thành phần công khai phải có: cấp giải quyết, cấp dưới của cấp giải quyết, Uỷ ban MTTQ Việt Nam cấp xã, các đoàn thể cấp xã và các tổ chức, cá nhân có liên quan); phối hợp với các cơ quan báo, đài để tuyên truyền, đưa tin về kết quả giải quyết, đồng thời thông báo đến cơ quan, đơn vị có liên quan để phối hợp theo dõi, phục vụ việc xử lý đơn và thống nhất trả lời công dân.

4. Về nâng cao công tác quản lý Nhà nước và tuyên truyền phổ biến pháp luật về tiếp công dân, khiếu nại, tố cáo

- Các sở, cơ quan thuộc UBND tỉnh và UBND các huyện, thành phố tăng cường công tác quản lý Nhà nước và công khai minh bạch trên các lĩnh vực (nhất là trong lĩnh vực đất đai, đầu tư, xây dựng, tài chính, chính sách xã hội...); thường xuyên rà soát, khắc phục những bất cập trong công tác quản lý; thực hiện tốt công tác cải cách hành chính, các quy định về thực hành tiết kiệm, chống lãng phí và phòng, chống tham nhũng, tiêu cực, gắn với thực hiện tốt Quy chế dân chủ ở cơ sở nhằm hạn chế phát sinh khiếu nại, tố cáo.

- Giám đốc sở, thủ trưởng các cơ quan thuộc UBND tỉnh và Chủ tịch UBND các huyện, thành phố: xây dựng kế hoạch tuyên truyền, phổ biến, giáo dục pháp luật nói chung gắn với pháp luật về tiếp công dân, khiếu nại, tố cáo nói riêng; tập trung tuyên truyền trước khi triển khai thực hiện các dự án nhất là các dự án phải thu hồi đất để phát triển kinh tế - xã hội và tại các địa phương, cơ sở có tình hình khiếu kiện phức tạp; cung cấp kịp thời, trung thực, khách quan về tình hình tiếp công dân, giải quyết khiếu nại, tố cáo cho các cơ quan báo, đài để thông tin, tuyên truyền về công tác tiếp công dân, giải quyết khiếu nại, tố cáo.

5. Về công tác thanh tra, kiểm tra trách nhiệm và xử lý vi phạm trong công tác tiếp công dân, giải quyết khiếu nại, tố cáo

- Giám đốc các sở, thủ trưởng cơ quan thuộc UBND tỉnh và Chủ tịch UBND các huyện, thành phố phải xác định công tác thanh tra, kiểm tra trách nhiệm trong việc thực hiện các quy định của pháp luật về tiếp công dân, khiếu nại, tố cáo là nhiệm vụ thường xuyên; định kỳ hằng năm có kế hoạch thanh tra, kiểm tra trách nhiệm người đứng đầu cơ quan, đơn vị cấp dưới (nội dung thanh tra, kiểm tra tập trung vào công tác chỉ đạo điều hành; việc thực hiện quy trình, thủ tục tiếp công dân, xử lý, giải quyết đơn; các vụ việc do cấp trên chuyển về và vụ việc công dân khiếu kiện vượt cấp; việc tổ chức thực hiện Quyết định, Kết luận giải quyết khiếu nại, tố cáo…), đồng thời chủ động thanh tra, kiểm tra đột xuất đối với địa phương, đơn vị phát sinh nhiều đơn thư vượt cấp, để xảy ra khiếu kiện phức tạp.

- Người đứng đầu cơ quan, đơn vị kịp thời nhắc nhở, kiểm điểm, phê bình, xử lý kỷ luật nghiêm cán bộ, công chức thiếu trách nhiệm trong việc tiếp công dân, xử lý đơn và giải quyết khiếu nại, tố cáo; người đứng đầu cơ quan, đơn vị cấp trên xử lý nghiêm trách nhiệm người đứng đầu cơ quan, đơn vị cấp dưới nếu để tái diễn những hạn chế, khuyết điểm đã được chỉ ra trước đó.

6. Công tác đào tạo, bồi dưỡng và phát triển cán bộ, công chức làm công tác tiếp công dân, giải quyết khiếu nại, tố cáo

- Người đứng đầu cơ quan, đơn vị thường xuyên quan tâm đến công tác đào tạo, tập huấn, bồi dưỡng nâng cao chất lượng, trình độ, kỹ năng, nghiệp vụ cho đội ngũ cán bộ, công chức làm công tác tiếp công dân, xử lý đơn và giải quyết khiếu nại, tố cáo (thực hiện đào tạo, tập huấn, bồi dưỡng theo nhóm đối tượng). Trong đó, Thanh tra tỉnh xây dựng kế hoạch đào tạo, bồi dưỡng cho cán bộ, công chức toàn tỉnh theo Kế hoạch, hướng dẫn của Thanh tra Chính phủ; chủ động tiến hành tập huấn, bồi dưỡng nghiệp vụ cho cán bộ, công chức các sở, ngành và cấp huyện; chỉ đạo Thanh tra cấp huyện tập huấn, bồi dưỡng nghiệp vụ cho cán bộ, công chức cấp xã.

- Các cơ quan, đơn vị tăng cường đầu tư cơ sở vật chất, trang thiết bị, đẩy mạnh ứng dụng công nghệ thông tin phục vụ cho công tác tiếp công dân, giải quyết KNTC; quan tâm thực hiện đầy đủ các chính sách, chế độ đãi ngộ cho đội ngũ cán bộ làm công tác tiếp công dân, xử lý đơn và tham mưu giải quyết khiếu nại, tố cáo ở các cấp, các ngành. Theo dõi, đánh giá chặt chẽ việc thực hiện nhiệm vụ của cán bộ, công chức; lấy kết quả, chất lượng công tác tiếp công dân, giải quyết khiếu nại, tố cáo là tiêu chí đánh giá xếp loại cán bộ, công chức và đề bạt bổ nhiệm; kịp thời động viên, khen thưởng cán bộ, công chức có thành tích xuất sắc trong thực hiện nhiệm vụ tiếp công dân, xử lý đơn và tham mưu giải quyết khiếu nại, tố cáo.

7. Công tác phối hợp tiếp công dân, giải quyết khiếu nại, tố cáo

- Các cấp, các ngành duy trì thường xuyên công tác phối hợp, trao đổi trong công tác tiếp công dân, xử lý đơn, giải quyết khiếu nại, tố cáo; cung cấp đầy đủ thông tin, tài liệu và tham gia tố tụng hành chính theo đề nghị của Toà án Nhân dân các cấp; phối hợp và tạo điều kiện để Đoàn Luật sư, Hội Luật gia, Trợ giúp viên pháp lý tham gia các hoạt động tiếp công dân, giải quyết khiếu nại, tố cáo, nhằm hỗ trợ người dân hiểu biết pháp luật và đảm bảo vụ việc được xem xét giải quyết khách quan, đúng quy định; tạo điều kiện thuận lợi cho cơ quan truyền thông đưa tin đầy đủ, chính xác, không để kẻ xấu lợi dụng xuyên tạc, kích động làm ảnh hưởng đến an ninh, trật tự.

- Người đứng đầu các cấp, các ngành cung cấp đầy đủ hồ sơ, tài liệu, thông tin phục vụ hoạt động giám sát của HĐND, Ủy ban MTTQ Việt Nam các cấp về thực hiện pháp luật tiếp công dân, khiếu nại, tố cáo; chủ động kiến nghị giám sát đối với một số vụ việc khiếu kiện đông người, kéo dài đã được các cấp, các ngành xem xét giải quyết, được rà soát nhưng công dân vẫn khiếu kiện phức tạp. Phối hợp chặt chẽ với cơ quan công an cùng cấp để theo dõi, xử lý, ngăn chặn, không để công dân tập trung đông người vượt cấp lên tỉnh, ra Trung ương khiếu kiện; cung cấp hồ sơ, tài liệu và thông tin liên quan để củng cố hồ sơ xử lý các đối tượng có hành vi kích động, lôi kéo công dân khiếu kiện trái pháp luật hoặc lợi dụng quyền khiếu nại, tố cáo để gây rối trật tự công cộng.

III. TỔ CHỨC THỰC HIỆN

1. Trên cơ sở Kế hoạch này, Giám đốc sở, thủ trưởng các cơ quan thuộc UBND tỉnh và Chủ tịch UBND các huyện, thành phố xây dựng kế hoạch cụ thể để triển khai thực hiện phù hợp với đơn vị, địa phương.

2. Giám đốc sở, thủ trưởng các cơ quan thuộc UBND tỉnh tham mưu Chủ tịch UBND tỉnh giải quyết kịp thời, đúng pháp luật các vụ việc thuộc thẩm quyền của Chủ tịch UBND tỉnh khi được giao.

Thanh tra tỉnh: tham mưu Chủ tịch UBND tỉnh lãnh đạo, chỉ đạo để nâng cao chất lượng, hiệu quả trong công tác tiếp công dân, giải quyết khiếu nại, tố cáo trên địa bàn tỉnh; thường xuyên theo dõi và nắm chắc tình hình khiếu kiện trên địa bàn tỉnh; hướng dẫn, kiểm tra, đôn đốc các cơ quan, đơn vị thực hiện tốt công tác tiếp công dân, xử lý đơn, giải quyết khiếu nại, tố cáo, thi hành các Quyết định, Kết luận giải quyết khiếu nại, tố cáo; chỉ đạo thực hiện nghiêm túc, hiệu quả các cuộc thanh tra, kiểm tra trách nhiệm về tiếp công dân, giải quyết khiếu nại, tố cáo theo kế hoạch và đột xuất; quan tâm tập huấn, bồi dưỡng cho đội ngũ cán bộ, công chức trực tiếp làm công tác tiếp công dân, xử lý đơn và tham mưu giải quyết khiếu nại, tố cáo; tham mưu Chủ tịch UBND tỉnh có văn bản phê bình, yêu cầu kiểm điểm, xử lý trách nhiệm đối với người đứng đầu các cơ quan, đơn vị thiếu trách nhiệm trong công tác tiếp dân, giải quyết khiếu nại, tố cáo; tham mưu Ban cán sự đảng UBND tỉnh, Chủ tịch UBND tỉnh thực hiện các nhiệm vụ được giao tại Chỉ thị số 25-CT/TU ngày 10/5/2023 của Ban Thường vụ Tỉnh ủy và Kế hoạch số 1265-KH/BCSĐ ngày 24/5/2023 của Ban cán sự đảng UBND tỉnh.

Sở Tài nguyên và Môi trường: thực hiện tốt việc tư vấn, hướng dẫn các huyện, thành phố và cấp xã về công tác hòa giải, giải quyết các vụ việc tranh chấp đất đai và các vụ việc khiếu nại trong lĩnh vực đất đai; ban hành và tham mưu UBND tỉnh, Chủ tịch UBND tỉnh ban hành các văn bản chấn chỉnh, chỉ đạo xử lý nghiêm các vi phạm về đất đai, kịp thời, giải quyết các vụ việc khiếu kiện liên quan đến đất đai, môi trường, khoáng sản…; tăng cường thanh tra chuyên đề, thanh tra đột xuất đối với cấp huyện, cấp xã có nhiều vi phạm về đất đai và phát sinh nhiều vụ việc khiếu kiện về đất đai.

3. Công an tỉnh: chỉ đạo các phòng chức năng và Công an các huyện, thành phố thực hiện tốt công tác phối hợp trong tiếp công dân và đảm bảo an ninh, trật tự tại trụ sở, địa điểm tiếp công dân; theo dõi, nắm chắc tình hình các đoàn khiếu kiện, các hội, nhóm khiếu kiện và các điểm tranh chấp, khiếu kiện đông người để tham mưu, kiến nghị cấp ủy, chính quyền cùng cấp có biện pháp chỉ đạo, giải quyết kịp thời; xử lý nghiêm các đối tượng có hành vi kích động, lôi kéo, xúi giục công dân khiếu kiện trái pháp luật và các đối tượng lợi dụng quyền khiếu nại, tố cáo để gây mất trật tự công cộng.

4. Đề nghị HĐND tỉnh tăng cường công tác giám sát việc thực hiện pháp luật về tiếp công dân, giải quyết khiếu nại, tố cáo; tăng cường giám sát đối với vụ việc khiếu kiện đông người, kéo dài đã được các cấp, các ngành xem xét giải quyết, được rà soát nhưng công dân vẫn khiếu kiện phức tạp.

Đề nghị Ủy ban MTTQ Việt Nam và các tổ chức chính trị - xã hội từ tỉnh đến cơ sở tăng cường phối hợp với chính quyền cùng cấp trong việc tuyên truyền pháp luật về tiếp công dân và khiếu nại, tố cáo; giám sát việc thực hiện công khai trong giải quyết vụ việc; đồng thời vận động thuyết phục các thành viên, hội viên tự giác chấp hành kết quả giải quyết, chấm dứt khiếu kiện đối với các vụ việc đã được xem xét, giải quyết đúng chính sách pháp luật.

5. Sở Tư pháp, Báo Bắc Giang, Đài Phát thanh và Truyền hình tỉnh, Đài Truyền thanh các huyện, thành phố tăng cường tuyên truyền, phổ biến pháp luật về những nội dung cơ bản của Luật Tiếp công dân, Luật Khiếu nại, Luật Tố cáo, các văn bản hướng dẫn thi hành; tăng cường tuyên truyền, phát phóng sự, đưa tin về tình hình, kết quả công tác tiếp công dân, giải quyết khiếu nại, tố cáo và xử lý các đối tượng các hành vi vi phạm pháp luật tiếp công dân, khiếu nại, tố cáo.

Giao Thanh tra tỉnh theo dõi, kiểm tra, đôn đốc việc thực hiện Kế hoạch này; kết quả báo cáo UBND tỉnh, Chủ tịch UBND tỉnh theo quy định./.

 


Nơi nhận:
- Văn phòng Chính phủ;
- Thanh tra CP, Ban TCDTW;
- Thường trực TU, HĐND tỉnh;
- Chủ tịch, các PCT UBND tỉnh;
- Ban cán sự đảng UBND tỉnh;
- Đoàn ĐBQH tỉnh;
- UB MTTQ và các đoàn thể tỉnh;
- Các sở, cơ quan thuộc UBND tỉnh (t/h);
- Báo Bắc Giang, Đài PT&TH tỉnh;
- UBND các huyện, thành phố (t/h);
- VP UBND tỉnh:
LĐVP, TH, HC-TC, NC;
Cổng TTĐT tỉnh;
Lưu: VT, TCD (02).

CHỦ TỊCH




Lê Ánh Dương

 



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