ỦY BAN NHÂN DÂN TỈNH QUẢNG NINH -------
CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM Độc lập - Tự do - Hạnh phúc ---------------
Số: 233/KH-UBND
Quảng Ninh, ngày 12 tháng 9 năm 2023
KẾ HOẠCH
SẢN XUẤT CÂY VỤ ĐÔNG NĂM 2023
Vụ Đông là vụ sản xuất hàng hóa quan trọng đối với sản xuất trồng trọt, sản phẩm cây vụ Đông rất đa dạng, thị trường tiêu thụ rộng, ổn định và mang lại thu nhập cao cho người dân. Kết quả trong sản xuất vụ Đông có ý nghĩa quan trọng đối với sự tăng trưởng lĩnh vực Trồng trọt. Với mục tiêu đẩy mạnh sản xuất vụ Đông theo hướng hàng hóa, nâng cao giá trị sản phẩm trên một đơn vị diện tích đất canh tác, tăng hệ số sử dụng đất và từng bước đưa vụ Đông trở thành một trong các vụ sản xuất chính trong năm, góp phần tăng tỷ trọng lĩnh vực trồng trọt trong cơ cấu ngành Nông nghiệp của tỉnh. Theo đề nghị của Sở Nông nghiệp và Phát triển nông thôn tại Tờ trình số 3877/TTr-SNNPTNT ngày 23/8/2023; Ủy ban nhân dân tỉnh ban hành Kế hoạch sản xuất vụ Đông năm 2023 với các nội dung sau:
I. ĐÁNH GIÁ KẾT QUẢ SẢN XUẤT VỤ ĐÔNG NĂM 2022
1. Thuận lợi
- Các chính sách hỗ trợ phát triển sản xuất của Trung ương, của Tỉnh tiếp tục được triển khai thực hiện trên địa bàn tỉnh- Từ tỉnh đến địa phương đã xác định sản xuất vụ Đông là vụ sản xuất chính, có giá trị kinh tế cao với nhiều lợi thế do cơ cấu cây trồng đa dạng phong phú và điều kiện khí hậu phù hợp;
- Điều kiện thời tiết giữa và cuối vụ thuận lợi cho các cây trồng vụ Đông sinh trưởng phát triển cho năng suất và chất lượng cao. Thị trường tiêu thụ cây trồng vụ Đông thuận lợi, giá một số sản phẩm vụ Đông đều tăng cao có lợi cho người sản xuất.
2. Khó khăn
- Thời tiết diễn biến phức tạp trong tháng 9, tháng 10 còn xuất hiện mưa lớn diện rộng ảnh hưởng đến thu hoạch lúa mùa, khó khăn cho việc làm đất phục vụ sản xuất cây vụ Đông sớm, cây ưa ấm ngô, lạc;
- Vụ Đông năm 2022, tiếp tục bị ảnh hưởng bởi thiếu hụt lực lượng lao động, nhất là lao động trẻ do chuyển sang làm các Khu công nghiệp hoặc các lĩnh vực khác phi nông nghiệp có thu nhập cao hơn. Việc ứng dụng cơ giới hóa trong sản xuất vụ Đông còn hạn chế, doanh nghiệp bao tiêu sản phẩm trồng trọt vẫn thiếu, chưa có nhiều thị trường tiêu thụ sản phẩm hàng hóa vụ Đông.
3. Kết quả sản xuất
- Diện tích gieo trồng cây vụ Đông năm 2022 đạt 7.167 ha, năng suất hầu hết các cây trồng đều đạt định mức, cây trồng có giá trị cao được mở rộng diện tích; giá trị sản xuất vụ Đông năm 2022 ước đạt trên 1.400 tỷ đồng. Những cây trồng có giá trị cao được các địa phương đưa vào sản xuất như khoai tây, củ đậu đạt giá trị từ 160 - 200 triệu đồng/ha; rau cao cấp 110 - 150 triệu đồng/ha; hoa cây cảnh từ 300 - 500 triệu đồng/ha;
- Diện tích tích tụ ruộng đất để sản xuất rau màu, khoai tây, hoa đạt khoảng 450 ha; việc tích tụ ruộng đất đã tạo thuận lợi cho phát triển cơ giới hóa và ứng dụng khoa học công nghệ vào sản xuất.
II. KẾ HOẠCH SẢN XUẤT VỤ ĐÔNG NĂM 2023
1. Nhận định tình hình
1.1. Thuận lợi
- Các địa phương chuẩn bị sớm các điều kiện, giải pháp phát triển sản xuất vụ Đông như tăng trà lúa mùa sớm, tăng giống ngắn ngày... để bố trí thời vụ cây vụ Đông, nhất là vụ Đông sớm; tăng diện tích sản xuất an toàn, theo quy trình VietGAP, hữu cơ; tăng cường tích tụ ruộng đất sản xuất quy mô lớn;
- Các cơ chế, chính sách hỗ trợ tái cơ cấu ngành nông nghiệp của tỉnh tiếp tục là động lực khuyến khích, thúc đẩy sản xuất phát triển cây vụ đông;
- Phát triển sản xuất theo hướng hàng hóa tập trung, quy mô lớn, sản xuất theo chuỗi giá trị và nhu cầu thị trường đang được nhân rộng.
1.2. Khó khăn
- Thời tiết vụ Đông năm 2023 dự báo sẽ diễn biến phức tạp. Đầu vụ Đông thường xảy ra mưa úng làm chậm tiến độ gieo trồng cây vụ Đông;
- Sản xuất manh mún, nhỏ lẻ vẫn chiếm tỷ lệ cao, ảnh hưởng đến việc đầu tư, áp dụng cơ giới hóa, nhất là khâu sơ chế, bảo quản sản phẩm sau thu hoạch;
- Giá vật tư đầu vào cho sản xuất vẫn ở mức cao, chi phí sản xuất lớn; nhân lực lao động sản xuất nông nghiệp thiếu và yếu do tuổi cao;
- Hoạt động xúc tiến thương mại, quảng bá, tiêu thụ sản phẩm chưa đáp ứng được nhu cầu tiêu thụ sản phẩm; chưa xây dựng mạng lưới tiêu thụ nông sản rộng khắp, đa dạng loại hình và quy mô, khuyến khích các thành phần kinh tế tham gia.
2. Định hướng sản xuất
- Kết quả sản xuất vụ Đông năm 2023 hết sức quan trọng với việc ổn định an sinh xã hội, xây dựng Nông thôn mới, nâng cao đời sống nhân dân, góp phần tăng trưởng ngành Nông nghiệp trong năm 2023 giúp người nông dân ổn định sinh kế;
- Tập trung thu hoạch nhanh lúa Mùa sớm để có quỹ đất trồng cây vụ Đông ưa ấm. Tận dụng tối đa phế phụ phẩm trong trồng trọt để sản xuất phân bón hữu cơ, thay thế phân bón vô cơ theo tỷ lệ phù hợp nhằm sử dụng phân bón tiết kiệm, cân đối và hiệu quả, giảm chi phí sản xuất và gia tăng giá trị;
- Khuyến khích các hình thức tích tụ ruộng đất liên kết với doanh nghiệp, sản xuất thành vùng tập trung với quy mô lớn có hợp đồng liên kết sản xuất và bao tiêu sản phẩm theo chuỗi giá trị. Áp dụng cơ giới hóa đồng bộ nhằm giảm công lao động, kiểm soát tốt sinh vật gây hại góp phần tăng năng suất, chất lượng sản phẩm, nâng cao giá trị sản xuất;
- Mở rộng diện tích và phát triển một số cây màu vụ Đông có giá trị kinh tế cao, có lợi thế về thị trường để tăng thu nhập cho nông dân.
3. Muc tiêu
- Toàn tỉnh phấn đấu gieo trồng 7.685,8 ha, trong đó diện tích cây ngô 972,3 ha, rau màu 4.705,4 ha, cây hoa 254 ha...; giá trị sản xuất trên 1.000 tỷ đồng.
(Có phụ lục chi tiết kèm theo)
- Các huyện, thị xã, thành phố triển khai xây dựng tối thiểu 01 mô hình điển hình sản xuất trong vụ Đông năm 2023.
4. Các giải pháp sản xuất vụ Đông năm 2023
4.1. Bố trí quỹ đất để tổ chức sản xuất
- Tăng cơ cấu giống cây trồng chất lượng cao phải phù hợp với quỹ đất hiện có của từng địa phương, các vùng có tầng canh tác dày, giầu dinh dưỡng, chủ động tưới tiêu và cần xác định rõ quỹ đất này sẽ bố trí trồng cây vụ Đông ưa ấm;
- Bố trí quỹ đất dành cho nhân dân địa phương thuê, mượn sản xuất, được chủ động ngay từ cơ sở thôn, trên cơ sở rà soát các hộ gia đình không có nhu cầu trồng cây vụ Đông cho các hộ có nhu cầu sản xuất thuê, mượn để mở rộng diện tích sản xuất, hạn chế việc bỏ ruộng không canh tác.
4.2. Giải pháp về chỉ đạo
- Tăng cường lực lượng cán bộ kỹ thuật ngành Nông nghiệp và Phát triển nông thôn xuống cơ sở tuyên truyền, tập huấn và chỉ đạo sản xuất về cơ cấu giống, lịch thời vụ, quy trình canh tác và công tác bảo vệ thực vật. Chủ động xử lý và có kế hoạch ứng phó với các tình huống bất lợi trong sản xuất ở vụ Đông năm 2023 như hạn, rét đậm, rét hại; chuột hại cây trồng;
- Huy động sự tham gia của hệ thống chính trị từ tỉnh, huyện đến xã, phường, thị trấn để chỉ đạo và tổ chức sản xuất với phương châm bảo đảm an ninh lương thực, tăng cường tiêu thụ nông sản, nâng cao đời sống của nhân dân; đổi mới sản xuất để xây dựng thương hiệu nông sản, mở rộng các cây trông có lợi thế;
- Tăng cường công tác quản lý nhà nước về vật tư nông nghiệp: công tác thanh tra kiểm tra các cơ sở sản xuất, kinh doanh vật tư nông nghiệp. Phát hiện xử lý kịp thời có hiệu quả các đối tượng vi phạm; đảm bảo hàng hóa phục vụ sản xuất, lưu thông trên thị trường có chất lượng tốt, giá cả hợp lý phục vụ sản xuất; tăng cường công tác quản lý chất lượng nông sản.
4.3. Giải pháp về kỹ thuật
a. Đối với nhóm cây ưa ấm
- Cây ngô: Mở rộng diện tích ngô sinh khối, ngô thực phẩm, ngô ăn tươi: Ngô nếp (giống HN 88, giống HN 68, TBM18... ) ngô đường năng suất cao, chất lượng tốt; các giống ngô có sinh khối lớn, chất lượng cao để làm thức ăn chăn nuôi: giống ngô lai NK66, NK6654, giống có khả năng chịu hạn tốt, giống ngô Biosed06, C919; thời gian gieo hạt từ 20/9 - 25/9/2023, đặt bầu trước ngày 10/10/2023. Đối với ngô nếp, ngô đường, ngô rau có thời gian sinh trưởng ngắn, sử dụng bắp tươi; ngô làm thức ăn xanh cho chăn nuôi, thời vụ gieo trồng có thể kéo dài đến 20/10/2023; sử dụng các biện pháp kỹ thuật như làm bầu ngô, làm đất tối thiểu, tăng mật độ ngô 6-7 vạn cây/ha đối với đất màu, 5,7-6 vạn cây/ha đối với đất 2 lúa; bón phân sớm, đủ lượng và cân đối;
- Cây bí xanh, bí ngô, dưa chuột, ớt: Khuyến cáo nông dân và các địa phương nên sử dụng các giống lai F1 như: Bí xanh HN999, Dưa chuột Thái Lan Chiatai 336, Bí đỏ Gotal 999, Bí đỏ Gotal 998...); áp dụng kỹ thuật làm bầu (nhóm dưa, bí), ươm cây con (ớt...) và chăm sóc cây con. Đối với bầu bí, dưa chuột có thể áp dụng kỹ thuật trồng gối bằng cách rạch lúa đặt bầu trước khi thu hoạch lúa để tranh thủ thời vụ.
b. Đối với nhóm cây ưa lạnh
- Khoai tây: Thời vụ tập trung từ ngày 15/10 - 5/11/2023, trên chân đất trồng lúa nên trồng trong tháng 10; giống khoai tây sử dụng các giống Marabel, Solara, Atlantic, Diamant... được lựa chọn từ những ruộng giống có nguồn gốc rõ ràng, sạch bệnh và được bảo quản trong kho lạnh.
- Rau, đậu: Lựa chọn các giống chất lượng, chống chịu thời tiết tốt, vụ sớm chọn giống chịu nhiệt. Giống cải bắp như KK cross, Sakata No70 chịu nhiệt, Hoa sen 570, N075, NS cross; su hào như B40 chịu nhiệt; súp lơ như Sakata 1502, súp lơ xanh F1 Marathone, White Corona, Nông Hữu.
Thời vụ: Gieo trồng từ 15/9 - 31/12.
Quy hoạch và xây dựng các vùng sản xuất hàng hóa tập trung ổn định theo quy trình sản xuất rau an toàn, áp dụng các biện pháp tưới nước tiết kiệm, sử dụng màng phủ nông nghiệp trong trồng rau, dưa, bí, lạc..., tăng cường sử dụng phân hữu cơ, phân vi sinh... Tận dụng tốt điều kiện đất đai, nhân lực, thời vụ, mở rộng tối đa diện tích gieo trồng, chủ động trồng rải vụ, trồng các loại rau đậu có giá trị và thị trường tiêu thụ tốt;
- Hoa cây cảnh: Chú trọng mở rộng diện tích trồng các loại hoa phục vụ Tết tại một số vùng trọng điểm của thành phố Hạ Long, thị xã Đông Triều, thị xã Quảng Yên.... Sử dụng đa dạng những giống hoa có chất lượng: Hoa Lily, Hoa cúc, Đồng tiền, các loại Hoa lan, Hoa hồng...
Thời vụ: Trồng tập trung trong tháng 10, tốt nhất từ 05/10 - 20/10/2023 để thu hoạch phục vụ tết Nguyên Đán Giáp Thìn (2024).
- Phân bón: Khuyến cáo nông dân sử dụng các chế phẩm sinh học để xử lý rơm rạ sau thu hoạch lúa mùa (khuyến cáo nghiêm cấm đốt rơm rạ); tăng cường sử dụng phân bón hữu cơ giúp cây trồng phát triển khỏe chống chịu tốt với điều kiện bất thuận của ngoại cảnh. Bón đúng, bón đủ đối tượng cây trong và phù hợp với giai đoạn sinh trưởng và phát triển của cây trồng, kết hợp biện pháp tưới tiêu hợp lý;
- Ứng dụng chương trình quản lý dịch hại tổng hợp (IPM) cho rau màu để hạn chế tối đa việc dùng thuốc bảo vệ thực vật đảm bảo an toàn vệ sinh thực phẩm, không ô nhiễm môi trường tạo cho cây khoẻ, tăng sức đề kháng của cây; tăng cường áp dụng các tiến bộ khoa học kỹ thuật mới trong sản xuất, điều tiết nước hợp lý; thường xuyên theo dõi đồng ruộng, hạn chế sâu bệnh phát sinh tăng hiệu quả sản xuất;
- Hướng dẫn nông dân sử dụng các loại thuốc bảo vệ thực vật có nguồn gốc sinh học trong phòng trừ sâu bệnh, sử dụng thuốc bảo vệ thực vật theo nguyên tắc 4 đúng (đúng thuốc, đúng lúc, đúng liều lượng và nồng độ, đúng cách); thực hiện tốt công tác dự tính, dự báo sớm các đối tượng sâu, bệnh gây hại cây trồng; hướng dẫn nông dân các biện pháp phòng chống chuột ngay từ đầu vụ;
- Ứng dụng tưới tiết kiệm, làm tốt công tác khơi thông dòng chảy trên các trục chính và hệ thống kênh mương nội đồng thuận lợi cho công tác tiêu úng.
4.4. Tổ chức sản xuất
- Hình thành các tổ chức là chủ thể sản xuất, liên kết sản xuất và tiêu thụ sản phẩm;
- Tập trung đất đai để sản xuất cây vụ Đông trên quy mô lớn, trên cơ sở người dân địa phương thuê, mượn ruộng để sản xuất;
- Từng bước khôi phục và mở rộng diện tích một số cây vụ Đông có lợi thế về thị trường và thổ nhưỡng đất đai để nâng cao thu nhập cho nông dân.
4.5. Giải pháp về tuyên truyền
- Đẩy mạnh tuyên truyền nâng cao nhận thức để triển khai, thực hiện Kế hoạch sản xuất cây vụ Đông năm 2023; tuyên truyền nâng cao nhận thức của người sản xuất đối với việc đổi mới tổ chức sản xuất tạo giá trị bền vững xây dựng thương hiệu tạo sản phẩm đủ sức cạnh tranh trong thị trường;
- Xây dựng các mô hình tập trung sản xuất có hiệu quả kinh tế cao, bền vững; chuyển đổi cơ cấu cây trồng từ trồng lúa sang trồng, cây dược liệu, hoa, cây cảnh và cây hàng năm khác mang lại hiệu quả kinh tế cao cho người nông dân;
- Mở rộng hình thức liên kết sản xuất, cho thuê ruộng, áp dụng cơ giới hóa trong khâu làm đất, chăm sóc cây rau màu, giúp giải phóng sức lao động trong bối cảnh lao động nông nghiệp ngày càng thiếu và yêu; ứng dụng các tiến bộ khoa học kỹ thuật, biện pháp quản lý dịch hại tổng hợp trên cây trồng.
4.6. Cơ chế, chính sách phát triển sản xuất
- Áp dụng các cơ chế, chính sách hiện có để hỗ trợ xây dựng các mô hình sản xuất trồng trọt có hiệu quả kinh tế bền vững, hướng tới việc xây dựng chỉ dẫn địa lý, nhãn hiệu hàng hóa nông sản của tỉnh;
- Ngoài chính sách hỗ trợ của tỉnh, các huyện, thị xã, thành phố căn cứ vào yêu cầu và điều kiện cụ thể có chính sách hỗ trợ riêng tập trung cho hỗ trợ giống mới, hỗ trợ tổ chức diệt chuột, sử dụng phân bón hữu cơ, hữu cơ vi sinh, tiến bộ khoa học kỹ thuật sản xuất cây vụ Đông... để phát triển, bảo vệ sản xuất nông nghiệp của địa phương đảm bảo tính hiệu quả và bền vững;
- Tiếp tục triển khai chính sách hỗ trợ xây dựng và duy trì các mô hình ứng dụng tiến bộ kỹ thuật mới, ứng dụng công nghệ cao, cơ giới hóa, sản xuất theo hướng hàng hóa; các mô hình có hợp đồng bao tiêu sản phẩm cho các tổ chức cá nhân tham gia sản xuất khuyến khích phát triển cây vụ Đông.
III. TỔ CHỨC THỰC HIỆN
1. Ủy ban nhân dân huyện, thị xã, thành phố
Căn cứ Kế hoạch sản xuất cây vụ Đông năm 2023 của tỉnh, xây dựng hoặc điều chỉnh Kế hoạch sản xuất cây vụ Đông năm 2023 của địa phương; triển khai Kế hoạch sản xuất đến các cơ quan, đơn vị, Ủy ban nhân dân các xã, phường, thị trấn và các Hợp tác xã dịch vụ Nông nghiệp; phân công các phòng, ban, đoàn thể chính trị - xã hội xuống cơ sở chỉ đạo, kiểm tra việc thực hiện Kế hoạch; chỉ đạo Ủy ban nhân dân các xã, phường, thị trấn phối hợp với cơ quan chuyên môn của ngành nông nghiệp chỉ đạo thực hiện tốt Kế hoạch sản xuất cây vụ Đông năm 2023; chỉ đạo tốt công tác thủy lợi nội đồng, nhất là việc khơi thông dòng chảy trong mùa mưa, lũ;
- Quản lý tốt việc cung ứng giống cây trồng, phân bón vật tư nông nghiệp; tổ chức kết nối giữa doanh nghiệp và người sản xuất có sự tham gia của chính quyền cấp xã, Hợp tác xã dịch vụ nông nghiệp để khuyến khích các doanh nghiệp vào đầu tư sản xuất và bao tiêu sản phẩm cho nhân dân, giám sát việc thực hiện hợp đồng.
2. Sở Nông nghiệp và Phát triển nông thôn
- Theo dõi, hướng dẫn, kiểm tra, đánh giá kết quả sản xuất của các địa phương, tham mưu và đề xuất kịp thời với Ủy ban nhân dân tỉnh xử lý các vấn đề phát sinh trong quá trình tổ chức, thực hiện Kế hoạch; chỉ đạo các đơn vị chuyên môn trong ngành phối hợp với các địa phương chuẩn bị tốt mọi điều kiện phục vụ sản xuất cây vụ Đông năm 2023;
- Tăng cường cán bộ kỹ thuật xuống cơ sở, phối hợp với Ủy ban nhân dân huyện, thị xã, thành phố để chỉ đạo, tập huấn, hướng dẫn kỹ thuật, tuyên truyền, vận động nông dân thực hiện nghiêm chủ trương của tỉnh, huyện, thị xã, thành phố đã đề ra trong Kế hoạch, đảm bảo có hiệu quả;
- Chỉ đạo các đơn vị chuyên môn thuộc sở phối hợp chặt chẽ với các địa phương chủ động tổ chức thực hiện nghiêm Kế hoạch sản xuất cây vụ Đông của tỉnh; Trung tâm Khuyến nông xây dựng và khuyến cáo các mô hình khuyến nông, hướng dẫn tập huấn kỹ thuật cho nông dân tập trung vào những nội dung thiết thực, khuyến cáo các mô hình sản xuất tiên tiến, hiệu quả cao vào sản xuất; phối hợp với Trung tâm truyền thông tỉnh xây dựng băng hình khoa giáo, chú trọng tới các biện pháp kỹ thuật sản xuất luân canh, xen canh, gối vụ để tăng vụ để nông dân tiếp thu thực hiện. Chi cục Trồng trọt và Bảo vệ thực vật phối hợp chặt chẽ với các cơ quan truyền thông, các cấp các ngành tăng cường tuyên truyền chủ trương, giải pháp để thực hiện tốt Kế hoạch sản xuất cây vụ Đông của tỉnh; theo dõi chặt chẽ diễn biến của thời tiết mưa úng để có biện pháp phòng chống kịp thời, hiệu quả; phối hợp với các địa phương đề xuất các biện pháp khắc phục kịp thời thiệt hại ảnh hưởng đến sản xuất vụ Đông; phát hiện sớm, dự tính dự báo chính xác, tham mưu kịp thời và hướng dẫn nông dân phòng trừ dịch hại theo nguyên tắc phòng trừ dịch hại tổng hợp;
- Làm tốt công tác thanh tra, kiểm tra việc sản xuất, kinh doanh, buôn bán vật tư nông nghiệp; ngăn chặn và xử lý kịp thời các hoạt động kinh doanh hàng giả, hàng kém chất lượng, trái với các quy định của Nhà nước, tăng cường công tác quản lý thuốc diệt cỏ trên địa bàn tỉnh.
3. Các sở, ban, ngành liên quan
Căn cứ chức năng, nhiệm vụ, lĩnh vực quản lý phối hợp với Sở Nông nghiệp và Phát triển nông thôn, Ủy ban nhân dân các huyện, thị xã, thành phố triển khai thực hiện Kế hoạch; tuyên truyền vận động và tạo mọi điều kiện thuận lợi để sản xuất vụ Đông năm 2023 đạt kết quả.
4. Trung tâm Truyền thông tỉnh
Tăng cường thời lượng thông tin, phổ biến chủ trương sản xuất cây vụ Đông 2023; tuyên truyền sâu rộng tới nhân dân trong tỉnh để người dân nhận thức đầy đủ về giá trị của sản xuất cây vụ Đông; biện pháp kỹ thuật thâm canh, phòng trừ các đối tượng sinh vật gây hại; các mô hình sản xuất có hiệu quả cao trong sản xuất vụ Đông để nhân rộng.
5. Đề nghị Ủy ban Mặt trận Tổ quốc và các tổ chức chính trị - xã hội
Đề nghị Ủy ban Mặt trận Tổ quốc tỉnh, các tổ chức chính trị - xã hội tỉnh, phối hợp với Sở Nông nghiệp và Phát triển nông thôn, Ủy ban nhân dân huyện, thị xã, thành phố đẩy mạnh công tác tuyên truyền, vận động, hướng dẫn để hộ nông dân hiểu và nắm vững chủ trương sản xuất cây vụ Đông, thực hiện tốt các mục tiêu phát triển sản xuất nông nghiệp năm 2023 và những năm tiếp theo.
Ủy ban nhân dân tỉnh yêu cầu Sở Nông nghiệp và Phát triển nông thôn, các sở, ngành liên quan; Ủy ban nhân dân các huyện, thị xã, thành phố triển khai thực hiện./.
Nơi nhận: - Bộ Nông nghiệp và PTNT (b/c); - Q.CT, P4 UBND tỉnh (b/c); - UBMTTQ tỉnh, các tổ chức CT-XH tỉnh; - Các sở: NNPTNT, TC, CT, TNMT; - Trung tâm Truyền thông tỉnh; - UBND các huyện, tx, tp; - V0, V1, V2, NLN1,3; - Lưu: VP, NLN3 (03b, KH19).
TM. ỦY BAN NHÂN DÂN KT. CHỦ TỊCH PHÓ CHỦ TỊCH Vũ Văn Diện
PHỤ LỤC:
KẾ HOẠCH SẢN XUẤT CÂY VỤ ĐÔNG NĂM 2023 (Kèm theo Kế hoạch số: 233/KH-UBND ngày 12 tháng 9 năm 2023 của UBND tỉnh Quảng Ninh)
Chỉ tiêu
ĐVT
Tổng
Đông Triều
Uông Bí
Quảng Yên
Hạ Long
Cẩm Phả
Vân Đồn
Ba Chẽ
Tiên Yên
Bình Liêu
Đầm Hà
Hải Hà
Móng Cái
Cô Tô
Tổng diện tích gieo trồng
7.685,8
1369
175
1.960
523,8
57
85
198
550
386
905
790
672
15
Sản lượng lương thực
4.178,9
717,7
148
330,4
540,5
0
16,5
0
630
49,4
1.025
546,3
175
0
Trong đó
Cây ngô
DT
ha
972,3
130,5
40
59
163,8
5
140
16
250
118
50
NS
Tạ/ha
42,9
55
37
56
33
33
45
30,9
41
46.3
35
SL
Tấn
4.178,9
717,7
148
330,4
540,5
16,5
630
49,4
1.025
546,3
175
Khoai lang
DT
ha
970,2
55
20
23
43,2
15
20
95
130
180
99
290
NS
Tạ/ha
57
66,5
66,5
63,2
72
64
68
46,4
55
55,9
67,2
SL
Tấn
5.537
133
152,9
273
108
128
646
603,2
990
553,4
1.950
Khoai tây
DT
ha
302,4
208
3
10
8,4
5
48
20
NS
Tạ/ha
122
119
86
88
121
180
143.5
110
SL
Tấn
3.689
2.475,2
25.8
88
101,6
90
688,8
220
Đỗ tương
DT
ha
14,2
0,2
14
NS
Tạ/ha
15,9
14,1
16
SL
Tấn
22.682
0,2
22,4
Lạc
DT
ha
25.9
9,9
16
NS
Tạ/ha
18
19,9
17
SL
Tấn
46,9
19,7
27.2
Rau
DT
ha
4.705,4
425
110
1.815
285,4
37
60
198
237
240
410
573
300
15
NS
Tạ/ha
124,6
138
164
155,5
190
125
202,7
141
113,3
111
108
164,6
105
SL
Tấn
58.648
1518
29,7
703
750
4.013,4
3.341,7
2719,2
4.551
6.188,4
4.940
157,5
Hoa
DT
ha
254
229
25
Cây khác
DT
ha
441,4
321,5
2
28
12,9
65
12
lồng nhau (bên trong) hay không
const memberID = 0;
const isVIP = false;
const vbID = '27d4b37b40251f1cf76ba8bb5f59637c';
const unlockAllPhanTich = true;
// 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
// Typing effect state
let typingTimerId = null;
let typingCancelled = false;
// Thinking GIF state
let thinkingGifIntervalId = null;
let thinkingGifActive = false;
let thinkingGifCurrent = 0; // chỉ số GIF hiện tại 1..10
// Detect touch device - chỉ true khi thiết bị CHÍNH sử dụng touch (không có mouse chính xác)
const isTouchDevice = () => {
// Nếu USE_THREE_DOTS_BUTTON = true, luôn trả về true (hiện trên mọi thiết bị)
if (USE_THREE_DOTS_BUTTON === true) return true;
// Ưu tiên: Kiểm tra pointer: coarse (thiết bị chính sử dụng touch, không có mouse/trackpad)
if (window.matchMedia) {
// pointer: coarse = thiết bị chính sử dụng touch (mobile/tablet)
// pointer: fine = thiết bị có mouse/trackpad chính xác (desktop/laptop)
const hasCoarsePointer = window.matchMedia('(pointer: coarse)').matches;
if (hasCoarsePointer) return true;
}
// Fallback: Kiểm tra touch support (không chính xác lắm vì laptop cũng có thể có touch)
// Chỉ dùng khi không support matchMedia
if (!window.matchMedia) {
return (('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0));
}
return false;
};
const isTouch = isTouchDevice();
// State for dropdown menu on touch devices
let currentOpenDropdown = null;
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, vb_ngaybanhanh: '2023-09-12 00:00:00 AM' };
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/menu
if (((unlockAllPhanTich) || memberID === 4 || memberID === 3 || memberID === 2) && typeof attachPhanTichBadge === 'function') {
setTimeout(function() {
// $element chính là thẻ p, kiểm tra và attach badge/menu trực tiếp
const $parent = $element.closest('phan, chuong, muc, tieumuc, dieu, khoan, diem');
if ($parent.length > 0) {
const address = $parent.attr('address');
const parentType = getParentTypeName($parent.prop('tagName').toLowerCase());
const extraClass = (unlockAllPhanTich && memberID <= 0) ? ' upgrade-require' : '';
if (isTouch) {
// Touch device: Thêm nút 3 chấm (append vào body)
if ($('body').find('.menu-button-phan-tich[data-for="' + address + '"]').length === 0) {
const $menuButton = $('');
$('body').append($menuButton); // Append vào body
$parent.addClass('has-phan-tich-menu');
// Trigger update positions sau khi thêm
setTimeout(function() {
if (typeof window.updateMenuButtonPositions === 'function') {
window.updateMenuButtonPositions();
}
}, 10);
}
} else {
// Desktop: Append badge vào parent
if ($parent.find('.badge-phan-tich[data-for="' + address + '"]').length === 0) {
$element.attr('data-address', address);
const $badge = $('');
$parent.append($badge);
$parent.addClass('has-phan-tich-badge');
}
}
}
// Xử lý các p con (nếu có sub-p)
attachPhanTichBadge($element);
}, 3); // Đợi 3ms để CTTD render xong
}
},
complete: function() {
$element.removeClass('loading-content');
}
})
);
processQueue();
}
});
} catch(e) {
}
}
$(window).on('scroll resize', function () {
processVisibleParagraphs();
});
processVisibleParagraphs();
// Chức năng phân tích điều luật (mở theo lịch unlockAllPhanTich cho tất cả, nhưng khách click sẽ mở modal đăng nhập/mua gói)
if ((unlockAllPhanTich) || memberID === 4 || memberID === 3 || memberID === 2) {
// 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';
}
// Chuyển Telex -> Unicode cho giá trị (ví dụ: dd->đ, oo->ô, ow->ơ, aa->â, ee->ê, aw->ă, uw->ư)
function telexToUnicode(str) {
if (!str) return str;
// Giữ nguyên số
if (/^\d+$/.test(str)) return str;
let s = String(str);
// dd / ĐĐ
s = s.replace(/dd/g, 'đ');
s = s.replace(/DD/g, 'Đ');
// nguyên âm có mũ/dấu
s = s.replace(/aa/g, 'â').replace(/AA/g, 'Â');
s = s.replace(/ee/g, 'ê').replace(/EE/g, 'Ê');
s = s.replace(/oo/g, 'ô').replace(/OO/g, 'Ô');
s = s.replace(/ow/g, 'ơ').replace(/OW/g, 'Ơ');
s = s.replace(/uw/g, 'ư').replace(/UW/g, 'Ư');
s = s.replace(/aw/g, 'ă').replace(/AW/g, 'Ă');
return s;
}
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');
// Trên touch device: Thêm nút 3 chấm dọc (append vào body vì dùng fixed position)
if (isTouch) {
// Kiểm tra đã có nút 3 chấm chưa (trong body)
if ($('body').find('.menu-button-phan-tich[data-for="' + address + '"]').length === 0) {
const parentType = getParentTypeName($parent.prop('tagName').toLowerCase());
const extraClass = (unlockAllPhanTich && memberID <= 0) ? ' upgrade-require' : '';
// Tạo nút 3 chấm với dropdown và append vào body
const $menuButton = $('');
$('body').append($menuButton); // Append vào body, không vào parent
$parent.addClass('has-phan-tich-menu');
}
} else {
// Desktop: Giữ nguyên badge hover như cũ (append vào parent)
if ($parent.find('.badge-phan-tich[data-for="' + address + '"]').length === 0) {
$p.attr('data-address', address);
const parentType = getParentTypeName($parent.prop('tagName').toLowerCase());
const extraClass = (unlockAllPhanTich && memberID <= 0) ? ' upgrade-require' : '';
const $badge = $('');
$parent.append($badge);
$parent.addClass('has-phan-tich-badge');
}
}
}
});
}
// Helper: Escape HTML entities
function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return String(text).replace(/[&<>"']/g, function(m) { return map[m]; });
}
// Helper: Convert Markdown to HTML (đơn giản)
function markdownToHtml(markdown) {
if (!markdown) return '';
let html = markdown;
// Headers
html = html.replace(/^### (.*$)/gim, '$1 ');
html = html.replace(/^## (.*$)/gim, '$1 ');
html = html.replace(/^# (.*$)/gim, '$1 ');
// Bold
html = html.replace(/\*\*(.*?)\*\*/g, '$1 ');
// Italic
html = html.replace(/\*(.*?)\*/g, '$1 ');
// Blockquote
html = html.replace(/^> (.*$)/gim, '$1 ');
html = html.replace(/^> (.*$)/gim, '$1 ');
// Lists (unordered)
html = html.replace(/^\- (.*$)/gim, '$1 ');
html = html.replace(/(.*<\/li>)/s, '');
// Lists (ordered)
html = html.replace(/^\d+\. (.*$)/gim, ' $1 ');
// Line breaks và paragraphs
html = html.split('\n\n').map(para => {
para = para.trim();
if (para.startsWith('')) {
return para;
}
if (para) {
return '' + para.replace(/\n/g, ' ') + '
';
}
return '';
}).join('\n');
// Clean up multiple line breaks
html = html.replace(/\n{3,}/g, '\n\n');
return html;
}
// Panel fixed position
function closePhanTichPanel() {
const $panel = $('#phanTichPanel');
if ($panel.length) {
$panel.removeClass('show');
setTimeout(() => {
$panel.remove();
}, 300);
}
// Stop typing animation nếu đang chạy
stopThinkingTyping();
// 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
} else {
// KHÔNG có CTTD → SHOW lại rightdocinfo
const $rightdocinfo = $('#rightdocinfo');
if ($rightdocinfo.length > 0) {
$rightdocinfo.show();
}
}
// Reset state
isAnalyzing = false;
currentAnalyzingAddress = null;
currentAnalyzingElement = null;
currentAnalyzingBadge = null;
isPanelOpen = false; // Đánh dấu panel đã đóng
}
// Panel đã song song với rightdocinfo → không cần MutationObserver nữa
// 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();
if ($('#phanTichPanelBody').hasClass('thinking-mode')) {
updateThinkingGifHeight();
}
}
}, 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');
// Mobile: dùng bottom sheet → để CSS điều khiển, bỏ qua reposition bằng JS
if ($(window).width() <= 768) {
return;
}
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'
});
} else {
}
// Restore trạng thái hidden nếu cần
if (wasHidden) {
$reference.hide().css('visibility', '');
}
}
}
// Hiệu ứng typing giả lập đang phân tích trong panel
function stopThinkingTyping() {
typingCancelled = true;
if (typingTimerId) {
clearTimeout(typingTimerId);
typingTimerId = null;
}
// Dừng trình chiếu ảnh khi dừng typing
stopThinkingImages();
}
// Helper GIF: chọn chỉ số ảnh mới 1..10 khác với exclude
function randomGifIndex(exclude) {
let n = exclude;
while (n === exclude) {
n = Math.floor(Math.random() * 10) + 1;
}
return n;
}
// Helper GIF: preload rồi gán src cho img, gọi callback sau khi load xong (hoặc lỗi)
function setGifSrc($img, idx, cb) {
const url = '/assets/images/gif/researching-' + idx + '.gif';
const updateWrapHeight = function(nW, nH){
try {
const $wrap = $img.closest('#thinkingGifWrapper');
if ($wrap.length && nW && nH) {
const wrapW = $wrap.width();
const maxW = wrapW * 0.9; // khớp với CSS max-width:90%
const displayW = Math.min(nW, maxW);
const displayH = nH * (displayW / nW);
$wrap.css('height', displayH + 'px');
}
} catch(e) { /* ignore */ }
};
if ($img.attr('src') === url) {
// Ảnh trùng src -> vẫn cập nhật lại chiều cao wrapper theo kích thước hiển thị hiện tại
const el = $img[0];
if (el && el.naturalWidth && el.naturalHeight) {
updateWrapHeight(el.naturalWidth, el.naturalHeight);
}
if (cb) cb();
return;
}
const pre = new Image();
pre.onload = function() {
$img.attr('src', url);
updateWrapHeight(pre.naturalWidth, pre.naturalHeight);
if (cb) cb();
};
pre.onerror = function() {
$img.attr('src', url);
// Không lấy được kích thước tự nhiên -> để auto
const $wrap = $img.closest('#thinkingGifWrapper');
if ($wrap.length) { $wrap.css('height', 'auto'); }
if (cb) cb();
};
pre.src = url;
}
function updateThinkingGifHeight() {
const $wrap = $('#thinkingGifWrapper');
if ($wrap.length === 0) return;
const $show = $('#thinkingGifA.visible, #thinkingGifB.visible').first();
if ($show.length === 0) return;
const el = $show[0];
if (!el.naturalWidth || !el.naturalHeight) return;
const wrapW = $wrap.width();
const maxW = wrapW * 0.9;
const displayW = Math.min(el.naturalWidth, maxW);
const displayH = el.naturalHeight * (displayW / el.naturalWidth);
$wrap.css('height', displayH + 'px');
}
function startThinkingImages() {
// Nếu body/khung chưa sẵn sàng thì bỏ qua
const $wrap = $('#thinkingGifWrapper');
if ($wrap.length === 0) return;
// Clear trước nếu đang chạy
stopThinkingImages();
thinkingGifActive = true;
const $a = $('#thinkingGifA');
const $b = $('#thinkingGifB');
$a.removeClass('visible');
$b.removeClass('visible');
// Ảnh đầu tiên
thinkingGifCurrent = randomGifIndex(0);
let useA = true; // ảnh A hiển thị trước
setGifSrc($a, thinkingGifCurrent, function(){ $a.addClass('visible'); });
// Mỗi 3s đổi ảnh, crossfade 0.5s qua CSS
thinkingGifIntervalId = setInterval(function(){
if (!thinkingGifActive) return;
const nextIdx = randomGifIndex(thinkingGifCurrent);
const $show = useA ? $b : $a; // show ảnh còn lại
const $hide = useA ? $a : $b;
setGifSrc($show, nextIdx, function(){
// Bắt đầu chuyển ảnh: ẩn ảnh cũ, hiện ảnh mới
$hide.removeClass('visible');
setTimeout(function(){ $show.addClass('visible'); }, 10);
thinkingGifCurrent = nextIdx;
useA = !useA;
});
}, 5000);
}
function stopThinkingImages() {
thinkingGifActive = false;
if (thinkingGifIntervalId) {
clearInterval(thinkingGifIntervalId);
thinkingGifIntervalId = null;
}
}
// Giải quyết address: nếu không có '_' thì decrypt (ưu tiên API, fallback client), ngược lại trả về nguyên vẹn
function clientDecrypt(encrypted, key) {
try {
const bin = atob(encrypted);
let out = '';
for (let i = 0; i < bin.length; i++) {
const ch = bin.charCodeAt(i);
const k = key.charCodeAt(i % key.length);
out += String.fromCharCode(ch ^ k);
}
// Chuẩn hóa tương tự server
out = out.toLowerCase().replace(/[^a-z0-9_]/g, '');
return out || encrypted;
} catch (e) {
return encrypted;
}
}
function resolveAddress(address) {
return new Promise(function(resolve) {
if (!address) { resolve(''); return; }
const addr = String(address);
const lower = addr.toLowerCase();
if (lower === 'trichyeu' || lower === 'cancu' || addr.indexOf('_') !== -1) {
resolve(addr);
return;
}
const randomServer = Math.floor(Math.random() * 10) + 1;
$.ajax({
url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/ajax/decrypt.ndsh.address.php',
type: 'POST',
data: { address_encrypted: addr },
timeout: 10000,
success: function(resp) {
try {
// jQuery sẽ parse JSON theo header, nhưng vẫn fallback nếu là string
if (typeof resp === 'string') { resp = JSON.parse(resp); }
} catch(e) { /* ignore */ }
if (resp && resp.ok && resp.address) {
resolve(resp.address);
} else {
// Fallback client decrypt
resolve(clientDecrypt(addr, 'htpl_noi_dung_vb_address'));
}
},
error: function() {
// Fallback client decrypt
resolve(clientDecrypt(addr, 'htpl_noi_dung_vb_address'));
}
});
});
}
function startThinkingTyping(address) {
// Reset trước khi bắt đầu
stopThinkingTyping();
typingCancelled = false;
const $body = $('#phanTichPanelBody');
if ($body.length === 0) return;
// Đánh dấu chế độ thinking để căn giữa toàn bộ nội dung trong body
$body.addClass('thinking-mode');
// Khởi tạo container nếu chưa có
if ($('#thinkingContainer').length === 0) {
$body.html('\
\
\
\
');
}
$('#thinkingText').html('');
// Khởi động slideshow ảnh thinking
startThinkingImages();
// Chờ resolve address (decrypt nếu cần) rồi mới bắt đầu typing
resolveAddress(address).then(function(addrPlain) {
if (typingCancelled) return;
const displayNameLarge = getElementDisplayNameLargeFirst(addrPlain);
$('.processing-text').text('Đang xử lý phân tích ' + displayNameLarge.toLowerCase() + '...');
// Câu nói đa dạng cho từng bước
const variants = [
[
'Tôi đã nhận được yêu cầu phân tích {name}...',
'Cảm ơn bạn đã gửi yêu cầu phân tích {name}, tôi sẽ bắt đầu...',
'Bạn đã yêu cầu tôi phân tích {name}, hãy chờ tôi lập kế hoạch...',
'Yêu cầu phân tích {name} đã được ghi nhận, tôi đang chuẩn bị...'
],
[
'Tiếp theo, tôi sẽ đọc kỹ nội dung chi tiết của {name}...',
'Bây giờ tôi cần xem xét kỹ nội dung của {name}...',
'Đang mở và duyệt qua nội dung {name}...'
],
[
'Tôi đã đọc xong. Tôi sẽ kiểm tra xem {name} có bị sửa đổi, bổ sung, thay thế hoặc bãi bỏ bởi điều khoản nào không...',
'Tôi sẽ đối chiếu các văn bản để xem {name} có thay đổi hiệu lực nào không...',
'Tiếp tục kiểm tra trạng thái hiệu lực và các lần sửa đổi của {name}...'
],
[
'Tôi cũng cần xem {name} có được hướng dẫn bởi điều luật nào không...',
'Đang tìm các quy định hướng dẫn áp dụng liên quan đến {name}...',
'Kiểm tra các văn bản hướng dẫn có nhắc đến {name}...'
],
[
'Tôi sẽ kiểm tra {name} có viện dẫn/nhắc đến điều luật khác để tham chiếu hay không...',
'Đang rà soát các điều khoản được {name} đề cập đến...',
'Tìm các tham chiếu pháp lý xuất hiện trong {name}...'
],
[
'Tôi sẽ nghiên cứu về phạm vi điều chỉnh và đối tượng áp dụng'
],
[
'Bây giờ tôi cần tìm ví dụ minh họa cho nội dung điều này...'
],
[
'Tôi cũng cần bổ sung vài lưu ý thực tiễn trong bài phân tích của tôi...'
],
[
'Giờ tôi sẽ viết phần kết luận của bài phân tích...'
],
[
'Bây giờ tôi bắt đầu phân tích chi tiết {name}...',
'Bắt đầu tổng hợp và phân tích {name}...',
'Tiến hành phân tích nội dung {name}...'
]
];
const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];
const lines = variants.map(group => pick(group).replace(/\{name\}/g, displayNameLarge));
let lineIndex = 0;
let charIndex = 0;
const speedMin = 12; // ms
const speedMax = 25; // ms
const linePause = 2000; // ms chờ 2s giữa các câu
function typeNextChar() {
if (typingCancelled) return;
const line = lines[lineIndex];
if (charIndex < line.length) {
$('#thinkingText').append(line.charAt(charIndex));
charIndex++;
const delay = Math.floor(Math.random() * (speedMax - speedMin + 1)) + speedMin;
typingTimerId = setTimeout(typeNextChar, delay);
} else {
// Hoàn tất 1 câu
if (lineIndex < lines.length - 1) {
// Chờ 2s rồi chuyển sang câu tiếp theo, thay thế câu cũ (không append)
typingTimerId = setTimeout(function() {
if (typingCancelled) return;
$('#thinkingText').html('');
lineIndex++;
charIndex = 0;
typeNextChar();
}, linePause);
} else {
// Câu cuối cùng -> giữ nguyên, chỉ để caret nhấp nháy; không loop
return;
}
}
}
typeNextChar();
});
}
function openPhanTichPanel(address, vbID) {
// Kiểm tra nếu đang phân tích element khác
if (isAnalyzing && currentAnalyzingAddress && currentAnalyzingAddress !== address) {
// Giải mã địa chỉ hiện đang phân tích trước khi hiển thị trong modal
resolveAddress(currentAnalyzingAddress).then(function(addrPlain) {
const currentName = getElementDisplayNameLargeFirst(addrPlain);
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) {
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
// ẨN rightdocinfo để tiết kiệm không gian
if ($rightdocinfo.length > 0) {
$rightdocinfo.hide();
}
// XÓA highlight persistent của TẤT CẢ elements cũ trước
$('#tab_noi_dung_vb .highlight-border-persistent').removeClass('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;
// 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
// Đả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 debugHTML = (memberID === 3 || memberID === 4) ? `
Debug Mode
` : '';
const panelHTML = `
`;
// 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;
// Bắt đầu typing
stopThinkingTyping();
startThinkingTyping(address);
}, 10);
} else {
// Khởi tạo giao diện typing khi mở lại panel
$('#phanTichPanelBody').addClass('thinking-mode').html('');
// Update dimensions khi re-open
updatePanelDimensions();
$('#phanTichPanel').addClass('show');
isPanelOpen = true;
// Bắt đầu typing
stopThinkingTyping();
startThinkingTyping(address);
}
// 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');
// Show typing trong panel thay cho loading
$('#phanTichPanelBody').addClass('thinking-mode').html('');
stopThinkingTyping();
startThinkingTyping(address);
// Gọi API xóa cache trước
deletePhanTichCache(address, vbID, function(deleteSuccess) {
if (deleteSuccess) {
// 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 {
$('#phanTichPanelBody').html(`
Lỗi! Không thể xóa cache. Vui lòng thử lại.
`);
$btn.prop('disabled', false);
$icon.removeClass('fa-spin');
}
});
});
// Gọi API phân tích (dùng function helper)
callPhanTichAPI(address, vbID);
}
// Helper: Gọi API phân tích (tách riêng để dùng lại)
function callPhanTichAPI(address, vbID, callback, attempt) {
attempt = attempt || 1;
const randomServer = Math.floor(Math.random() * 10) + 1;
const debugMode = $('#debugModePhanTich').is(':checked') ? 1 : 0;
$.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,
debug: debugMode
}),
success: function(response) {
if (response && response.ok) {
// Thành công -> kết thúc thinking và reset trạng thái
stopThinkingTyping();
if (currentAnalyzingBadge) {
currentAnalyzingBadge.text('Phân tích').removeClass('analyzing');
currentAnalyzingBadge.data('analyzing', false);
}
isAnalyzing = false;
// Render kết quả phân tích với hiệu ứng xuất hiện dần từ trên xuống dưới
let html = '';
html += '';
html += '';
html += '
' + markdownToHtml(response.phan_tich) + '
';
// Khuyến cáo thay cho thống kê token
html += '
';
html += 'Những thông tin em vừa cung cấp chỉ mang tính chất tham khảo, không đại diện cho tư vấn chính thức của luật sư. Quý khách nên tìm đến sự tư vấn trực tiếp từ Luật sư hoặc đơn vị pháp lý có chuyên môn để được hỗ trợ cụ thể cho trường hợp của mình.';
html += '
';
html += '
';
$('#phanTichPanelBody').removeClass('thinking-mode').html(html);
applyFadeReveal();
} else {
// Không ok -> nếu là quá tải và chưa vượt số lần thử thì retry
const msg = response && response.error ? response.error : '';
if (isOverloadedMessage(msg) && attempt < 50 && isPanelOpen && isAnalyzing && currentAnalyzingAddress === address) {
const delay = Math.min(1200 + attempt * 100, 5000);
setTimeout(function() { callPhanTichAPI(address, vbID, callback, attempt + 1); }, delay);
return;
}
// Hết số lần thử hoặc không phải quá tải -> hiển thị lỗi
stopThinkingTyping();
if (currentAnalyzingBadge) {
currentAnalyzingBadge.text('Phân tích').removeClass('analyzing');
currentAnalyzingBadge.data('analyzing', false);
}
isAnalyzing = false;
if (isOverloadedMessage(msg)) {
$('#phanTichPanelBody').removeClass('thinking-mode').html(`
Hiện tại A.I đang bị quá tải , vui lòng thử lại sau ít phút!
Thử lại
`);
$(document).off('click.tryAgainPanel').on('click.tryAgainPanel', '#btnTryAgainPanel', function() {
openPhanTichPanel(address, vbID);
});
} else {
$('#phanTichPanelBody').removeClass('thinking-mode').html(`
Lỗi! ${escapeHtml(msg || 'Không thể phân tích điều luật.')}
Vui lòng thử lại sau.
`);
}
}
if (callback) callback();
},
error: function(xhr, status, error) {
// Nếu quá tải và chưa quá 50 lần -> retry, giữ hiệu ứng thinking và trạng thái analyzing
let errorMsg = error;
if (xhr.responseJSON && xhr.responseJSON.error) {
errorMsg = (xhr.responseJSON.error.message || xhr.responseJSON.error) || errorMsg;
} else if (xhr.responseText) {
errorMsg = xhr.responseText;
}
if ((xhr.status === 503 || isOverloadedMessage(errorMsg)) && attempt < 50 && isPanelOpen && isAnalyzing && currentAnalyzingAddress === address) {
const delay = Math.min(1200 + attempt * 100, 5000);
setTimeout(function() { callPhanTichAPI(address, vbID, callback, attempt + 1); }, delay);
return;
}
// Hết số lần thử hoặc lỗi khác -> hiển thị thông báo phù hợp
stopThinkingTyping();
if (currentAnalyzingBadge) {
currentAnalyzingBadge.text('Phân tích').removeClass('analyzing');
currentAnalyzingBadge.data('analyzing', false);
}
isAnalyzing = false;
if (xhr.status === 503 || isOverloadedMessage(errorMsg)) {
$('#phanTichPanelBody').removeClass('thinking-mode').html(`
Hiện tại A.I đang bị quá tải , vui lòng thử lại sau ít phút!
Thử lại
`);
$(document).off('click.tryAgainPanel').on('click.tryAgainPanel', '#btnTryAgainPanel', function() {
openPhanTichPanel(address, vbID);
});
} else {
$('#phanTichPanelBody').removeClass('thinking-mode').html(`
Lỗi! Không thể kết nối đến server phân tích.
Chi tiết: ${escapeHtml(errorMsg)}
`);
}
if (callback) callback();
}
});
}
// Helper: Xóa cache phân tích
function deletePhanTichCache(address, vbID, callback) {
const randomServer = Math.floor(Math.random() * 10) + 1;
$.ajax({
url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/delete.phan.tich.cache.php',
type: 'POST',
contentType: 'application/json',
timeout: 10000,
data: JSON.stringify({
address: address,
vb_id: vbID
}),
success: function(response) {
if (callback) callback(response.ok || false);
},
error: function(xhr, status, error) {
if (callback) callback(false);
}
});
}
// Helper: Lấy tên hiển thị của element từ address (có chuyển Telex -> Unicode ở phần giá trị)
function getElementDisplayName(address) {
if (!address) return 'nội dung';
const addrStr = String(address).toLowerCase();
// Các trường hợp đặc biệt không có cặp key_value
if (addrStr === 'trichyeu') return 'Trích yếu';
if (addrStr === 'cancu') return 'Căn cứ';
// Parse địa chỉ linh hoạt: hỗ trợ cả dạng thiếu cặp
const parts = addrStr.split('_');
const types = new Set(['phan', 'chuong', 'muc', 'tieumuc', 'dieu', 'khoan', 'diem']);
const displayParts = [];
for (let i = 0; i < parts.length; i++) {
const key = parts[i];
if (types.has(key)) {
const label = getParentTypeName(key);
const val = (i + 1 < parts.length) ? parts[i + 1] : '';
const valVN = telexToUnicode(val);
displayParts.push(label + (valVN ? ' ' + valVN : ''));
if (val) i++; // bỏ qua value nếu đã dùng
}
}
const title = displayParts.reverse().join(' ');
if (title) return title;
// Fallback: nếu không parse được, trả về address gốc
return address;
}
// Helper: Lấy tên hiển thị theo thứ tự lớn -> nhỏ (Điều > Khoản > Điểm), có chuyển Telex
function getElementDisplayNameLargeFirst(address) {
if (!address) return 'nội dung';
const addrStr = String(address).toLowerCase();
if (addrStr === 'trichyeu') return 'Trích yếu';
if (addrStr === 'cancu') return 'Căn cứ';
const parts = addrStr.split('_');
const types = new Set(['phan', 'chuong', 'muc', 'tieumuc', 'dieu', 'khoan', 'diem']);
const displayParts = [];
for (let i = 0; i < parts.length; i++) {
const key = parts[i];
if (types.has(key)) {
const label = getParentTypeName(key);
const val = (i + 1 < parts.length) ? parts[i + 1] : '';
const valVN = telexToUnicode(val);
displayParts.push(label + (valVN ? ' ' + valVN : ''));
if (val) i++;
}
}
const title = displayParts.join(' ');
return title || address;
}
// Hiệu ứng typing nhanh cho nội dung kết quả (preview text), sau đó thay bằng HTML đầy đủ
let fastTypingTimerId = null;
function stopFastTypingContent() {
if (fastTypingTimerId) {
clearTimeout(fastTypingTimerId);
fastTypingTimerId = null;
}
}
function stripHtmlToText(html) {
const tmp = document.createElement('div');
tmp.innerHTML = html;
const text = (tmp.textContent || tmp.innerText || '') || '';
return text.replace(/\u00A0/g, ' ');
}
function startFastTypingFinalContent(finalHtml) {
stopThinkingTyping();
stopFastTypingContent();
stopThinkingImages();
const $body = $('#phanTichPanelBody');
if ($body.length === 0) return;
$body.removeClass('thinking-mode');
const previewTextFull = stripHtmlToText(finalHtml).trim();
const maxChars = 800; // giới hạn để không quá lâu
const previewText = previewTextFull.slice(0, maxChars);
$body.html('');
let idx = 0;
const speedMin = 2;
const speedMax = 5;
function typeNext() {
if (idx < previewText.length) {
$('#fastTypingText').append(previewText.charAt(idx));
idx++;
const delay = Math.floor(Math.random() * (speedMax - speedMin + 1)) + speedMin;
fastTypingTimerId = setTimeout(typeNext, delay);
} else {
// Khi gõ xong preview → thay bằng HTML đầy đủ
$body.html(finalHtml);
}
}
typeNext();
}
// Áp dụng hiệu ứng xuất hiện dần từ trên xuống dưới
function applyFadeReveal() {
const $container = $('#phanTichPanelBody .fade-reveal-container');
if (!$container.length) return;
// Lấy các block cấp cao và các phần tử con trong nội dung phân tích
const $blocks = $().add($container.children())
.add($container.find('.phan-tich-content').children());
let delayMs = 0;
const stepMs = 60; // ms giữa các phần tử
$blocks.each(function() {
const $el = $(this);
// Bỏ qua các node text trống
if ($el.prop('nodeType') !== 1) return;
$el.addClass('fade-reveal').css('animation-delay', (delayMs/1000) + 's');
delayMs += stepMs;
});
}
// Nhận diện lỗi quá tải model (503/overloaded) - phạm vi toàn cục
function isOverloadedMessage(msg) {
if (!msg) return false;
const s = String(msg).toLowerCase();
return s.includes('overloaded') || s.includes('unavailable') || s.includes('503');
}
function openPhanTichModal(address, vbID) {
// Tạo modal nếu chưa có
if ($('#modalPhanTich').length === 0) {
const modalHTML = `
Đang phân tích...
Đang phân tích...
`;
$('body').append(modalHTML);
}
// Reset và hiển thị modal với loading
$('#modalPhanTichBody').html(`
Đang phân tích...
Đang phân tích...
`);
$('#modalPhanTich').modal('show');
// AJAX request với retry tối đa 50 lần khi quá tải
(function requestModal(attempt) {
attempt = attempt || 1;
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 && response.ok) {
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) + ' ';
html += '
';
html += '' + markdownToHtml(response.phan_tich) + '
';
html += '';
html += 'Những thông tin em vừa cung cấp chỉ mang tính chất tham khảo, không đại diện cho tư vấn chính thức của luật sư. Quý khách nên tìm đến sự tư vấn trực tiếp từ Luật sư hoặc đơn vị pháp lý có chuyên môn để được hỗ trợ cụ thể cho trường hợp của mình.';
html += '
';
$('#modalPhanTichBody').html(html);
} else {
const msg = response && response.error ? response.error : '';
if (isOverloadedMessage(msg) && attempt < 50) {
const delay = Math.min(1200 + attempt * 100, 5000);
setTimeout(function(){ requestModal(attempt + 1); }, delay);
return;
}
if (isOverloadedMessage(msg)) {
$('#modalPhanTichBody').html(`
Hiện tại A.I đang bị quá tải , vui lòng thử lại sau ít phút!
Thử lại
`);
$(document).off('click.tryAgainModal').on('click.tryAgainModal', '#btnTryAgainModal', function(){
openPhanTichModal(address, vbID);
});
} else {
$('#modalPhanTichBody').html(`
Lỗi! ${escapeHtml(msg || 'Không thể phân tích điều luật.')}
Vui lòng thử lại sau.
`);
}
}
},
error: function(xhr, status, error) {
let errorMsg = error;
if (xhr.responseJSON && xhr.responseJSON.error) {
errorMsg = (xhr.responseJSON.error.message || xhr.responseJSON.error) || errorMsg;
} else if (xhr.responseText) {
errorMsg = xhr.responseText;
}
if ((xhr.status === 503 || isOverloadedMessage(errorMsg)) && attempt < 50) {
const delay = Math.min(1200 + attempt * 100, 5000);
setTimeout(function(){ requestModal(attempt + 1); }, delay);
return;
}
if (xhr.status === 503 || isOverloadedMessage(errorMsg)) {
$('#modalPhanTichBody').html(`
Hiện tại A.I đang bị quá tải , vui lòng thử lại sau ít phút!
Thử lại
`);
$(document).off('click.tryAgainModal').on('click.tryAgainModal', '#btnTryAgainModal', function(){
openPhanTichModal(address, vbID);
});
} else {
$('#modalPhanTichBody').html(`
Lỗi! Không thể kết nối đến server phân tích.
Chi tiết: ${escapeHtml(errorMsg)}
`);
}
}
});
})(1);
}
// 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) {
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 + 8) + 'px',
left: (offset.left + $parent.outerWidth() - badgeWidth - scrollLeft - 4) + 'px' // -5px padding
});
$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;
// Dùng mousemove để track chính xác element nào đang được hover (hiển thị ngay lập tức)
$(document).on('mousemove', '#tab_noi_dung_vb', function(e) {
// Bỏ logic ẩn badge khi hover vào tnpl - bây giờ badge luôn hiển thị
// Badge "Phân tích" sẽ luôn hiện kể cả khi di chuột vào tnpl
// Tìm element gần nhất (phan, chuong, muc, tieumuc, 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;
}
// Element thay đổi → xử lý ngay lập tức (không debounce)
// 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 extraClass = (unlockAllPhanTich && memberID <= 0) ? ' upgrade-require' : '';
const $badge = $('');
$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;
});
// Event delegation cho hover ra khỏi #tab_noi_dung_vb
$(document).on('mouseleave', '#tab_noi_dung_vb', function(e) {
// Nếu di chuột sang menu button thì KHÔNG clear currentHoveredElement
if (e.relatedTarget && $(e.relatedTarget).closest('.menu-button-phan-tich').length > 0) {
return;
}
// 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'});
}
});
}
}, 3);
});
// 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');
// Nếu di chuột sang menu button của chính nó thì KHÔNG xử lý mouseleave
if (e.relatedTarget && $(e.relatedTarget).closest('.menu-button-phan-tich[data-for="' + parentAddress + '"]').length > 0) {
return;
}
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')) {
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);
}
}, 3); // 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')) {
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);
}
}, 3);
});
// 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(), 3);
}
});
// Event delegation cho click badge → mở panel
$(document).on('click', '.badge-phan-tich, .badge-phan-tich-container, .badge-phan-tich-fixed', function(e) {
const $badge = $(this);
// Nếu là khách (chưa đăng nhập) sau thời điểm mở khóa → mở modal đăng nhập/mua gói
if (typeof memberID !== 'undefined' && memberID !== 4 && !isVIP) {
e.preventDefault();
e.stopPropagation();
openModal(this, '/ajax/member/m-register/new/1');
return;
}
// Thành viên → mở panel phân tích
e.preventDefault();
e.stopPropagation();
// Nếu badge đang analyzing thì không cho click
if ($badge.hasClass('analyzing') || $badge.data('analyzing')) {
return;
}
// Lấy address từ data-for attribute
const address = $badge.attr('data-for');
if (address && vbID) {
openPhanTichPanel(address, vbID);
} else {
showWarningModal('Không tìm thấy địa chỉ điều luật hoặc ID văn bản!');
}
});
// Xử lý click vào CTTD/DCTD
$(document).on('click', 'cttd, dctk, dctd, .chuthichtudong', function(e) {
// Khách (non-VIP): mở modal đăng ký
if (typeof memberID !== 'undefined' && memberID !== 4 && !isVIP) {
e.preventDefault();
e.stopImmediatePropagation();
openModal(this, '/ajax/member/m-register/new/1');
return false;
}
// VIP: Đảm bảo các thuộc tính kích hoạt modal có sẵn
var $this = $(this);
if (!$this.attr('data-toggle')) {
$this.attr('data-toggle', 'modal');
$this.attr('data-target', '#ct_modal');
}
// Force mở modal #ct_modal an toàn (Logic từ fallback cũ)
var $ctModal = $('#ct_modal');
if ($ctModal.length > 0) {
if (typeof $ctModal.modal === 'function') {
$ctModal.modal('show');
} else if (window.jQuery && typeof window.jQuery('#ct_modal').modal === 'function') {
window.jQuery('#ct_modal').modal('show');
} else {
// Fallback load bootstrap if missing
console.warn('Bootstrap modal not loaded. Attempting to load local fallback...');
var loadBootstrap = function() {
$.getScript('/libs/jquery/bootstrap/dist/js/bootstrap.js', function() {
if (typeof $('#ct_modal').modal === 'function') {
$('#ct_modal').modal('show');
} else if (window.jQuery && typeof window.jQuery('#ct_modal').modal === 'function') {
window.jQuery('#ct_modal').modal('show');
}
});
};
if (typeof window.Tether === 'undefined') {
$.getScript('https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js', loadBootstrap);
} else {
loadBootstrap();
}
}
}
});
// Ẩn badge khi click vào CTTD
$(document).on('click', 'cttd.chuthichtudong span, dctk span, dctd span', function(e) {
// Ẩ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'});
}
});
});
// 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);
// Function để update vị trí nút 3 chấm (fixed position) - exposed globally
window.updateMenuButtonPositions = function() {
if (!isTouch) return; // Chỉ chạy trên touch device
$('.menu-button-phan-tich').each(function() {
const $menuButton = $(this);
const address = $menuButton.attr('data-for');
const $parent = $('[address="' + address + '"]').first();
if ($parent.length > 0) {
const parentOffset = $parent.offset();
const parentWidth = $parent.outerWidth();
const parentHeight = $parent.outerHeight();
const scrollTop = $(window).scrollTop();
const windowHeight = $(window).innerHeight();
const viewportTop = scrollTop;
const viewportBottom = scrollTop + windowHeight;
// Kiểm tra parent có trong viewport không
const parentTop = parentOffset.top;
const parentBottom = parentOffset.top + parentHeight;
const inViewport = (parentBottom > viewportTop && parentTop < viewportBottom);
if (inViewport) {
const scrollLeft = $(window).scrollLeft();
// Tính vị trí: góc phải của parent element
// Canh chỉnh top để tâm của nút 3 chấm (cao ~36px) ngang hàng với tâm của badge (cao ~21px, top 8px)
// Badge center: 8 + 10.5 = 18.5px
// Button center: Top + 18px
// => Top = 18.5 - 18 = 0.5px -> Lấy tròn 1px
const topOffset = 3;
topPosition = parentOffset.top - scrollTop + topOffset;
// Left = left của parent + width của parent - khoảng 30px (chiều rộng icon + padding)
// Để nút nằm bên trong parent, góc phải
// Trừ scrollLeft vì position: fixed tính theo viewport
const leftPosition = parentOffset.left + parentWidth - 2 - scrollLeft;
$menuButton.css({
top: topPosition + 'px',
left: leftPosition + 'px',
right: 'auto', // Reset right
display: 'block'
});
} else {
// Ẩn nếu parent không trong viewport
$menuButton.css({display: 'none'});
}
}
});
};
// Highlight parent khi hover/touch vào nút 3 chấm
$(document).on('mouseenter touchstart', '.menu-button-phan-tich', function() {
const address = $(this).attr('data-for');
const $parent = $('[address="' + address + '"]').first();
if ($parent.length) {
$parent.addClass('highlight-border');
$parent.data('hovering', true); // Mark as hovering
currentHoveredElement = $parent; // Update global tracker
// Attach badge nếu chưa có (logic tương tự như khi hover vào parent)
if ($parent.find('.badge-phan-tich-container[data-for="' + address + '"]').length === 0) {
const parentType = getParentTypeName($parent.prop('tagName').toLowerCase());
const extraClass = (unlockAllPhanTich && memberID <= 0) ? ' upgrade-require' : '';
const $badge = $('');
$parent.append($badge);
$parent.addClass('has-phan-tich-badge');
}
// Show badge tương ứng
if (typeof showPhanTichBadgeForParent === 'function') {
showPhanTichBadgeForParent($parent);
}
}
});
$(document).on('mouseleave touchend', '.menu-button-phan-tich', function(e) {
const address = $(this).attr('data-for');
const $parent = $('[address="' + address + '"]').first();
// Nếu di chuột sang parent thì không remove highlight
if (e.relatedTarget && $(e.relatedTarget).closest('[address="' + address + '"]').length > 0) {
return;
}
// Nếu di chuột ra ngoài hoàn toàn (không vào parent)
currentHoveredElement = null;
if ($parent.length) {
$parent.removeClass('highlight-border');
$parent.data('hovering', false);
// Hide badge
if (typeof hidePhanTichBadgeForParent === 'function') {
hidePhanTichBadgeForParent($parent);
}
}
});
// ===== Event handlers cho touch device =====
if (isTouch) {
// Update positions khi scroll hoặc resize
$(window).on('scroll resize', function() {
window.updateMenuButtonPositions();
});
// Initial update
setTimeout(window.updateMenuButtonPositions, 500);
// Xử lý click nút Phân tích (badge hoặc dropdown item)
$(document).on('click', '.badge-phan-tich, .dropdown-item-phan-tich[data-action="analyze"]', function(e) {
e.preventDefault();
e.stopPropagation();
if (typeof memberID !== 'undefined' && memberID !== 4 && !isVIP) {
openModal(this, '/ajax/member/m-register/new/1');
return;
}
const $btn = $(this);
let address = $btn.attr('data-for');
// Nếu click từ dropdown item, cần lấy address từ parent menu button
if (!address) {
const $menuBtn = $btn.closest('.menu-button-phan-tich');
address = $menuBtn.attr('data-for');
}
if (address) {
// Đóng dropdown menu nếu đang mở (trên mobile)
if (currentOpenDropdown) {
currentOpenDropdown.removeClass('show');
currentOpenDropdown = null;
}
openPhanTichPanel(address, vbID);
}
});
// Click vào nút 3 chấm -> mở panel phân tích luôn (không cần dropdown)
$(document).on('click', '.btn-three-dots', function(e) {
e.preventDefault();
e.stopPropagation();
const $button = $(this);
const $menuContainer = $button.closest('.menu-button-phan-tich');
const address = $menuContainer.attr('data-for');
// Kiểm tra nếu là khách (chưa đăng nhập)
if (unlockAllPhanTich && memberID <= 0) {
if (!$menuContainer.hasClass('upgrade-require')) {
$menuContainer.addClass('upgrade-require');
}
// Trigger event để modal.content.php bắt và mở modal đăng nhập
$menuContainer.trigger('click');
return;
}
// Thành viên -> mở panel phân tích trực tiếp
if (address && vbID) {
openPhanTichPanel(address, vbID);
} else {
showWarningModal('Không tìm thấy địa chỉ điều luật hoặc ID văn bản!');
}
});
// Update positions khi scroll hoặc resize
$(window).on('scroll resize', function() {
window.updateMenuButtonPositions();
});
}
}
});
Tra cứu thuật ngữ với từ hoặc cụm từ đã chọn?
×
Kế hoạch 233/KH-UBND về sản xuất vụ Đông năm 2023 do tỉnh Quảng Ninh ban hành