This commit is contained in:
Your Name
2026-09-07 10:07:47 +08:00
parent cf3fbdc5ef
commit d5164b7369
388 changed files with 19863 additions and 18720 deletions
@@ -60,6 +60,7 @@ from ..diagnosis_drawer import (
)
from ..diagnosis_editors import DailyRecordEditorDialog
from ..diagnosis_media import RecordingPlaybackCell, RecordingPlayerDialog
from ..infinite_list import InfiniteList
from ..widgets import (
display_text,
first_value,
@@ -190,74 +191,74 @@ _ORDER_OFFSET_HELP = (
_ORDER_DETAIL_QSS = """
QDialog#DiagnosisOrderDetailOverlay { background: transparent; }
QFrame#DiagnosisOrderDetailScrim { background: rgba(30, 64, 175, 0.18); border: 0; }
QFrame#DiagnosisOrderDetailScrim { background: rgba(26, 28, 31, 0.18); border: 0; }
QFrame#DiagnosisOrderDetailDrawer {
background: #F7F9FE;
background: #F7F7F7;
border: 0;
border-left: 1px solid #DDE7FF;
border-left: 1px solid #F0F0F0;
}
QFrame#DiagnosisOrderDetailHeader {
background: #FFFFFF;
border: 0;
border-bottom: 1px solid #DDE7FF;
border-bottom: 1px solid #F0F0F0;
}
QLabel#DiagnosisOrderDetailTitle { color: #15224A; font-size: 19px; font-weight: 650; }
QLabel#DiagnosisOrderDetailMeta { color: #7481A3; font-size: 12px; }
QLabel#DiagnosisOrderDetailTitle { color: #1A1C1F; font-size: 19px; font-weight: 650; }
QLabel#DiagnosisOrderDetailMeta { color: #606163; font-size: 12px; }
QLabel#DiagnosisOrderReadonlyBadge {
color: #3F4E75;
background: #F7F9FE;
border: 1px solid #E2E7F4;
color: #1A1C1F;
background: #F7F7F7;
border: 1px solid #EDEDEE;
border-radius: 4px;
padding: 3px 7px;
font-size: 11px;
font-weight: 600;
}
QScrollArea#DiagnosisOrderDetailScroll { border: 0; background: #F7F9FE; }
QScrollArea#DiagnosisOrderDetailScroll > QWidget > QWidget { background: #F7F9FE; }
QScrollArea#DiagnosisOrderDetailScroll { border: 0; background: #F7F7F7; }
QScrollArea#DiagnosisOrderDetailScroll > QWidget > QWidget { background: #F7F7F7; }
QFrame[orderAmountCard="true"] {
background: #FFFFFF;
border: 1px solid #DDE7FF;
border: 1px solid #F0F0F0;
border-radius: 9px;
}
QLabel[orderAmountTitle="true"] { color: #7481A3; font-size: 11px; font-weight: 550; }
QLabel[orderAmountTitle="true"] { color: #606163; font-size: 11px; font-weight: 550; }
QLabel[orderAmountValue="true"] {
color: #15224A;
color: #1A1C1F;
font-size: 18px;
font-weight: 700;
}
QLabel[orderAmountTone="danger"] { color: #C43E55; }
QLabel[orderAmountTone="success"] { color: #16876C; }
QLabel[orderAmountTone="warning"] { color: #9A6813; }
QLabel[orderAmountTone="danger"] { color: #BE4B58; }
QLabel[orderAmountTone="success"] { color: #287B65; }
QLabel[orderAmountTone="warning"] { color: #A9691D; }
QFrame[orderDetailSection="true"] {
background: #FFFFFF;
border: 1px solid #E2E7F4;
border: 1px solid #EDEDEE;
border-radius: 10px;
}
QLabel[orderSectionTitle="true"] { color: #15224A; font-size: 15px; font-weight: 650; }
QLabel[orderSectionHint="true"] { color: #7481A3; font-size: 11px; }
QLabel[orderSectionTitle="true"] { color: #1A1C1F; font-size: 15px; font-weight: 650; }
QLabel[orderSectionHint="true"] { color: #606163; font-size: 11px; }
QFrame[orderField="true"] {
background: #F2F6FE;
border: 1px solid #E2E7F4;
background: #F7F7F7;
border: 1px solid #EDEDEE;
border-radius: 7px;
}
QLabel[orderFieldLabel="true"] { color: #7481A3; font-size: 11px; }
QLabel[orderFieldValue="true"] { color: #15224A; font-size: 13px; }
QLabel[orderFieldLabel="true"] { color: #6A6B6D; font-size: 11px; }
QLabel[orderFieldValue="true"] { color: #1A1C1F; font-size: 13px; }
QLabel[orderEmptyState="true"] {
color: #7481A3;
background: #F2F6FE;
border: 1px dashed #C9D8F2;
color: #606163;
background: #F7F7F7;
border: 1px dashed #E4E4E5;
border-radius: 5px;
padding: 18px 12px;
font-size: 12px;
}
QFrame#DiagnosisOrderTimelineItem { border: 0; border-left: 2px solid #93B4F4; }
QLabel#DiagnosisOrderTimelineTime { color: #7481A3; font-size: 11px; }
QLabel#DiagnosisOrderTimelineTitle { color: #15224A; font-size: 12px; font-weight: 600; }
QLabel#DiagnosisOrderTimelineBody { color: #7481A3; font-size: 12px; }
QFrame#DiagnosisOrderTimelineItem { border: 0; border-left: 2px solid #8B9AD9; }
QLabel#DiagnosisOrderTimelineTime { color: #606163; font-size: 11px; }
QLabel#DiagnosisOrderTimelineTitle { color: #1A1C1F; font-size: 12px; font-weight: 600; }
QLabel#DiagnosisOrderTimelineBody { color: #606163; font-size: 12px; }
QFrame#DiagnosisOrderDetailFooter {
background: #FFFFFF;
border: 0;
border-top: 1px solid #DDE7FF;
border-top: 1px solid #F0F0F0;
}
"""
@@ -1003,8 +1004,8 @@ class DiagnosisDialog(QDialog):
self.readonly_back_button.setCursor(Qt.CursorShape.PointingHandCursor)
self.readonly_back_button.setStyleSheet(
"QPushButton{height:32px;padding:0 8px;border:0;background:transparent;"
"color:#5265F6;font-size:13px;font-weight:500;}"
"QPushButton:hover,QPushButton:focus{background:#F0F2FF;border-radius:6px;}"
"color:#1A1C1F;font-size:13px;font-weight:500;}"
"QPushButton:hover,QPushButton:focus{background:#EEF1FA;border-radius:6px;}"
)
self.readonly_back_button.clicked.connect(self.reject)
left_layout.addWidget(self.readonly_back_button)
@@ -1532,20 +1533,11 @@ class DiagnosisDialog(QDialog):
layout.addWidget(toolbar)
self.orders_table = self._new_table("orders", "DiagnosisTableOrders")
layout.addWidget(self.orders_table, 1)
footer = QHBoxLayout()
self.orders_summary = QLabel("共 0 条")
self.orders_summary.setObjectName("DiagnosisOrdersSummary")
footer.addWidget(self.orders_summary)
footer.addStretch(1)
self.orders_previous = QPushButton("上一页")
self.orders_previous.clicked.connect(lambda: self._change_orders_page(-1))
footer.addWidget(self.orders_previous)
self.orders_page_label = QLabel("1 / 1")
footer.addWidget(self.orders_page_label)
self.orders_next = QPushButton("下一页")
self.orders_next.clicked.connect(lambda: self._change_orders_page(1))
footer.addWidget(self.orders_next)
layout.addLayout(footer)
self.orders_list = InfiniteList(self._orders_page_size, page)
for table in self._table_registry["orders"]:
self.orders_list.bind(table)
self._orders_footer_layout = layout
layout.addWidget(self.orders_list)
return page
def _wrap_tab(self, object_name: str, body: QWidget) -> QScrollArea:
@@ -2021,6 +2013,13 @@ class DiagnosisDialog(QDialog):
self._daily_todo_status = None
self._orders_page = 1
self._orders_total = 0
self.orders_list.reset()
footer_layout = (
self._readonly_sections["orders"].layout()
if self._standalone_readonly
else self._orders_footer_layout
)
footer_layout.addWidget(self.orders_list)
self._detail = authoritative_detail if authoritative_detail is not None else seed
self.save_button.set_state("idle")
self.refresh_permissions()
@@ -2315,6 +2314,7 @@ class DiagnosisDialog(QDialog):
self._generation += 1
self._save_generation += 1
self._orders_generation += 1
self.orders_list.invalidate()
self._order_detail_generation += 1
self._daily_mutation_generation += 1
self._notes_mutation_generation += 1
@@ -2639,6 +2639,9 @@ class DiagnosisDialog(QDialog):
return
if not force and (key in self._loaded_tabs or key in self._loading_tabs):
return
if key == "orders":
self._load_orders()
return
self._tab_generations[key] += 1
generation = self._tab_generations[key]
diagnosis_id = self._diagnosis_id
@@ -2732,10 +2735,9 @@ class DiagnosisDialog(QDialog):
self._fill_prescriptions(page_items(result))
elif key == "orders":
rows = page_items(result)
self._orders_page = 1
self._orders_page = self.orders_list.page
self._orders_total = page_total(result, len(rows))
self._fill_orders(rows)
self._update_orders_pager()
elif key == "assign":
self._fill_assignments(page_items(result))
elif key == "appointment":
@@ -3448,8 +3450,7 @@ class DiagnosisDialog(QDialog):
panel.set_unavailable("切换到聊天记录后加载归档数据。")
for panel in self._daily_panels:
panel.clear()
self.orders_summary.setText("共 0 条")
self.orders_page_label.setText("1 / 1")
self.orders_list.update_state(1, 0)
@staticmethod
def _set_row(table: QTableWidget, row: int, values: Sequence[Any]) -> None:
@@ -4067,6 +4068,9 @@ class DiagnosisDialog(QDialog):
)
for row_index, row in enumerate(rows):
order_id = _int(first_value(row, "id", "order_id"), 0)
item = table.item(row_index, 0)
if item is not None:
item.setData(Qt.ItemDataRole.UserRole, row)
if (
self._can_order_detail
and order_id > 0
@@ -4738,52 +4742,44 @@ class DiagnosisDialog(QDialog):
if generation == self._order_detail_generation and diagnosis_id == self._diagnosis_id:
self._show_message(friendly_error(error), "danger")
def _update_orders_pager(self) -> None:
pages = max(1, (self._orders_total + self._orders_page_size - 1) // self._orders_page_size)
self.orders_summary.setText(f"共 {self._orders_total} 条")
self.orders_page_label.setText(f"{self._orders_page} / {pages}")
self.orders_previous.setEnabled(self._orders_page > 1)
self.orders_next.setEnabled(self._orders_page < pages)
def _change_orders_page(self, offset: int) -> None:
def _load_orders(self) -> None:
if not self._can_patient_orders or self._diagnosis_id <= 0:
return
pages = max(1, (self._orders_total + self._orders_page_size - 1) // self._orders_page_size)
target_page = self._orders_page + offset
if target_page < 1 or target_page > pages:
return
self._orders_generation += 1
generation = self._orders_generation
self._tab_generations["orders"] += 1
generation = self._tab_generations["orders"]
diagnosis_id = self._diagnosis_id
patient_id = self._patient_id
self._show_message("正在加载患者订单…", "info")
run_async(
lambda: self._query_orders(diagnosis_id, patient_id, target_page),
on_success=lambda result: self._apply_orders_page(
result, diagnosis_id, target_page, generation
self._loading_tabs.add("orders")
if not self.orders_list.rows:
self._set_tab_loading("orders")
self.orders_list.reload(
lambda page: self._query_orders(diagnosis_id, patient_id, page),
apply=lambda result: self._apply_orders_result(
result, diagnosis_id, generation
),
on_error=lambda error: self._orders_error(error, diagnosis_id, generation),
on_error=lambda error: self._tab_load_error(
"orders", error, diagnosis_id, generation
),
runner=run_async,
query_key=(diagnosis_id, patient_id),
)
def _apply_orders_page(
def _apply_orders_result(
self,
result: Any,
diagnosis_id: int,
page: int,
generation: int,
) -> None:
if generation != self._orders_generation or diagnosis_id != self._diagnosis_id:
if (
generation != self._tab_generations["orders"]
or diagnosis_id != self._diagnosis_id
or not self._authoritative_detail_loaded
):
return
rows = page_items(result)
self._orders_page = page
self._orders_total = page_total(result, len(rows))
self._fill_orders(rows)
self._update_orders_pager()
self._clear_message()
def _orders_error(self, error: Exception, diagnosis_id: int, generation: int) -> None:
if generation == self._orders_generation and diagnosis_id == self._diagnosis_id:
self._show_message(friendly_error(error), "danger")
if self.orders_list.page == 0:
self._fill_orders([])
return
self._apply_tab_result("orders", result, diagnosis_id, generation)
def _save(self) -> None:
if (