This commit is contained in:
Your Name
2026-08-12 17:18:56 +08:00
parent 28cd110dae
commit f48a66b611
24 changed files with 3095 additions and 233 deletions
@@ -20,6 +20,7 @@ from PySide6.QtWidgets import (
QInputDialog,
QLabel,
QMessageBox,
QPlainTextEdit,
QPushButton,
QScrollArea,
QSizePolicy,
@@ -1411,7 +1412,7 @@ class DiagnosisDialog(QDialog):
layout.setContentsMargins(16, 14, 16, 18)
layout.setSpacing(12)
toolbar = QHBoxLayout()
hint = QLabel("每条通话记录可包含多个回放地址,并可追加指定记录的视频。")
hint = QLabel("每条通话记录可包含多个回放地址;录音转写完成后可查看本次面诊对话文字。")
hint.setObjectName("DiagnosisDialogGuidance")
hint.setWordWrap(True)
toolbar.addWidget(hint, 1)
@@ -1553,7 +1554,7 @@ class DiagnosisDialog(QDialog):
("房间号", 180),
("时长", 110),
("状态", 90),
("录制", 100),
("录制 / 文字", 120),
("操作", 130),
),
"assign": (
@@ -3365,11 +3366,71 @@ class DiagnosisDialog(QDialog):
cell.stop()
self._inline_recording_cells.clear()
@staticmethod
def _call_transcript_text(row: Any) -> str:
raw = first_value(
row,
"transcript_text",
"call_transcript",
"conversation_text",
"transcript",
default="",
)
if isinstance(raw, Mapping):
raw = first_value(raw, "text", "full_text", "content", default="")
text = str(raw or "").strip()
if text:
return text
segments = first_value(row, "transcript_segments", "segments", default=[]) or []
if isinstance(segments, Sequence) and not isinstance(
segments, (str, bytes, bytearray)
):
labels = {"doctor": "医生", "patient": "患者", "unknown": "未知说话人"}
lines: list[str] = []
for segment in segments:
content = str(first_value(segment, "text", "sourceText", default="") or "").strip()
if not content:
continue
role = str(
first_value(segment, "speaker_role", "speakerRole", default="unknown")
or "unknown"
)
lines.append(f"{labels.get(role, '未知说话人')}:{content}")
return "\n".join(lines)
return ""
def _view_call_transcript(self, call_record_id: int, transcript: str) -> None:
dialog = QDialog(self)
dialog.setObjectName("DiagnosisCallTranscriptDialog")
dialog.setWindowTitle(f"面诊对话文字 · 通话记录 #{call_record_id}")
dialog.resize(680, 520)
layout = QVBoxLayout(dialog)
layout.setContentsMargins(20, 18, 20, 18)
layout.setSpacing(12)
title = QLabel("录音转写对话")
title.setObjectName("DiagnosisDailySectionTitle")
layout.addWidget(title)
hint = QLabel("以下内容由语音自动转写,仅作为面诊记录辅助,请由医生核对。")
hint.setObjectName("DiagnosisDialogGuidance")
hint.setWordWrap(True)
layout.addWidget(hint)
content = QPlainTextEdit(dialog)
content.setObjectName("DiagnosisCallTranscriptText")
content.setReadOnly(True)
content.setPlainText(transcript)
layout.addWidget(content, 1)
close_button = QPushButton("关闭")
close_button.setProperty("variant", "primary")
close_button.clicked.connect(dialog.accept)
layout.addWidget(close_button, 0, Qt.AlignmentFlag.AlignRight)
dialog.exec()
def _fill_video(self, rows: Sequence[Any]) -> None:
self._stop_inline_recordings()
matrix: list[tuple[Any, ...]] = []
row_urls: list[list[str]] = []
record_ids: list[int] = []
transcripts: list[str] = []
for row in rows:
raw_urls = first_value(row, "recording_urls_list", "recording_urls", default=[]) or []
if isinstance(raw_urls, str) or not isinstance(raw_urls, Sequence):
@@ -3382,6 +3443,8 @@ class DiagnosisDialog(QDialog):
normalized.append(url)
row_urls.append(normalized)
record_ids.append(_int(first_value(row, "id", "call_record_id"), 0))
transcript = self._call_transcript_text(row)
transcripts.append(transcript)
call_type = _raw_value(row, "call_type_text")
if call_type is _MISSING:
raw_call_type = _raw_value(row, "call_type")
@@ -3398,6 +3461,15 @@ class DiagnosisDialog(QDialog):
3: "未接听",
4: "已取消",
}.get(_int(raw_status, -1), "—")
recording_status = first_value(
row, "recording_status_text", "record_status_text", "record_status"
)
transcript_status = first_value(
row,
"transcription_status_text",
"transcript_status_text",
default="文字已生成" if transcript else "未生成文字",
)
matrix.append(
(
"" if normalized else "暂无录制回放",
@@ -3407,9 +3479,7 @@ class DiagnosisDialog(QDialog):
first_value(row, "room_id", "room_no"),
first_value(row, "duration_text", "duration"),
status,
first_value(
row, "recording_status_text", "record_status_text", "record_status"
),
f"{display_text(recording_status)}\n{display_text(transcript_status)}",
"",
)
)
@@ -3434,6 +3504,20 @@ class DiagnosisDialog(QDialog):
if item is not None:
item.setText("")
call_record_id = record_ids[row_index]
actions: list[QPushButton] = []
transcript = transcripts[row_index]
if transcript and call_record_id > 0:
view_transcript = self._action_button(
"查看文字", f"查看通话记录 #{call_record_id} 的录音转写"
)
view_transcript.setObjectName("DiagnosisVideoTranscriptView")
view_transcript.setProperty("callRecordId", call_record_id)
view_transcript.clicked.connect(
lambda _checked=False, selected=call_record_id, text=transcript: self._view_call_transcript(
selected, text
)
)
actions.append(view_transcript)
if self._editable and self._can_video_upload and call_record_id > 0:
upload = self._action_button(
"追加回放", f"上传并绑定通话记录 #{call_record_id}"
@@ -3452,12 +3536,16 @@ class DiagnosisDialog(QDialog):
selected
)
)
upload_host = QWidget()
upload_host.setObjectName("DiagnosisVideoRowUploadCell")
upload_layout = QVBoxLayout(upload_host)
upload_layout.setContentsMargins(0, 0, 0, 0)
upload_layout.addWidget(upload, 0, Qt.AlignmentFlag.AlignCenter)
table.setCellWidget(row_index, 8, upload_host)
actions.append(upload)
if actions:
action_host = QWidget()
action_host.setObjectName("DiagnosisVideoRowUploadCell")
action_layout = QVBoxLayout(action_host)
action_layout.setContentsMargins(0, 0, 0, 0)
action_layout.setSpacing(2)
for action in actions:
action_layout.addWidget(action, 0, Qt.AlignmentFlag.AlignCenter)
table.setCellWidget(row_index, 8, action_host)
upload_item = table.item(row_index, 8)
if upload_item is not None:
upload_item.setText("")