Files
zyt/app/scripts/render_prescription_list_density.py
T
2026-08-18 14:08:38 +08:00

181 lines
5.7 KiB
Python

"""Render deterministic prescription-list density acceptance screenshots."""
from __future__ import annotations
import os
from pathlib import Path
from types import SimpleNamespace
from typing import Any
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
from PySide6.QtGui import QFont, QFontDatabase
from PySide6.QtWidgets import QApplication
from doctor_workstation.ui.pages import prescription_library as library_module
from doctor_workstation.ui.pages import prescriptions as prescriptions_module
from doctor_workstation.ui.pages.prescription_library import PrescriptionLibraryPage
from doctor_workstation.ui.pages.prescriptions import PrescriptionsPage
from doctor_workstation.ui.theme import apply_theme
DENSITY_SIZES = ((1366, 768), (1710, 920))
def _run_immediately(
function: Any,
*args: Any,
on_success: Any = None,
on_error: Any = None,
on_finished: Any = None,
**kwargs: Any,
) -> object:
try:
result = function(*args, **kwargs)
except Exception as error:
if on_error is not None:
on_error(error)
else:
if on_success is not None:
on_success(result)
finally:
if on_finished is not None:
on_finished()
return object()
prescriptions_module.run_async = _run_immediately
library_module.run_async = _run_immediately
def _issued_row(index: int) -> dict[str, Any]:
return {
"id": 1000 + index,
"sn": f"CF-202608-{1000 + index}",
"prescription_type": "汤剂",
"is_system_auto": index % 2,
"patient_name": ("林晓岚", "周明远", "许安然")[index % 3],
"gender": 2 if index % 2 else 1,
"age": 29 + index,
"audit_status": index % 3,
"void_status": 0,
"has_prescription_order": index % 2,
"creator_id": 7,
"doctor_name": "陈医生",
"assistant_name": "赵医助",
"create_time": f"2026-08-{(index % 9) + 10:02d} 09:30:00",
"herbs": [{"name": "黄芪", "dosage": 15}],
}
def _library_row(index: int) -> dict[str, Any]:
return {
"id": 2000 + index,
"prescription_name": ("益气养阴方", "清热祛湿方", "滋阴调和方")[index % 3],
"formula_type": "主方" if index % 3 else "辅方",
"herbs": [
{"name": "黄芪", "dosage": 15},
{"name": "党参", "dosage": 12},
],
"efficacy": ("益气养阴", "清热祛湿", "滋阴补肾")[index % 3],
"is_public": index % 2,
"disable_edit": 0,
"creator_id": 7,
"creator_name": "陈医生",
"create_time": f"2026-08-{(index % 9) + 10:02d} 08:20:00",
}
class ScreenshotRepository:
def __init__(self) -> None:
self.issued_rows = [_issued_row(index) for index in range(15)]
self.library_rows = [_library_row(index) for index in range(15)]
def list_diagnosis_doctors(self) -> list[dict[str, Any]]:
return [{"id": 7, "name": "陈医生"}, {"id": 8, "name": "孙医生"}]
def list_prescriptions(self, **_filters: Any) -> dict[str, Any]:
return {"lists": self.issued_rows, "count": 44}
def list_prescription_templates(self, **_filters: Any) -> dict[str, Any]:
return {"lists": self.library_rows, "count": 41}
def _application() -> QApplication:
app = QApplication.instance() or QApplication([])
font_path = Path("C:/Windows/Fonts/msyh.ttc")
if font_path.is_file():
font_id = QFontDatabase.addApplicationFont(str(font_path))
families = QFontDatabase.applicationFontFamilies(font_id)
if families:
app.setFont(QFont(families[0], 9))
apply_theme(app)
return app
def _settle(app: QApplication) -> None:
for _ in range(6):
app.processEvents()
def _visible_rows(page: PrescriptionsPage | PrescriptionLibraryPage) -> int:
viewport = page.table.viewport()
return sum(
1
for row in range(page.table.rowCount())
if (
(item := page.table.item(row, 0)) is not None
and (rect := page.table.visualItemRect(item)).isValid()
and rect.top() >= 0
and rect.bottom() < viewport.height()
)
)
def _new_page(
kind: str,
repository: ScreenshotRepository,
) -> PrescriptionsPage | PrescriptionLibraryPage:
current_user = SimpleNamespace(id=7, name="陈医生", root=1, role_ids=[0])
if kind == "prescriptions":
page: PrescriptionsPage | PrescriptionLibraryPage = PrescriptionsPage(
repository, {"*"}, current_user
)
else:
page = PrescriptionLibraryPage(repository, {"*"}, current_user)
page.refresh()
return page
def render() -> list[Path]:
app = _application()
root = Path(__file__).resolve().parents[1]
output = root / "artifacts" / "prescription_list_density"
output.mkdir(parents=True, exist_ok=True)
repository = ScreenshotRepository()
paths: list[Path] = []
for kind in ("prescriptions", "prescription_library"):
for width, height in DENSITY_SIZES:
page = _new_page(kind, repository)
page.resize(width, height)
page.show()
_settle(app)
minimum_rows = 6 if height == 768 else 9
visible_rows = _visible_rows(page)
if visible_rows < minimum_rows:
raise RuntimeError(
f"{kind} at {width}x{height} exposes only {visible_rows} full rows"
)
path = output / f"{kind}_{width}x{height}.png"
if not page.grab().save(str(path), "PNG"):
raise RuntimeError(f"failed to save {path}")
paths.append(path)
page.close()
_settle(app)
return paths
if __name__ == "__main__":
for rendered in render():
print(rendered)