This commit is contained in:
Your Name
2026-08-12 18:09:57 +08:00
parent a1092c02c3
commit b2eb18c75f
391 changed files with 1666 additions and 638 deletions
@@ -76,6 +76,7 @@ _ORDER_DETAIL_PERMISSION = "tcm.prescriptionOrder/detail"
_ORDER_LOGS_PERMISSION = "tcm.prescriptionOrder/logs"
_DAILY_PERMISSION = "tcm.diagnosis/dailyRecord"
_PRESCRIPTION_PERMISSION = "tcm.diagnosis/chufang"
_PRESCRIPTION_EDIT_PERMISSION = "cf.prescription/edit"
_OFFSET_PERMISSION = "tcm.diagnosis/setRevisitSlotStartOffset"
_VIDEO_PERMISSION = "tcm.diagnosis/huifang"
_CHAT_PERMISSION = "tcm.diagnosis/chat"
@@ -798,6 +799,9 @@ class DiagnosisDialog(QDialog):
self._can_prescribe = has_permission(
self.permissions, _PRESCRIPTION_PERMISSION, default=False
) and callable(getattr(self.repository, "create_prescription", None))
self._can_edit_prescription = has_permission(
self.permissions, _PRESCRIPTION_EDIT_PERMISSION, default=False
) and callable(getattr(self.repository, "update_prescription", None))
self._can_offset = has_permission(
self.permissions, _OFFSET_PERMISSION, default=False
) and callable(getattr(self.repository, "set_revisit_slot_start_offset", None))
@@ -826,6 +830,8 @@ class DiagnosisDialog(QDialog):
self._daily_mutation_generation = 0
self._notes_mutation_generation = 0
self._media_generation = 0
self._prescription_detail_generation = 0
self._prescription_detail_target = 0
self._offset_generation = 0
self._tab_generations: dict[str, int] = {key: 0 for key, _label, _codes in _TAB_DEFINITIONS}
self._loaded_tabs: set[str] = set()
@@ -1631,6 +1637,9 @@ class DiagnosisDialog(QDialog):
self._can_prescribe = has_permission(
self.permissions, _PRESCRIPTION_PERMISSION, default=False
) and callable(getattr(self.repository, "create_prescription", None))
self._can_edit_prescription = has_permission(
self.permissions, _PRESCRIPTION_EDIT_PERMISSION, default=False
) and callable(getattr(self.repository, "update_prescription", None))
self._can_offset = has_permission(
self.permissions, _OFFSET_PERMISSION, default=False
) and callable(getattr(self.repository, "set_revisit_slot_start_offset", None))
@@ -1895,6 +1904,7 @@ class DiagnosisDialog(QDialog):
self._daily_mutation_generation += 1
self._notes_mutation_generation += 1
self._media_generation += 1
self._prescription_detail_generation += 1
self._offset_generation += 1
for key in self._tab_generations:
self._tab_generations[key] += 1
@@ -2176,6 +2186,7 @@ class DiagnosisDialog(QDialog):
self._daily_mutation_generation += 1
self._notes_mutation_generation += 1
self._media_generation += 1
self._prescription_detail_generation += 1
self._offset_generation += 1
for key in self._tab_generations:
self._tab_generations[key] += 1
@@ -3012,7 +3023,9 @@ class DiagnosisDialog(QDialog):
diagnosis_id=diagnosis_id, appointment_id=appointment_id
),
"tongue": first_value(diagnosis, "tongue", "tongue_coating"),
"tongue_image": first_value(diagnosis, "tongue_image"),
"pulse": first_value(diagnosis, "pulse"),
"pulse_condition": first_value(diagnosis, "pulse_condition"),
"clinical_diagnosis": build_prescription_clinical_diagnosis(diagnosis, case_record),
"doctor_name": first_value(
appointment, "doctor_name", default=first_value(diagnosis, "doctor_name")
@@ -3025,6 +3038,7 @@ class DiagnosisDialog(QDialog):
current_user=getattr(self.parentWidget(), "current_user", None),
parent=self,
)
dialog.diagnosis_requested.connect(self._open_current_diagnosis_detail)
dialog.setObjectName("DiagnosisPrescriptionEditor")
dialog.setStyleSheet(DIAGNOSIS_QSS)
if dialog.exec() != QDialog.DialogCode.Accepted:
@@ -3343,13 +3357,106 @@ class DiagnosisDialog(QDialog):
table.set_matrix(matrix)
self._semanticize(table, 5)
for row_index, row in enumerate(rows):
actions = QWidget()
actions_layout = QHBoxLayout(actions)
actions_layout.setContentsMargins(0, 0, 0, 0)
actions_layout.setSpacing(6)
button = self._action_button("查看", "打开真实处方详情")
button.clicked.connect(
lambda _checked=False, source=row: self._view_prescription(source)
)
table.setCellWidget(row_index, 6, button)
actions_layout.addWidget(button)
approved = _int(first_value(row, "audit_status", "status", default=-1), -1) == 1
voided = _truthy(first_value(row, "void_status", "is_void", default=False))
can_edit = (
self._editable
and self._can_edit_prescription
and (not approved or voided)
)
if can_edit:
edit_button = self._action_button("编辑", "使用完整处方表单编辑")
edit_button.clicked.connect(
lambda _checked=False, source=row: self._edit_prescription(source)
)
actions_layout.addWidget(edit_button)
actions_layout.addStretch(1)
table.setCellWidget(row_index, 6, actions)
def _view_prescription(self, prescription: Any) -> None:
prescription_id = _int(first_value(prescription, "id", "prescription_id", default=0), 0)
method = getattr(self.repository, "get_prescription", None)
if prescription_id <= 0 or not callable(method):
self._show_message("无法加载完整处方详情。", "warning")
return
self._prescription_detail_generation += 1
generation = self._prescription_detail_generation
self._prescription_detail_target = prescription_id
self._show_message("正在加载完整处方详情…", "info")
run_async(
lambda: method(prescription_id),
on_success=lambda detail: self._prescription_detail_loaded(
detail, prescription_id, generation, edit=False
),
on_error=lambda error: self._prescription_detail_error(
error, prescription_id, generation
),
)
def _edit_prescription(self, prescription: Any) -> None:
if (
not self._editable
or not self._can_edit_prescription
):
self._show_message("当前账号无处方编辑权限或接口不可用。", "warning")
return
prescription_id = _int(first_value(prescription, "id", "prescription_id", default=0), 0)
if prescription_id <= 0:
self._show_message("处方编号不完整,无法编辑。", "warning")
return
approved = _int(first_value(prescription, "audit_status", "status", default=-1), -1) == 1
voided = _truthy(first_value(prescription, "void_status", "is_void", default=False))
if approved and not voided:
self._show_message("审核通过且未作废的处方只能查看。", "warning")
return
method = getattr(self.repository, "get_prescription", None)
if not callable(method):
self._show_message("无法加载完整处方详情。", "warning")
return
self._prescription_detail_generation += 1
generation = self._prescription_detail_generation
self._prescription_detail_target = prescription_id
self._show_message("正在准备编辑处方…", "info")
run_async(
lambda: method(prescription_id),
on_success=lambda detail: self._prescription_detail_loaded(
detail, prescription_id, generation, edit=True
),
on_error=lambda error: self._prescription_detail_error(
error, prescription_id, generation
),
)
def _prescription_detail_loaded(
self,
prescription: Any,
prescription_id: int,
generation: int,
*,
edit: bool,
) -> None:
if (
generation != self._prescription_detail_generation
or prescription_id != self._prescription_detail_target
):
return
actual_id = _int(first_value(prescription, "id", "prescription_id", default=0), 0)
if actual_id != prescription_id:
self._show_message("服务端处方与当前行不一致,已停止打开。", "danger")
return
self._clear_message()
if edit:
self._open_prescription_edit_dialog(prescription, prescription_id)
return
from .prescription import PrescriptionDetailDialog
dialog = PrescriptionDetailDialog(
@@ -3360,6 +3467,55 @@ class DiagnosisDialog(QDialog):
)
dialog.exec()
def _prescription_detail_error(
self, error: Exception, prescription_id: int, generation: int
) -> None:
if (
generation == self._prescription_detail_generation
and prescription_id == self._prescription_detail_target
):
self._show_message(friendly_error(error), "danger")
def _open_prescription_edit_dialog(self, prescription: Any, prescription_id: int) -> None:
from .prescription import PrescriptionEditorDialog
dialog = PrescriptionEditorDialog(
self.repository,
prescription,
mode="edit",
current_user=getattr(self.parentWidget(), "current_user", None),
parent=self,
)
dialog.diagnosis_requested.connect(self._open_current_diagnosis_detail)
dialog.setObjectName("DiagnosisPrescriptionEditor")
dialog.setStyleSheet(DIAGNOSIS_QSS)
if dialog.exec() != QDialog.DialogCode.Accepted:
return
payload = dialog.payload()
self._run_media_mutation(
lambda: invoke(
self.repository,
"update_prescription",
prescription=prescription_id,
changes=payload,
),
"处方已保存并重新进入待审核。",
"prescription",
)
def _open_current_diagnosis_detail(self, diagnosis_id: int) -> None:
if diagnosis_id <= 0 or diagnosis_id != self._diagnosis_id or not self._detail:
self._show_message("当前处方关联的诊单详情不可用。", "warning")
return
from .prescription import DiagnosisDetailDialog
DiagnosisDetailDialog(
self._detail,
self,
repository=self.repository,
permissions=self.permissions,
).exec()
def _stop_inline_recordings(self) -> None:
for cell in list(getattr(self, "_inline_recording_cells", [])):
with suppress(RuntimeError):