first commit

This commit is contained in:
Your Name
2026-09-08 11:40:15 +08:00
commit a5353f7eb5
9568 changed files with 1646214 additions and 0 deletions
@@ -0,0 +1,348 @@
from __future__ import annotations
import os
import sys
from pathlib import Path
from typing import Any
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
ROOT = Path(__file__).resolve().parents[1]
SRC = ROOT / "src"
if str(SRC) not in sys.path:
sys.path.insert(0, str(SRC))
from PySide6.QtCore import Qt # noqa: E402
from PySide6.QtGui import QFont, QFontDatabase # noqa: E402
from PySide6.QtWidgets import QApplication, QFrame, QLabel, QVBoxLayout # noqa: E402
from doctor_workstation.ui.diagnosis_drawer import DIAGNOSIS_QSS # noqa: E402
from doctor_workstation.ui.diagnosis_media import ( # noqa: E402
InlineRecordingPlayer,
RecordingPlaybackCell,
)
from doctor_workstation.ui.dialogs.diagnosis import DiagnosisDialog # noqa: E402
class RenderRepository:
def get_prescription_order(self, order_id: int) -> dict[str, Any]:
return {"id": order_id}
def set_revisit_slot_start_offset(self, diagnosis_id: int, offset: int) -> dict[str, Any]:
return {"diagnosis_id": diagnosis_id, "revisit_slot_start_offset": offset}
def upload_call_recording(
self,
path: str,
diagnosis_id: int,
*,
call_record_id: int | None = None,
) -> dict[str, Any]:
return {
"path": path,
"diagnosis_id": diagnosis_id,
"call_record_id": call_record_id,
}
def order_detail() -> dict[str, Any]:
return {
"id": 801,
"order_no": "RX-20260811-0801",
"gancao_reciperl_order_no": "GC-260811-4728",
"diagnosis_id": 501,
"amount": 428.5,
"linked_pay_paid_total": 300,
"refund_amount": 20,
"agency_collect_amount": 128.5,
"fulfillment_status": 5,
"prescription_audit_status": 1,
"payment_slip_audit_status": 1,
"doctor_name": "陈医生",
"creator_name": "赵医助",
"creator_account": "assistant.zhao",
"create_time": "2026-08-11 09:26",
"recipient_name": "林晓岚",
"recipient_phone": "18600004218",
"shipping_province": "河南省",
"shipping_city": "洛阳市",
"shipping_district": "洛龙区",
"shipping_address": "开元大道 88 号",
"is_follow_up": 1,
"medication_days": 14,
"service_channel": "线上复诊",
"service_package": ["调理服务", "复诊随访"],
"fee_type": 3,
"tracking_number": "SF164208110801",
"express_company": "sf",
"remark_assistant": "工作日下午送达",
"prescription_audit_remark": "辨证与用量已复核",
"payment_slip_audit_remark": "收款凭证已核验",
"prescription": {
"id": 601,
"sn": "RX601",
"patient_name": "林晓岚",
"gender_desc": "",
"age": 34,
"phone": "18600004218",
"prescription_date": "2026-08-11",
"doctor_name": "陈医生",
"prescription_type": "饮片",
"clinical_diagnosis": "气阴两虚",
"dose_count": 14,
"dose_unit": "",
"usage_instruction": "水煎服",
"amount": 428.5,
"audit_status": 1,
"dosage_amount": 180,
"dosage_unit": "g",
"need_decoction": 1,
"times_per_day": 2,
"usage_days": 14,
"dietary_taboo": ["辛辣", "生冷"],
"void_status": 0,
},
"linked_pay_orders": [
{
"id": 9101,
"order_no": "PAY-9101",
"order_type_desc": "药品费用",
"amount": 300,
"status_desc": "已支付",
"creator_name": "赵医助",
"create_time": "2026-08-11 09:32",
}
],
"unlinked_pay_orders": [],
"logistics_trace": {
"state_text": "运输中",
"carrier_label": "顺丰速运",
"traces": [
{
"time": "2026-08-11 16:10",
"status": "运输中",
"context": "快件已离开洛阳集散中心",
},
{
"time": "2026-08-11 13:06",
"status": "已揽收",
"context": "顺丰速运已收取快件",
},
],
},
"logs": [
{
"admin_name": "赵医助",
"action": "ship",
"summary": "确认发货并填写顺丰运单",
"create_time": "2026-08-11 13:08",
}
],
}
def render_order(app: QApplication, output: Path) -> None:
host = DiagnosisDialog(RenderRepository(), permissions=["*"])
host.resize(1440, 900)
host.show()
drawer = host._build_order_detail_dialog(order_detail(), 801)
drawer.show()
app.processEvents()
image = drawer.grab()
if not image.save(str(output), "PNG"):
raise RuntimeError(f"failed to save {output}")
host.resize(1024, 640)
drawer.sync_to_owner()
app.processEvents()
compact = output.parent / "diagnosis_state_order_detail_drawer_1024x640.png"
if not drawer.grab().save(str(compact), "PNG"):
raise RuntimeError(f"failed to save {compact}")
legacy = output.parent / "diagnosis_state_order_detail_640x540.png"
if not drawer.grab().save(str(legacy), "PNG"):
raise RuntimeError(f"failed to save {legacy}")
drawer.close()
host.close()
app.processEvents()
def render_video(app: QApplication, output: Path) -> None:
dialog = DiagnosisDialog(RenderRepository(), permissions=["*"])
dialog._editable = True
dialog._can_video_upload = True
dialog._diagnosis_id = 501
dialog._tab_generations["video"] = 3
dialog._fill_video(
[
{
"id": 48,
"recording_urls_list": [
"https://media.example.invalid/consultation-48.mp4",
"https://bucket.cos.ap-shanghai.myqcloud.com/consultation-48/index.m3u8",
"https://media.example.invalid/consultation-48.webm",
],
"start_time_text": "2026-08-11 10:02:18",
"end_time_text": "2026-08-11 10:26:43",
"call_type": 2,
"room_id": "room-501-20260811",
"duration_text": "24分25秒",
"status": 2,
"recording_status_text": "录制完成",
},
{
"id": 47,
"recording_urls_list": [],
"start_time_text": "2026-08-04 09:18:05",
"end_time_text": "2026-08-04 09:23:17",
"call_type": 1,
"room_id": "room-501-20260804",
"duration_text": "5分12秒",
"status": 3,
"recording_status_text": "暂无录制",
},
]
)
preview = QFrame()
preview.setObjectName("DiagnosisVideoRender")
preview.setStyleSheet(
DIAGNOSIS_QSS
+ "QFrame#DiagnosisVideoRender{background:#F6F8FB;}"
+ "QLabel#DiagnosisVideoRenderTitle{color:#1F2937;font-size:20px;font-weight:650;}"
)
layout = QVBoxLayout(preview)
layout.setContentsMargins(22, 18, 22, 22)
layout.setSpacing(12)
title = QLabel("视频录制回放")
title.setObjectName("DiagnosisVideoRenderTitle")
title.setFixedHeight(32)
title.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
layout.addWidget(title)
page = dialog._tab_pages["video"]
page.setParent(preview)
page.show()
dialog.video_upload_button.show()
layout.addWidget(page, 1)
preview.resize(1200, 560)
preview.show()
app.processEvents()
table = dialog._table_registry["video"][1]
playback = table.cellWidget(0, 0)
if not isinstance(playback, RecordingPlaybackCell):
raise RuntimeError("video render is missing the inline playback cell")
player = playback.findChild(InlineRecordingPlayer)
if (
player is None
or playback.height() < playback.minimumSizeHint().height()
or not 158 <= player.height() <= 180
or table.rowHeight(0) < playback.required_table_row_height()
):
raise RuntimeError("video render clipped the inline playback geometry")
image = preview.grab()
if not image.save(str(output), "PNG"):
raise RuntimeError(f"failed to save {output}")
preview.resize(1024, 640)
app.processEvents()
replay_state = output.parent / "diagnosis_state_video_replay_1024x640.png"
if not preview.grab().save(str(replay_state), "PNG"):
raise RuntimeError(f"failed to save {replay_state}")
table.horizontalScrollBar().setValue(table.horizontalScrollBar().maximum())
app.processEvents()
upload_state = output.parent / "diagnosis_state_video_upload_action_1024x640.png"
if not preview.grab().save(str(upload_state), "PNG"):
raise RuntimeError(f"failed to save {upload_state}")
preview.close()
dialog.close()
app.processEvents()
def render_order_offset(app: QApplication, output: Path) -> None:
dialog = DiagnosisDialog(RenderRepository(), permissions=["*"])
dialog._editable = True
dialog._can_offset = True
dialog._can_order_detail = True
dialog._diagnosis_id = 501
dialog._saved_order_offset = 0
dialog.order_offset.setVisible(True)
dialog.order_offset_save.setVisible(True)
dialog.order_offset.setValue(2)
dialog._fill_orders(
[
{
"id": 801,
"order_no": "RX-20260811-0801",
"global_visit_seq": 3,
"counts_for_revisit_rate": 1,
"amount": 428.5,
"doctor_name": "陈医生",
"assistant_name": "赵医助",
"fulfillment_status": 5,
"create_time": "2026-08-11 09:26",
},
{
"id": 794,
"order_no": "RX-20260724-0794",
"global_visit_seq": 2,
"counts_for_revisit_rate": 1,
"amount": 386,
"doctor_name": "陈医生",
"assistant_name": "赵医助",
"fulfillment_status": 6,
"create_time": "2026-07-24 10:18",
},
]
)
dialog._orders_total = 2
dialog._update_orders_pager()
preview = QFrame()
preview.setObjectName("DiagnosisOrderRender")
preview.setStyleSheet(
DIAGNOSIS_QSS
+ "QFrame#DiagnosisOrderRender{background:#F6F8FB;}"
+ "QLabel#DiagnosisOrderRenderTitle{color:#1F2937;font-size:20px;font-weight:650;}"
)
layout = QVBoxLayout(preview)
layout.setContentsMargins(22, 18, 22, 22)
layout.setSpacing(12)
title = QLabel("业务订单")
title.setObjectName("DiagnosisOrderRenderTitle")
title.setFixedHeight(32)
layout.addWidget(title)
page = dialog._tab_pages["orders"]
page.setParent(preview)
page.show()
layout.addWidget(page, 1)
preview.resize(1024, 640)
preview.show()
app.processEvents()
if not preview.grab().save(str(output), "PNG"):
raise RuntimeError(f"failed to save {output}")
preview.close()
dialog.close()
app.processEvents()
def main() -> int:
output_dir = ROOT / "artifacts" / "diagnosis_visual"
output_dir.mkdir(parents=True, exist_ok=True)
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))
order_output = output_dir / "diagnosis_order_detail_drawer_1440x900.png"
video_output = output_dir / "diagnosis_video_inline_player_1200x560.png"
offset_output = output_dir / "diagnosis_state_order_offset_1024x640.png"
render_order(app, order_output)
render_video(app, video_output)
render_order_offset(app, offset_output)
print(order_output)
print(video_output)
print(offset_output)
return 0
if __name__ == "__main__":
raise SystemExit(main())