feat: implement dynamic training course tab system and modular PDF data migration scripts

This commit is contained in:
2026-07-27 17:00:43 +07:00
parent 54e420499f
commit 1a8726285c
98 changed files with 8041 additions and 3949 deletions
+121
View File
@@ -0,0 +1,121 @@
import pdfplumber
import json
import os
import re
files = [
"/home/x79/sisvietnamvn_01/sisvietnamvn_Trang chính thức hiện tại/DaoTao/2.-CHUONG-TRINH-CAN-THIEP-MACH-MAU-THAN-KINH-NANG-CAO-BO-SUNG-FINAL.pdf",
"/home/x79/sisvietnamvn_01/sisvietnamvn_Trang chính thức hiện tại/DaoTao/CHUONG-TRINH-CAN-THIEP-MACH-MAU-CAC-TANG-VA-MACH-MAU-NGOAI-BIEN-CO-BAN.pdf",
"/home/x79/sisvietnamvn_01/sisvietnamvn_Trang chính thức hiện tại/DaoTao/CHUONG-TRINH-CHUAN-BI-DUNG-CU-VA-CHAM-SOC-BENH-NHAN-TRONG-PHONG-CHUP-MACH.pdf",
"/home/x79/sisvietnamvn_01/sisvietnamvn_Trang chính thức hiện tại/DaoTao/CHUONG-TRINH-DAO-TAO-TIM-MACH-CAN-THIEP-1.pdf"
]
slugs = [
"can-thiep-mach-mau-than-kinh-nang-cao",
"can-thiep-mach-mau-cac-tang-va-ngoai-bien-co-ban",
"chuan-bi-dung-cu-va-cham-soc-benh-nhan-trong-phong-chup-mach",
"tim-mach-can-thiep-co-ban"
]
titles = [
"Can thiệp mạch máu thần kinh nâng cao",
"Can thiệp mạch máu các tạng và mạch máu ngoại biên cơ bản",
"Chuẩn bị dụng cụ và chăm sóc bệnh nhân trong phòng chụp mạch",
"Tim mạch can thiệp cơ bản"
]
def make_text_block(text):
return {
"type": "paragraph",
"data": {
"text": text.replace('\n', '<br>')
}
}
def make_header_block(text, level=3):
return {
"type": "header",
"data": {
"text": text,
"level": level
}
}
def make_tab_start(title):
return {
"type": "tabStart",
"data": {
"title": title
}
}
def make_tab_end():
return {
"type": "tabEnd",
"data": {}
}
os.makedirs('pdf_json_output', exist_ok=True)
for f, slug, title in zip(files, slugs, titles):
blocks = []
blocks.append(make_tab_start("Nội dung"))
with pdfplumber.open(f) as pdf:
for page in pdf.pages:
text = page.extract_text()
if not text:
continue
# Simple heuristic: split by double newlines or single newlines
paragraphs = text.split('\n')
current_p = []
for line in paragraphs:
line = line.strip()
if not line:
continue
# If it looks like a heading
if re.match(r'^(\d+)\.\s+(.*)$', line) or line.isupper():
if current_p:
blocks.append(make_text_block(' '.join(current_p)))
current_p = []
blocks.append(make_header_block(line, level=3))
else:
current_p.append(line)
if current_p:
blocks.append(make_text_block(' '.join(current_p)))
# Try to extract tables
tables = page.extract_tables()
for table in tables:
if not table: continue
# Convert table to HTML for raw block
html = "<table class='table table-bordered'><tbody>"
for row in table:
html += "<tr>"
for cell in row:
cell_text = cell.replace('\n', '<br>') if cell else ''
html += f"<td>{cell_text}</td>"
html += "</tr>"
html += "</tbody></table>"
blocks.append({
"type": "raw",
"data": {
"html": html
}
})
blocks.append(make_tab_end())
editor_data = {
"time": 1700000000000,
"blocks": blocks,
"version": "2.29.1"
}
with open(f"pdf_json_output/{slug}.json", 'w', encoding='utf-8') as out:
json.dump(editor_data, out, ensure_ascii=False)
print(f"Processed {title}")
print("All done!")