更新
This commit is contained in:
@@ -228,19 +228,18 @@ def _status_value(row: Any) -> int:
|
||||
return _as_int(first_value(row, "status", default=0))
|
||||
|
||||
|
||||
def prescription_action_label(row: Any) -> str:
|
||||
audit = _as_int(first_value(row, "prescription_audit_status", "audit_status"), -1)
|
||||
voided = _as_int(first_value(row, "prescription_void_status", "void_status"), 0)
|
||||
explicit = first_value(row, "has_prescription", default=None)
|
||||
has_prescription = (
|
||||
_as_bool(explicit)
|
||||
if explicit is not None
|
||||
else _as_int(first_value(row, "prescription_id", default=0), 0) > 0
|
||||
or audit in {0, 1, 2}
|
||||
)
|
||||
if not has_prescription:
|
||||
return "开方"
|
||||
return "查看" if audit == 1 and voided != 1 else "编辑处方"
|
||||
def prescription_action_label(row: Any) -> str:
|
||||
audit = _as_int(first_value(row, "prescription_audit_status", "audit_status"), -1)
|
||||
voided = _as_int(first_value(row, "prescription_void_status", "void_status"), 0)
|
||||
explicit = first_value(row, "has_prescription", default=None)
|
||||
has_prescription = (
|
||||
_as_bool(explicit)
|
||||
if explicit is not None
|
||||
else _as_int(first_value(row, "prescription_id", default=0), 0) > 0 or audit in {0, 1, 2}
|
||||
)
|
||||
if not has_prescription:
|
||||
return "开方"
|
||||
return "查看" if audit == 1 and voided != 1 else "编辑处方"
|
||||
|
||||
|
||||
def _patient_cell(_value: Any, row: Any, *, can_plain: bool) -> str:
|
||||
@@ -270,9 +269,8 @@ def _patient_cell(_value: Any, row: Any, *, can_plain: bool) -> str:
|
||||
)
|
||||
if part and part != "—"
|
||||
)
|
||||
return (
|
||||
f"{display_text(first_value(row, 'patient_name'), '—')}\n{phone}"
|
||||
+ (f"\n{extras}" if extras else "")
|
||||
return f"{display_text(first_value(row, 'patient_name'), '—')}\n{phone}" + (
|
||||
f"\n{extras}" if extras else ""
|
||||
)
|
||||
|
||||
|
||||
@@ -284,7 +282,9 @@ def _datetime_cell(_value: Any, row: Any) -> str:
|
||||
|
||||
|
||||
def _confirmed_cell(_value: Any, row: Any) -> str:
|
||||
return "已确认" if _as_bool(first_value(row, "diagnosis_confirmed", default=False)) else "未确认"
|
||||
return (
|
||||
"已确认" if _as_bool(first_value(row, "diagnosis_confirmed", default=False)) else "未确认"
|
||||
)
|
||||
|
||||
|
||||
def _prescription_cell(_value: Any, row: Any) -> str:
|
||||
@@ -296,7 +296,9 @@ def _prescription_cell(_value: Any, row: Any) -> str:
|
||||
|
||||
|
||||
def _status_cell(_value: Any, row: Any) -> str:
|
||||
return display_text(first_value(row, "status_desc"), str(first_value(row, "status", default="—")))
|
||||
return display_text(
|
||||
first_value(row, "status_desc"), str(first_value(row, "status", default="—"))
|
||||
)
|
||||
|
||||
|
||||
def _offset_date(preset: str) -> date | None:
|
||||
@@ -374,8 +376,6 @@ class AppointmentsPage(QWidget):
|
||||
)
|
||||
self._native_video_capable = _supports_native_video(repository)
|
||||
self._is_admin = _is_admin_user(current_user)
|
||||
self.diagnosis_dialog = DiagnosisDialog(repository, self, permissions=permissions)
|
||||
self.diagnosis_dialog.saved.connect(lambda: self.refresh(silent=True))
|
||||
|
||||
root = QVBoxLayout(self)
|
||||
root.setContentsMargins(24, 20, 24, 24)
|
||||
@@ -396,6 +396,14 @@ class AppointmentsPage(QWidget):
|
||||
self.poll_timer.setInterval(LIST_POLL_MS)
|
||||
self.poll_timer.timeout.connect(lambda: self.refresh(silent=True))
|
||||
|
||||
def _diagnosis_dialog(self) -> DiagnosisDialog:
|
||||
dialog = getattr(self, "_diagnosis_dialog_impl", None)
|
||||
if dialog is None:
|
||||
dialog = DiagnosisDialog(self.repository, self, permissions=self.permissions)
|
||||
dialog.saved.connect(lambda: self.refresh(silent=True))
|
||||
self._diagnosis_dialog_impl = dialog
|
||||
return dialog
|
||||
|
||||
def _build_toolbar(self) -> QWidget:
|
||||
frame = QFrame()
|
||||
frame.setObjectName("FilterBar")
|
||||
@@ -457,7 +465,9 @@ class AppointmentsPage(QWidget):
|
||||
button = QPushButton(label)
|
||||
button.setCheckable(True)
|
||||
button.setProperty("variant", "chip")
|
||||
button.clicked.connect(lambda _checked=False, value=preset: self._set_date_preset(value))
|
||||
button.clicked.connect(
|
||||
lambda _checked=False, value=preset: self._set_date_preset(value)
|
||||
)
|
||||
self.date_buttons[preset] = button
|
||||
date_row.addWidget(button)
|
||||
date_row.addStretch(1)
|
||||
@@ -490,9 +500,7 @@ class AppointmentsPage(QWidget):
|
||||
layout.setSpacing(8)
|
||||
|
||||
actions = QHBoxLayout()
|
||||
self.edit_button = self._action_button(
|
||||
"编辑患者", "tcm.diagnosis/edit", self._edit_patient
|
||||
)
|
||||
self.edit_button = self._action_button("编辑患者", "tcm.diagnosis/edit", self._edit_patient)
|
||||
actions.addWidget(self.edit_button)
|
||||
self.qr_button = self._action_button(
|
||||
"视频二维码", "tcm.diagnosis/videoQr", self._request_video_qr
|
||||
@@ -510,9 +518,7 @@ class AppointmentsPage(QWidget):
|
||||
"开方", "tcm.diagnosis/kaifang", self._open_prescription
|
||||
)
|
||||
actions.addWidget(self.prescription_button)
|
||||
self.case_button = self._action_button(
|
||||
"病历", "tcm.diagnosis/kaifang", self._view_case
|
||||
)
|
||||
self.case_button = self._action_button("病历", "tcm.diagnosis/kaifang", self._view_case)
|
||||
actions.addWidget(self.case_button)
|
||||
self.cancel_button = self._action_button(
|
||||
"取消挂号",
|
||||
@@ -601,7 +607,9 @@ class AppointmentsPage(QWidget):
|
||||
dialog = QDialog(self)
|
||||
dialog.setWindowTitle("自定义日期")
|
||||
layout = QVBoxLayout(dialog)
|
||||
start = QDateEdit(QDate.fromString(self._start_date or date.today().isoformat(), "yyyy-MM-dd"))
|
||||
start = QDateEdit(
|
||||
QDate.fromString(self._start_date or date.today().isoformat(), "yyyy-MM-dd")
|
||||
)
|
||||
start.setCalendarPopup(True)
|
||||
start.setDisplayFormat("yyyy-MM-dd")
|
||||
end = QDateEdit(QDate.fromString(self._end_date or date.today().isoformat(), "yyyy-MM-dd"))
|
||||
@@ -719,9 +727,7 @@ class AppointmentsPage(QWidget):
|
||||
self._fit_table_rows()
|
||||
for row_index in range(self.table.rowCount()):
|
||||
source_item = self.table.item(row_index, 0)
|
||||
source = (
|
||||
source_item.data(Qt.ItemDataRole.UserRole) if source_item is not None else None
|
||||
)
|
||||
source = source_item.data(Qt.ItemDataRole.UserRole) if source_item is not None else None
|
||||
status = _status_value(source)
|
||||
status_kind = {
|
||||
1: "warning",
|
||||
@@ -822,7 +828,7 @@ class AppointmentsPage(QWidget):
|
||||
if diagnosis_id <= 0:
|
||||
show_toast(self, "该预约没有关联诊单信息。", "warning")
|
||||
return
|
||||
self.diagnosis_dialog.open_for(diagnosis_id, editable=True, seed=row)
|
||||
self._diagnosis_dialog().open_for(diagnosis_id, editable=True, seed=row)
|
||||
|
||||
def _request_video(self) -> None:
|
||||
if not _canonical_allowed(
|
||||
@@ -882,6 +888,7 @@ class AppointmentsPage(QWidget):
|
||||
self._action_generation += 1
|
||||
generation = self._action_generation
|
||||
self.banner.show_message("正在生成视频二维码…", "info")
|
||||
|
||||
def _worker() -> dict[str, Any]:
|
||||
config = invoke(self.repository, "get_mini_program_config")
|
||||
if not str(first_value(config, "app_id", default="") or "").strip():
|
||||
@@ -901,9 +908,7 @@ class AppointmentsPage(QWidget):
|
||||
if not url:
|
||||
raise ValueError("服务器未返回可用的二维码地址")
|
||||
try:
|
||||
result["_image_bytes"] = invoke(
|
||||
self.repository, "download_public_image", url=url
|
||||
)
|
||||
result["_image_bytes"] = invoke(self.repository, "download_public_image", url=url)
|
||||
except Exception as exc:
|
||||
result["_image_error"] = friendly_error(exc)
|
||||
return result
|
||||
@@ -962,8 +967,7 @@ class AppointmentsPage(QWidget):
|
||||
else:
|
||||
reason = str(first_value(result, "_image_error", default="") or "").strip()
|
||||
image_label.setText(
|
||||
"二维码图片加载失败\n请重新生成或在浏览器中打开"
|
||||
+ (f"\n{reason}" if reason else "")
|
||||
"二维码图片加载失败\n请重新生成或在浏览器中打开" + (f"\n{reason}" if reason else "")
|
||||
)
|
||||
image_row = QHBoxLayout()
|
||||
image_row.addStretch(1)
|
||||
@@ -1186,64 +1190,64 @@ class AppointmentsPage(QWidget):
|
||||
def _prescription_loaded(self, existing: Any, row: Any, generation: int) -> None:
|
||||
if generation != self._prescription_generation:
|
||||
return
|
||||
self.banner.clear()
|
||||
if existing is not None and _as_int(first_value(existing, "id", default=0)) > 0:
|
||||
approved = _as_int(first_value(existing, "audit_status", "status"), -1) == 1
|
||||
voided = _as_int(first_value(existing, "void_status", "is_void"), 0) == 1
|
||||
if not approved or voided:
|
||||
self._open_existing_prescription_editor(existing)
|
||||
else:
|
||||
dialog = PrescriptionDetailDialog(
|
||||
existing,
|
||||
can_open_diagnosis=_canonical_allowed(
|
||||
self.permissions, "tcm.diagnosis/readonlyDetail", default=False
|
||||
),
|
||||
parent=self,
|
||||
)
|
||||
dialog.diagnosis_requested.connect(self._open_diagnosis_id)
|
||||
dialog.exec()
|
||||
return
|
||||
self._begin_case_record_load(row)
|
||||
|
||||
def _open_existing_prescription_editor(self, prescription: Any) -> None:
|
||||
prescription_id = _as_int(first_value(prescription, "id", "prescription_id", default=0))
|
||||
if prescription_id <= 0:
|
||||
self.banner.show_message("处方编号不完整,无法编辑。", "danger")
|
||||
return
|
||||
dialog = PrescriptionEditorDialog(
|
||||
self.repository,
|
||||
prescription,
|
||||
mode="edit",
|
||||
current_user=self.current_user,
|
||||
parent=self,
|
||||
)
|
||||
diagnosis_signal = getattr(dialog, "diagnosis_requested", None)
|
||||
if diagnosis_signal is not None:
|
||||
diagnosis_signal.connect(self._open_diagnosis_id)
|
||||
if dialog.exec() != QDialog.DialogCode.Accepted:
|
||||
return
|
||||
frozen_payload = MappingProxyType(dialog.payload())
|
||||
self._mutation_pending = True
|
||||
self._action_generation += 1
|
||||
generation = self._action_generation
|
||||
self.banner.show_message("正在保存处方…", "info")
|
||||
run_async(
|
||||
lambda: invoke(
|
||||
self.repository,
|
||||
"update_prescription",
|
||||
prescription=prescription_id,
|
||||
changes=frozen_payload,
|
||||
),
|
||||
on_success=lambda _result: self._prescription_updated(generation),
|
||||
on_error=lambda error: self._action_error(error, generation),
|
||||
on_finished=lambda: self._mutation_finished(generation),
|
||||
)
|
||||
|
||||
def _prescription_updated(self, generation: int) -> None:
|
||||
if generation != self._action_generation:
|
||||
return
|
||||
self.banner.show_message("处方已保存并重新进入待审核。", "success")
|
||||
self.refresh(silent=True)
|
||||
self.banner.clear()
|
||||
if existing is not None and _as_int(first_value(existing, "id", default=0)) > 0:
|
||||
approved = _as_int(first_value(existing, "audit_status", "status"), -1) == 1
|
||||
voided = _as_int(first_value(existing, "void_status", "is_void"), 0) == 1
|
||||
if not approved or voided:
|
||||
self._open_existing_prescription_editor(existing)
|
||||
else:
|
||||
dialog = PrescriptionDetailDialog(
|
||||
existing,
|
||||
can_open_diagnosis=_canonical_allowed(
|
||||
self.permissions, "tcm.diagnosis/readonlyDetail", default=False
|
||||
),
|
||||
parent=self,
|
||||
)
|
||||
dialog.diagnosis_requested.connect(self._open_diagnosis_id)
|
||||
dialog.exec()
|
||||
return
|
||||
self._begin_case_record_load(row)
|
||||
|
||||
def _open_existing_prescription_editor(self, prescription: Any) -> None:
|
||||
prescription_id = _as_int(first_value(prescription, "id", "prescription_id", default=0))
|
||||
if prescription_id <= 0:
|
||||
self.banner.show_message("处方编号不完整,无法编辑。", "danger")
|
||||
return
|
||||
dialog = PrescriptionEditorDialog(
|
||||
self.repository,
|
||||
prescription,
|
||||
mode="edit",
|
||||
current_user=self.current_user,
|
||||
parent=self,
|
||||
)
|
||||
diagnosis_signal = getattr(dialog, "diagnosis_requested", None)
|
||||
if diagnosis_signal is not None:
|
||||
diagnosis_signal.connect(self._open_diagnosis_id)
|
||||
if dialog.exec() != QDialog.DialogCode.Accepted:
|
||||
return
|
||||
frozen_payload = MappingProxyType(dialog.payload())
|
||||
self._mutation_pending = True
|
||||
self._action_generation += 1
|
||||
generation = self._action_generation
|
||||
self.banner.show_message("正在保存处方…", "info")
|
||||
run_async(
|
||||
lambda: invoke(
|
||||
self.repository,
|
||||
"update_prescription",
|
||||
prescription=prescription_id,
|
||||
changes=frozen_payload,
|
||||
),
|
||||
on_success=lambda _result: self._prescription_updated(generation),
|
||||
on_error=lambda error: self._action_error(error, generation),
|
||||
on_finished=lambda: self._mutation_finished(generation),
|
||||
)
|
||||
|
||||
def _prescription_updated(self, generation: int) -> None:
|
||||
if generation != self._action_generation:
|
||||
return
|
||||
self.banner.show_message("处方已保存并重新进入待审核。", "success")
|
||||
self.refresh(silent=True)
|
||||
|
||||
def _begin_case_record_load(self, row: Any) -> None:
|
||||
snapshot = deepcopy(row)
|
||||
@@ -1304,10 +1308,10 @@ class AppointmentsPage(QWidget):
|
||||
"visit_no": build_prescription_visit_no(
|
||||
diagnosis_id=diagnosis_id, appointment_id=appointment_id
|
||||
),
|
||||
"tongue": authoritative("tongue", "tongue_coating", default=""),
|
||||
"tongue_image": authoritative("tongue_image", default=""),
|
||||
"pulse": authoritative("pulse", default=""),
|
||||
"pulse_condition": authoritative("pulse_condition", default=""),
|
||||
"tongue": authoritative("tongue", "tongue_coating", default=""),
|
||||
"tongue_image": authoritative("tongue_image", default=""),
|
||||
"pulse": authoritative("pulse", default=""),
|
||||
"pulse_condition": authoritative("pulse_condition", default=""),
|
||||
"clinical_diagnosis": build_prescription_clinical_diagnosis(
|
||||
diagnosis, patient, record, case_record
|
||||
),
|
||||
@@ -1318,21 +1322,21 @@ class AppointmentsPage(QWidget):
|
||||
|
||||
def _open_diagnosis_id(self, diagnosis_id: int) -> None:
|
||||
if diagnosis_id > 0:
|
||||
self.diagnosis_dialog.open_view_only(diagnosis_id)
|
||||
self._diagnosis_dialog().open_view_only(diagnosis_id)
|
||||
|
||||
def _open_prescription_editor(self, record: Any, case_record: Any) -> None:
|
||||
seed = self._prescription_seed(record, case_record)
|
||||
dialog = PrescriptionEditorDialog(
|
||||
dialog = PrescriptionEditorDialog(
|
||||
self.repository,
|
||||
seed,
|
||||
mode="add",
|
||||
current_user=self.current_user,
|
||||
parent=self,
|
||||
)
|
||||
diagnosis_signal = getattr(dialog, "diagnosis_requested", None)
|
||||
if diagnosis_signal is not None:
|
||||
diagnosis_signal.connect(self._open_diagnosis_id)
|
||||
if dialog.exec() != QDialog.DialogCode.Accepted:
|
||||
parent=self,
|
||||
)
|
||||
diagnosis_signal = getattr(dialog, "diagnosis_requested", None)
|
||||
if diagnosis_signal is not None:
|
||||
diagnosis_signal.connect(self._open_diagnosis_id)
|
||||
if dialog.exec() != QDialog.DialogCode.Accepted:
|
||||
return
|
||||
payload = dialog.payload()
|
||||
payload["diagnosis_id"] = seed["diagnosis_id"]
|
||||
|
||||
Reference in New Issue
Block a user