This commit is contained in:
Your Name
2026-08-11 17:39:41 +08:00
parent cfe4c82c90
commit 25467b9d91
350 changed files with 201115 additions and 132208 deletions
+132 -3
View File
@@ -15,7 +15,6 @@ from PySide6.QtWidgets import (
QFrame,
QLabel,
QPushButton,
QRadioButton,
QScrollArea,
QToolButton,
QWidget,
@@ -187,6 +186,63 @@ class VisualRepository:
{"name": "口干", "value": "口干"},
{"name": "口苦", "value": "口苦"},
],
"water_intake": [
{"name": "偏少", "value": "偏少"},
{"name": "正常", "value": "正常"},
],
"weight_change": [
{"name": "下降", "value": "下降"},
{"name": "上升", "value": "上升"},
],
"fatty_liver_degree": [
{"name": "轻度", "value": "轻度"},
{"name": "中度", "value": "中度"},
],
"diet_condition": [
{"name": "纳差", "value": "纳差"},
{"name": "多食易饥", "value": "多食易饥"},
],
"body_feeling": [
{"name": "乏力", "value": "乏力"},
{"name": "肢体麻木", "value": "肢体麻木"},
],
"sleep_condition": [
{"name": "入睡困难", "value": "入睡困难"},
{"name": "多梦", "value": "多梦"},
{"name": "易醒", "value": "易醒"},
],
"eye_condition": [
{"name": "视物模糊", "value": "视物模糊"},
{"name": "眼干", "value": "眼干"},
],
"head_feeling": [
{"name": "头痛", "value": "头痛"},
{"name": "头晕", "value": "头晕"},
],
"sweat_condition": [
{"name": "自汗", "value": "自汗"},
{"name": "盗汗", "value": "盗汗"},
],
"skin_condition": [
{"name": "皮肤瘙痒", "value": "皮肤瘙痒"},
{"name": "皮肤干燥", "value": "皮肤干燥"},
],
"urine_condition": [
{"name": "尿频", "value": "尿频"},
{"name": "夜尿多", "value": "夜尿多"},
],
"stool_condition": [
{"name": "便秘", "value": "便秘"},
{"name": "便溏", "value": "便溏"},
],
"kidney_condition": [
{"name": "腰酸", "value": "腰酸"},
{"name": "腰痛", "value": "腰痛"},
],
"past_history": [
{"name": "高血压", "value": "高血压"},
{"name": "冠心病", "value": "冠心病"},
],
}
return dictionaries.get(dictionary_type, [])
@@ -661,7 +717,8 @@ def test_semantic_form_controls_keep_desktop_grid_and_canonical_diagnosis_type(
)
assert isinstance(dialog.edit_fields["gender"], DiagnosisChoiceButtons)
assert len(dialog.edit_fields["gender"].findChildren(QRadioButton)) == 2
assert len(dialog.edit_fields["gender"]._buttons) == 2
assert all(button.isCheckable() for button in dialog.edit_fields["gender"]._buttons)
assert isinstance(dialog.edit_fields["local_hospital_diagnosis"], DiagnosisChoiceButtons)
assert isinstance(dialog.edit_fields["age"], DiagnosisNumberEdit)
assert isinstance(dialog.edit_fields["height"], DiagnosisNumberEdit)
@@ -677,8 +734,9 @@ def test_semantic_form_controls_keep_desktop_grid_and_canonical_diagnosis_type(
]
assert diagnosis_type.toPlainText() == "follow_up"
assert "diagnosis_type" in repository.dictionary_calls
# 1024×60% drawer keeps a two-column grid; only phone-narrow widths stack.
assert dialog._form_narrow is False
assert any(len(fields) >= 3 for _layout, fields, _remainder in dialog._form_rows)
assert any(len(fields) >= 2 for _layout, fields, _remainder in dialog._form_rows)
_select_tab(dialog, "notes")
assert not dialog.save_button.isVisibleTo(dialog)
@@ -690,6 +748,77 @@ def test_semantic_form_controls_keep_desktop_grid_and_canonical_diagnosis_type(
dialog.close()
def test_hpi_choice_chips_are_visible_after_dictionary_load(
application: QApplication,
) -> None:
"""Regression: wrapped choice chips must not clip to blank white space."""
dialog = _open_dialog(application, (1024, 640), mode="edit")
diet = dialog.edit_fields["diet_condition"]
sleep = dialog.edit_fields["sleep_condition"]
assert isinstance(diet, DiagnosisChoiceButtons)
assert isinstance(sleep, DiagnosisChoiceButtons)
assert len(diet._buttons) >= 2
assert diet.height() >= 32
assert diet.minimumHeight() >= diet.heightForWidth(max(160, diet.width()))
visible_chips = [button for button in diet._buttons if button.isVisibleTo(dialog)]
assert visible_chips
assert all(button.height() >= 24 for button in visible_chips)
# Chips must sit inside the choice host, not below a clipped viewport.
host_bottom = diet.mapTo(dialog.drawer_panel, diet.rect().bottomLeft()).y()
chip_bottom = visible_chips[0].mapTo(dialog.drawer_panel, visible_chips[0].rect().bottomLeft()).y()
assert chip_bottom <= host_bottom + 2
dialog.close()
application.processEvents()
def test_choice_chips_keep_visible_checked_style_when_readonly(
application: QApplication,
) -> None:
"""Selected chips must stay cyan even when the form is view-only locked."""
dialog = _open_dialog(application, (1024, 640), mode="edit")
diet = dialog.edit_fields["diet_condition"]
assert isinstance(diet, DiagnosisChoiceButtons)
diet.setPlainText("纳差")
selected = next(button for button in diet._buttons if button.isChecked())
application.processEvents()
# Sample the pad (not glyph center) so white text does not hide the fill.
enabled_color = selected.grab().toImage().pixelColor(6, selected.height() // 2)
assert enabled_color.name().lower() == "#cffafe"
diet.setReadOnly(True)
application.processEvents()
disabled_color = selected.grab().toImage().pixelColor(6, selected.height() // 2)
assert selected.isChecked()
assert selected.isEnabled()
assert diet.isReadOnly()
assert disabled_color.name().lower() == "#cffafe"
dialog.close()
application.processEvents()
def test_view_only_drawer_shows_selected_choice_chips(
application: QApplication,
) -> None:
"""Admin openViewOnly keeps the 病历 form with selected chips visible."""
dialog = _open_dialog(application, (1024, 640), mode="viewOnly")
assert dialog.view_stack.currentWidget() is dialog.drawer_overlay
assert dialog._view_only is True
assert not dialog._editable
diet = dialog.edit_fields["diet_condition"]
assert isinstance(diet, DiagnosisChoiceButtons)
diet.setPlainText("纳差")
selected = next(button for button in diet._buttons if button.isChecked())
application.processEvents()
color = selected.grab().toImage().pixelColor(6, selected.height() // 2)
assert color.name().lower() == "#cffafe"
assert diet.isReadOnly()
assert not dialog.save_button.isVisibleTo(dialog)
dialog.close()
application.processEvents()
def test_view_only_uses_ordinary_detail_and_standalone_uses_readonly_detail(
application: QApplication,
) -> None: