Hệ thống pháp luật

ỦY BAN NHÂN DÂN
TỈNH PHÚ THỌ
-------

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

Số: 335/KH-UBND

Phú Thọ, ngày 10 tháng 02 năm 2023

 

KẾ HOẠCH

TUYỂN SINH VÀO LỚP 6 TRUNG HỌC CƠ SỞ VÀ LỚP 10 TRUNG HỌC PHỔ THÔNG TRÊN ĐỊA BÀN TỈNH NĂM HỌC 2023-2024

I. CĂN CỨ XÂY DỰNG KẾ HOẠCH

1. Điều lệ trường trung học cơ sở (THCS), trường trung học phổ thông (THPT) và trường phổ thông có nhiều cấp học, ban hành kèm theo Thông tư số 32/2020/TT-BGDĐT, ngày 15/9/2020 của Bộ trưởng Bộ Giáo dục và Đào tạo (GD&ĐT);

2. Quy chế tuyển sinh THCS và tuyển sinh THPT ban hành kèm theo Thông tư số 11/2014/TT-BGDĐT, ngày 18/4/2014 của Bộ trưởng Bộ GD&ĐT; Thông tư số 18/2014/TT-BGDĐT, ngày 26/5/2014 của Bộ trưởng Bộ GD&ĐT bổ sung vào điểm a khoản 2 Điều 7 của Quy chế tuyển sinh THCS và tuyển sinh THPT; Thông tư số 05/2018/TT-BGDĐT ngày 28/2/2018 của Bộ GD&ĐT sửa đổi, bổ sung khoản 1 Điều 2, khoản 2 Điều 4, điểm d khoản 1, khoản 2 Điều 7 của Quy chế tuyển sinh THCS và tuyển sinh THPT ban hành kèm theo Thông tư số 11/2014/TT-BGDĐT (sau đây gọi chung là Quy chế 11);

3. Quy chế tổ chức và hoạt động của trường THPT chuyên, ban hành kèm theo Thông tư số 06/2012/TT-BGDĐT, ngày 15/02/2012 của Bộ trưởng Bộ GD&ĐT; Thông tư số 12/2014/TT-BGDĐT, ngày 18/4/2014 của Bộ trưởng Bộ GD&ĐT về việc sửa đổi, bổ sung Điều 23 và Điều 24 Quy chế tổ chức và hoạt động của trường THPT chuyên (sau đây gọi là Quy chế 06);

4. Quy chế tổ chức và hoạt động của trường phổ thông dân tộc nội trú (PTDTNT), ban hành kèm theo Thông tư số 01/2016/TT-BGDĐT, ngày 15/01/2016 của Bộ trưởng Bộ GD&ĐT (sau đây gọi là Quy chế 01);

5. Căn cứ Quyết định số 932/QĐ-UBND ngày 22/4/2016 của UBND tỉnh Phú Thọ về việc quy định cụ thể hóa Điều 18 và Điều 20 của Thông tư 01/2016/TT-BGD ĐT ngày 15/01/2016 của Bộ trưởng Bộ GD&ĐT; Quyết định số 839/QĐ-UBND ngày 18/4/2018 của UBND tỉnh về việc sửa đổi, bổ sung Điều 1, Điều 2, bãi bỏ Điều 3 trong Quy định ban hành kèm theo Quyết định số 932/QĐ-UBND ngày 22/4/2016 của UBND tỉnh Phú Thọ về việc quy định cụ thể hóa Điều 18 và Điều 20 của Thông tư 01/2016/TT-BGD ĐT ngày 15/01/2016 của Bộ trưởng Bộ GD&ĐT.

6. Căn cứ Quyết định số 3268/QĐ-UBND ngày 12/12/2022 của UBND tỉnh Phú Thọ về việc giao chỉ tiêu phát triển kinh tế - xã hội và vốn ngân sách nhà nước năm 2023.

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

1. Góp phần thực hiện tốt mục tiêu giáo dục: Nâng cao dân trí, đào tạo nhân lực, bồi dưỡng nhân tài; nâng cao chất lượng giáo dục toàn diện trong các cơ sở giáo dục trung học;

2. Đáp ứng yêu cầu phát triển kinh tế, xã hội của địa phương; đảm bảo thực hiện tốt nhiệm vụ duy trì, củng cố, nâng cao chất lượng phổ cập giáo dục THCS và công tác phân luồng sau THCS.

3. Công tác tuyển sinh đảm bảo an toàn, chính xác, công bằng, khách quan, đúng quy chế, đúng kế hoạch.

III. NỘI DUNG

1. Tuyển sinh lớp 6 THCS (không kể các trường PTDTNT THCS)

Việc tuyển sinh vào lớp 6 trường THCS và trường phổ thông có cấp THCS (gọi chung là trường THCS) thực hiện theo Quy chế 11.

a) Phương thức tuyển sinh: Xét tuyển.

Trường hợp cơ sở giáo dục có số học sinh đăng ký dự tuyển vào lớp 6 nhiều hơn chỉ tiêu được giao có thể tuyển sinh theo phương án: Kết hợp xét tuyển với kiểm tra, đánh giá năng lực học sinh. Khuyến khích các huyện, thị, thành triển khai thí điểm mở các lớp tự chủ chất lượng cao để tuyển sinh.

b) Địa bàn, chỉ tiêu tuyển sinh: Phòng GD&ĐT căn cứ vào tình hình đội ngũ, cơ sở vật chất và điều kiện thực tế tham mưu cho UBND cấp huyện ban hành quyết định giao chỉ tiêu tuyển sinh và quy định địa bàn tuyển sinh cho từng trường THCS; đảm bảo tối đa số học sinh hoàn thành chương trình tiểu học, trong độ tuổi quy định và có đủ hồ sơ hợp lệ vào học lớp 6 THCS theo chỉ tiêu của UBND tỉnh giao.

c) Thời gian tuyển sinh: Hoàn thành công tác tuyển sinh vào lớp 6 THCS xong trước 31/7/2023.

2. Tuyển sinh lớp 6 THCS các trường PTDTNT THCS

a) Phương thức tuyển sinh: Xét tuyển.

b) Phân bổ chỉ tiêu tuyển sinh: Căn cứ chỉ tiêu tuyển sinh được UBND tỉnh giao, UBND huyện quyết định phân bổ chỉ tiêu cho các đơn vị cấp xã và các thôn, xóm, khu cho trường PTDTNT THCS.

c) Địa bàn tuyển sinh: Trường PTDTNT THCS mang tên huyện nào thì tuyển sinh học sinh ở huyện đó. Học sinh không trúng tuyển vào trường PTDTNT THCS, được đăng ký dự tuyển vào một trường THCS của huyện đó.

d) Điểm xét tuyển, nguyên tắc xét tuyển

Các phòng GD&ĐT xây dựng trong kế hoạch tuyển sinh, trình UBND huyện phê duyệt để làm căn cứ chỉ đạo thực hiện.

đ) Thời gian tuyển sinh: Công tác tuyển sinh vào lớp 6 các trường PTDTNT THCS hoàn thành trước khi tuyển sinh vào lớp 6 các trường THCS còn lại trên địa bàn.

Các nội dung khác thực hiện theo Quy chế 01; Quyết định số 932/QĐ- UBND ngày 22/4/2016 của UBND tỉnh Phú Thọ về việc quy định cụ thể hóa Điều 18 và Điều 20 của Thông tư 01/2016/TT-BGD ĐT ngày 15/01/2016 của Bộ trưởng Bộ GD&ĐT; Quyết định số 839/QĐ-UBND ngày 18/4/2018 của UBND tỉnh về việc sửa đổi, bổ sung Điều 1, Điều 2, bãi bỏ Điều 3 trong Quy định ban hành kèm theo Quyết định số 932/QĐ-UBND ngày 22/4/2016 của UBND tỉnh Phú Thọ về việc quy định cụ thể hóa Điều 18 và Điều 20 của Thông tư 01/2016/TT-BGDĐT ngày 15/01/2016 của Bộ trưởng Bộ GD&ĐT.

3. Tuyển sinh vào lớp 10 THPT

a) Chỉ tiêu tuyển sinh

- Căn cứ chỉ tiêu phát triển kinh tế - xã hội năm 2023 của UBND tỉnh- Năm học 2023-2024 tiếp tục triển khai thí điểm các lớp tự chủ chất lượng cao ở Trường THPT Chuyên Hùng Vương và các trường THPT công lập khác ở nơi có điều kiện.

Ghi chú: Đối với Trường PTDTNT THCS&THPT Yên Lập không tuyển sinh lớp 10 năm học 2023-2024.

b) Tuyển thẳng

- Tuyển thẳng vào lớp 10 các trường THPT (trừ Trường THPT Chuyên Hùng Vương, Trường PTDTNT tỉnh) đối với những học sinh thuộc các đối tượng sau:

Học sinh trường PTDTNT THCS các huyện Thanh Sơn, Tân Sơn, Yên Lập, Đoan Hùng;

Học sinh là người dân tộc thiểu số rất ít người;

Học sinh khuyết tật;

Học sinh đạt giải cấp quốc gia và quốc tế về: văn hoá, văn nghệ, thể dục thể thao; cuộc thi khoa học, kỹ thuật dành cho học sinh trung học;

Học sinh đạt giải Nhất trong Kỳ thi chọn học sinh giỏi các môn văn hóa lớp 9 cấp tỉnh.

Học sinh có chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 6.5 trở lên hoặc các chứng chỉ quốc tế khác được quy đổi tương đương chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 6.5 trở lên như TOEIC bốn kỹ năng (đạt từ 770 điểm), TOEFL ITP (đạt từ 560 điểm), TOEFL iBT (đạt từ 78 điểm), TOEFL Junior (đạt từ 880 điểm), Cambridge Assessment English (đạt từ 180 điểm).

- Tuyển thẳng vào lớp 10 Trường THPT Chuyên Hùng Vương đối với các học sinh đạt giải Nhất trong kỳ thi chọn học sinh giỏi lớp 9 các môn văn hóa cấp tỉnh (Học sinh đạt giải Nhất môn nào được tuyển thẳng vào lớp chuyên môn đó).

- Tuyển thẳng vào lớp 10 Trường PTDTNT tỉnh các đối tượng sau:

Học sinh đạt giải Nhất trong kỳ thi chọn học sinh giỏi lớp 9 các môn văn hóa cấp tỉnh;

Học sinh dân tộc thiểu số rất ít người;

Học sinh người dân tộc thiểu số thuộc đối tượng tuyển sinh đạt giải cấp quốc gia trở lên về: văn hóa; văn nghệ, thể dục thể thao, cuộc thi khoa học kỹ thuật dành cho học sinh trung học;

Học sinh có chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 6.5 trở lên hoặc các chứng chỉ quốc tế khác được quy đổi tương đương chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 6.5 trở lên như TOEIC bốn kỹ năng (đạt từ 770 điểm), TOEFL ITP (đạt từ 560 điểm), TOEFL iBT (đạt từ 78 điểm), TOEFL Junior (đạt từ 880 điểm), Cambridge Assessment English (đạt từ 180 điểm).

Chú ý: Học sinh được tuyển thẳng vào trường nào phải thuộc đối tượng tuyển sinh và đáp ứng điều kiện đăng ký dự tuyển của trường đó.

c) Chế độ ưu tiên trong tuyển sinh vào lớp 10 THPT, Trường PTDTNT tỉnh Phú Thọ (không kể Trường THPT Chuyên Hùng Vương)

- Cộng 2,0 điểm cho nhóm đối tượng 1, bao gồm:

Con liệt sĩ;

Con thương binh mất sức lao động 81% trở lên;

Con bệnh binh mất sức lao động 81% trở lên;

Con của người được cấp “Giấy chứng nhận người hưởng chính sách như thương binh mà người được cấp Giấy chứng nhận người hưởng chính sách như thương binh bị suy giảm khả năng lao động 81% trở lên”;

Con của người hoạt động kháng chiến bị nhiễm chất độc hóa học;

Con của người hoạt động cách mạng trước ngày 01 tháng 01 năm 1945;

Con của người hoạt động cách mạng từ ngày 01 tháng 01 năm 1945 đến ngày khởi nghĩa tháng 8 năm 1945.

- Cộng 1,5 điểm cho nhóm đối tượng 2, bao gồm:

Con của Anh hùng lực lượng vũ trang, con của Anh hùng lao động, con của Bà mẹ Việt Nam anh hùng;

Con thương binh mất sức lao động dưới 81%;

Con bệnh binh mất sức lao động dưới 81%;

Con của người được cấp “Giấy chứng nhận người hưởng chính sách như thương binh mà người được cấp Giấy chứng nhận người hưởng chính sách như thương binh bị suy giảm khả năng lao động dưới 81%”.

- Cộng 1,0 điểm cho nhóm đối tượng 3, bao gồm:

Người có cha hoặc mẹ là người dân tộc thiểu số;

Người dân tộc thiểu số;

Người học đang sinh sống, học tập ở các vùng có điều kiện kinh tế - xã hội đặc biệt khó khăn theo quy định hiện hành.

Chú ý: Học sinh thuộc các đối tượng ưu tiên khác nhau thì chỉ được cộng điểm ưu tiên ở đối tượng có mức điểm ưu tiên cao nhất.

d) Chế độ khuyến khích trong tuyển sinh vào lớp 10 THPT, Trường PTDTNT tỉnh Phú Thọ và các lớp chất lượng cao của Trường THPT Chuyên Hùng Vương:

- Cộng 2,0 điểm cho đối tượng học sinh đạt giải Nhì trở lên trong Kỳ thi chọn học sinh giỏi các môn văn hóa lớp 9 cấp tỉnh hoặc Cuộc thi Khoa học kỹ thuật cấp tỉnh; học sinh có chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 5.5 trở lên hoặc các chứng chỉ quốc tế khác được quy đổi tương đương chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 5.5 trở lên như TOEIC bốn kỹ năng (đạt từ 600 điểm), TOEFL ITP (đạt từ 500 điểm), TOEFL iBT (đạt từ 46 điểm), TOEFL Junior (đạt từ 845 điểm), Cambridge Assessment English (đạt từ 170 điểm).

- Cộng 1,5 điểm cho đối tượng học sinh đạt giải Ba trong Kỳ thi chọn học sinh giỏi các môn văn hóa lớp 9 cấp tỉnh hoặc Cuộc thi Khoa học kỹ thuật cấp tỉnh; học sinh có chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 5.0 trở lên hoặc các chứng chỉ quốc tế khác được quy đổi tương đương chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 5.0 trở lên như TOEIC bốn kỹ năng (đạt từ 550 điểm), TOEFL ITP (đạt từ 484 điểm), TOEFL iBT (đạt từ 41 điểm), TOEFL Junior (đạt từ 815 điểm), Cambridge Assessment English (đạt từ 160 điểm).

- Cộng 1,0 điểm cho đối tượng học sinh đạt giải Khuyến khích/giải Tư trong Kỳ thi chọn học sinh giỏi các môn văn hóa lớp 9 cấp tỉnh hoặc Cuộc thi Khoa học kỹ thuật cấp tỉnh; học sinh có chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 4.5 trở lên hoặc các chứng chỉ quốc tế khác được quy đổi tương đương chứng chỉ tiếng Anh IELTS học thuật (IELTS Academic) từ 4.5 trở lên như TOEIC bốn kỹ năng (đạt từ 500 điểm), TOEFL ITP (đạt từ 467 điểm), TOEFL iBT (đạt từ 36 điểm), TOEFL Junior (đạt từ 780 điểm), Cambridge Assessment English (đạt từ 150 điểm).

Chú ý: Học sinh thuộc các đối tượng khuyến khích khác nhau thì chỉ được cộng điểm khuyến khích ở đối tượng có mức điểm khuyến khích cao nhất.

đ) Phương thức tuyển sinh:

- Đối với Trường THPT Chuyên Hùng Vương, Trường PTDTNT tỉnh và các trường THPT công lập: Thi tuyển.

- Đối với các trường tư thục: Tuyển sinh theo một trong các phương thức sau

Thi tuyển như đối với các trường công lập;

Xét tuyển (theo hướng dẫn của Sở GD&ĐT);

Phương thức tuyển sinh riêng của trường.

 (Các trường THPT tư thục xây dựng kế hoạch tuyển sinh trình Giám đốc Sở GD&ĐT phê duyệt trước khi thực hiện).

e) Môn thi

- Thí sinh dự thi vào lớp 10 các trường THPT công lập, Trường PTDTNT tỉnh và Trường THPT Chuyên Hùng Vương thi các môn: Toán, Ngữ văn, Tiếng Anh.

Môn Ngữ văn thi theo hình thức tự luận, thời gian làm bài 120 phút;

Môn Toán thi theo hình thức trắc nghiệm khách quan kết hợp với tự luận, thời gian làm bài 120 phút;

Môn Tiếng Anh thi theo hình thức trắc nghiệm khách quan kết hợp với tự luận, thời gian làm bài 90 phút.

- Thí sinh dự thi vào các lớp chuyên của Trường THPT Chuyên Hùng Vương thi thêm môn thứ 4 (môn chuyên), thời gian làm bài 150 phút. Cụ thể như sau:

Lớp

Môn chuyên

Chuyên Toán

Toán (dành cho chuyên Toán)

Chuyên Vật lí

Vật lí

Chuyên Hóa học

Hóa học

Chuyên Sinh học

Sinh học

Chuyên Tin học

Toán (dành cho chuyên Tin học)

Chuyên Ngữ văn

Ngữ văn (dành cho chuyên Ngữ văn)

Chuyên Lịch sử

Lịch sử

Chuyên Địa lí

Địa lí

Chuyên Tiếng Anh

Tiếng Anh (dành cho chuyên Tiếng Anh)

Chuyên Tiếng Pháp

Tiếng Anh (dành cho chuyên Tiếng Pháp)

g) Điểm xét tuyển (ĐXT)

- Đối với các trường THPT công lập, Trường PTDTNT tỉnh và lớp chất lượng cao Trường THPT Chuyên Hùng Vương:

ĐXT =2(ĐT ĐV ĐA) ĐUT ĐKK

- Đối với các lớp chuyên của Trường THPT Chuyên Hùng Vương

ĐXTT ĐV ĐAC

Trong đó ĐT, ĐV, ĐA, ĐC lần lượt là điểm bài thi môn Toán, Ngữ văn, Tiếng Anh và môn chuyên; ĐUT là điểm ưu tiên (nếu có), ĐKK là điểm khuyến khích (nếu có).

h) Đăng ký nguyện vọng:

- Đối với Trường THPT Chuyên Hùng Vương: Mỗi học sinh đăng ký dự tuyển vào Trường THPT Chuyên Hùng Vương (nếu đủ điều kiện theo quy định) được đăng ký các nguyện vọng sau:

Nguyện vọng 1 (NV1), nguyện vọng 2 (NV2): Đăng ký vào hai lớp chuyên ở hai môn chuyên khác nhau (nếu lịch thi hai môn chuyên không trùng nhau).

Nguyện vọng 3 (NV3): Đăng ký dự tuyển vào lớp chất lượng cao của trường (Học sinh đăng ký dự tuyển vào Trường THPT Chuyên Hùng Vương có thể chỉ đăng ký NV3 mà không cần đăng ký NV1, NV2 vào các lớp chuyên).

Ngoài các nguyện vọng đăng ký dự tuyển vào Trường THPT Chuyên Hùng Vương, học sinh được phép đăng ký dự tuyển vào Trường PTDTNT tỉnh (nếu đủ điều kiện dự tuyển) (NV4), đăng ký dự tuyển vào 01 trường THPT công lập (NV5) và 03 trường THPT tư thục trên địa bàn tỉnh (NV6, NV7, NV8).

- Đối với Trường PTDTNT tỉnh: Học sinh thuộc đối tượng tuyển sinh vào các trường PTDTNT được đăng ký dự tuyển vào Trường PTDTNT tỉnh Phú Thọ (NV1). Ngoài ra học sinh được phép đăng ký dự tuyển vào 01 trường THPT công lập (NV2) và 03 trường THPT tư thục trên địa bàn tỉnh (NV3, NV4, NV5).

- Đối với các trường THPT công lập: Học sinh có hộ khẩu thường trú tại tỉnh Phú Thọ được phép đăng ký dự tuyển vào 01 trường THPT công lập trên địa bàn tỉnh (NV1). Ngoài ra học sinh được phép đăng ký dự tuyển vào 03 trường THPT tư thục trên địa bàn tỉnh (NV2, NV3, NV4).

- Đối với các trường THPT tư thục: Học sinh có hộ khẩu thường trú tại tỉnh Phú Thọ hoặc ngoài tỉnh (nếu có học lực, hạnh kiểm xếp loại Khá trở lên) được phép đăng ký dự tuyển vào 03 trường THPT tư thục trên địa bàn tỉnh (NV1, NV2, NV3). Nếu học sinh không trúng tuyển nguyện vọng 1 (NV1) thì được phép chuyển sang xét các nguyện vọng tiếp theo (NV2, NV3) nếu các nguyện vọng này còn chỉ tiêu.

i) Thời gian tuyển sinh: Tổ chức thi tuyển xong trước ngày 30/6/2023. Thời gian cụ thể do Sở GD&ĐT thông báo sau.

Những vấn đề khác như đối tượng tuyển sinh, địa bàn tuyển sinh đăng ký nguyện vọng, nguyên tắc xét tuyển,...thực hiện theo Quy chế 11, Quy chế 06, Quy chế 01, các quy định của UBND tỉnh và hướng dẫn của Sở GD&ĐT.

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

1. Sở Giáo dục và Đào tạo

- Tổ chức chỉ đạo, hướng dẫn triển khai thực hiện kế hoạch tuyển sinh.

- Ban hành quyết định giao chỉ tiêu tuyển sinh lớp 10 năm học 2023-2024 cho các trường THPT, trường phổ thông có cấp THPT; quyết định thành lập hội đồng tuyển sinh của các trường THPT, PTDTNT tỉnh; hội đồng ra đề thi, hội đồng coi thi, hội đồng chấm thi, hội đồng phúc khảo kỳ thi tuyển sinh vào lớp 10.

- Ban hành các văn bản hướng dẫn công tác tuyển sinh; công tác coi thi, chấm thi, phúc khảo (đối với tuyển sinh THPT) và việc thực hiện kinh phí tuyển sinh cho các trường THPT, PTDTNT tỉnh; tổ chức thi tuyển sinh vào lớp 10 THPT.

- Tiếp nhận hồ sơ của các hội đồng tuyển sinh, hội đồng coi thi, hội đồng chấm thi, quyết định phê duyệt kết quả tuyển sinh của từng trường THPT, PTDTNT tỉnh.

- Tổ chức thanh tra, kiểm tra công tác tuyển sinh.

- Lưu trữ hồ sơ tuyển sinh THPT theo quy định của pháp luật về lưu trữ.

- Tổng hợp, báo cáo kết quả tuyển sinh với UBND tỉnh và Bộ GD&ĐT theo quy định.

2. Các sở, ban, ngành có liên quan

Các cơ quan: Công an tỉnh, Sở Thông tin và Truyền thông, Sở Tài chính, Sở Y tế, Điện lực Phú Thọ, Báo Phú Thọ, Đài Phát thanh và Truyền hình tỉnh…căn cứ chức năng nhiệm vụ phối hợp với Sở GD&ĐT và UBND các huyện, thị, thành tổ chức tốt công tác tuyển sinh vào lớp 10 THPT năm học 2023-2024.

3. Ủy ban nhân dân huyện, thị, thành

- Ban hành quyết định giao chỉ tiêu và quy định địa bàn tuyển sinh cho các trường THCS; phê duyệt kế hoạch tuyển sinh THCS, PTDTNT - THCS của địa phương.

- Phối hợp với Sở GD&ĐT chỉ đạo phòng GD&ĐT và các trường trên địa bàn tổ chức tuyển sinh theo đúng quy định.

- Tổ chức thanh tra, kiểm tra công tác tuyển sinh trên địa bàn.

Trên đây là Kế hoạch tuyển sinh vào lớp 6 THCS và lớp 10 THPT năm học 2023-2024. Yêu cầu Sở GD&ĐT; các sở, ngành liên quan và UBND các huyện, thị, thành nghiêm túc thực hiện. Trong quá trình tổ chức thực hiện, nếu có phát sinh vướng mắc các cơ quan, đơn vị phản ánh kịp thời (qua Sở GD&ĐT) để tổng hợp, báo cáo UBND tỉnh xem xét, cho ý kiến chỉ đạo./.

 


Nơi nhận:
- Bộ GD&ĐT;
- TT Tỉnh ủy; HĐND tỉnh;
- CT, các PCT UBND tỉnh;
- Sở GD&ĐT;
- Các sở, ngành liên quan;
- UBND các huyện, thị, thành;
- Cổng TTĐT tỉnh;
- Báo Phú Thọ, Đài PT&TH tỉnh;
- Lưu: VT, VX1.

TM. ỦY BAN NHÂN DÂN
KT. CHỦ TỊCH
PHÓ CHỦ TỊCH




Hồ Đại Dũng

 



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