feat: 消费停录汇总与查结果同口径,并更新分类与 TSV
- 停录时由 details 经 build_consumption_summary 写 TSV/终端汇总,移除 consumption_log_totals 与时间窗累加 - 更新 consumable_classifier 权重、YAML 标签与 consumable_vision_algorithm - 扩展 consumption TSV 相关测试与配置注释 Made-with: Cursor
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
- 置信度 ≥ 自动阈值但 Top1 不在候选内 → 视 voice_confirmation_enabled 入 pending。
|
||||
- 中等置信度 → 入 pending(若有可展示候选项)。
|
||||
|
||||
需医生确认时:消耗 TSV / 内存明细记「待确认」(不写模型 top1 商品名);语音确认后再落最终耗材并更新汇总。
|
||||
需医生确认时:消耗 TSV / 内存明细记「待确认」(不写模型 top1 商品名);语音确认后**替换**该条 TSV 为最终耗材。停录时 TSV/终端汇总与查结果 API 同口径,由 details 经 ``build_consumption_summary`` 生成。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -85,7 +85,6 @@ class VisionClassificationHandler:
|
||||
camera_id=camera_id,
|
||||
wall_start_epoch=ready.wall_lo,
|
||||
wall_end_epoch=ready.wall_hi,
|
||||
running_totals=state.consumption_log_totals,
|
||||
)
|
||||
|
||||
async def handle(
|
||||
@@ -99,7 +98,8 @@ class VisionClassificationHandler:
|
||||
) -> None:
|
||||
conf = cls_res.confidence
|
||||
label = (cls_res.label or "").strip()
|
||||
item_id = resolve_consumption_item_id(label, "", state.name_to_code)
|
||||
t1_pid = (ready.best.t1_pid if ready is not None else "")
|
||||
item_id = resolve_consumption_item_id(label, t1_pid, state.name_to_code)
|
||||
voice_floor = self._s.video_voice_confirm_min_confidence
|
||||
if conf < voice_floor:
|
||||
return
|
||||
|
||||
@@ -29,6 +29,7 @@ from app.services.video.session_registry import (
|
||||
)
|
||||
from app.services.video.stream_worker import CameraStreamWorker, redact_rtsp_url
|
||||
from app.services.video.types import VideoBackendKind
|
||||
from app.schemas import SurgeryConsumptionDetail, build_consumption_summary
|
||||
from app.services.consumption_tsv_log import (
|
||||
append_consumption_log_summary,
|
||||
init_consumption_log_file,
|
||||
@@ -214,11 +215,21 @@ class CameraSessionManager:
|
||||
if isinstance(res, BaseException):
|
||||
logger.warning("surgery task finished with error: {}", res)
|
||||
|
||||
totals = dict(run.state.consumption_log_totals)
|
||||
details = list(run.state.details)
|
||||
detail_rows = [
|
||||
SurgeryConsumptionDetail(
|
||||
item_id=r.item_id,
|
||||
item_name=r.item_name,
|
||||
qty=r.qty,
|
||||
doctor_id=r.doctor_id,
|
||||
timestamp=r.timestamp,
|
||||
)
|
||||
for r in details
|
||||
]
|
||||
summ = build_consumption_summary(detail_rows)
|
||||
totals = {s.item_id: (s.item_name, s.total_quantity) for s in summ}
|
||||
append_consumption_log_summary(surgery_id, totals)
|
||||
print_consumption_summary_markdown(totals)
|
||||
|
||||
details = list(run.state.details)
|
||||
await self._archive.persist_or_archive(surgery_id, details)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@@ -22,8 +22,7 @@ from app.services.consumable_vision_algorithm import (
|
||||
_norm_product_name,
|
||||
)
|
||||
from app.services.consumption_tsv_log import (
|
||||
append_consumption_voice_resolution_line,
|
||||
resolve_consumption_ids,
|
||||
replace_pending_line_with_voice_resolution,
|
||||
resolve_consumption_item_id,
|
||||
)
|
||||
from app.services.voice_confirm import build_prompt_text
|
||||
@@ -74,8 +73,6 @@ class SurgerySessionState:
|
||||
last_asr_text: str | None = None
|
||||
#: 最近一次语音确认错误说明(ASR/解析失败等)。
|
||||
last_voice_error: str | None = None
|
||||
#: 视觉时间窗落盘用量累计,供停录时写汇总(item_id -> 首次名称, 次数)。
|
||||
consumption_log_totals: dict[str, tuple[str, int]] = field(default_factory=dict)
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -281,6 +278,7 @@ class SurgerySessionRegistry:
|
||||
self._finalize_voice_confirmed_consumption_log(
|
||||
state=st,
|
||||
surgery_id=surgery_id,
|
||||
confirmation_id=confirmation_id,
|
||||
chosen_label=label,
|
||||
)
|
||||
try:
|
||||
@@ -295,20 +293,16 @@ class SurgerySessionRegistry:
|
||||
*,
|
||||
state: SurgerySessionState,
|
||||
surgery_id: str,
|
||||
confirmation_id: str,
|
||||
chosen_label: str,
|
||||
) -> None:
|
||||
"""待确认流程在语音落锤后:汇总 +1 最终耗材,并追加 TSV 正式行。"""
|
||||
"""待确认流程在语音落锤后:将 TSV 中原 pending 行替换为最终真值。停录汇总与 HTTP 一致,由 details 经 ``build_consumption_summary`` 得到。"""
|
||||
cl = (chosen_label or "").strip()
|
||||
if not cl:
|
||||
return
|
||||
_, key_chosen = resolve_consumption_ids(cl, "", state.name_to_code)
|
||||
tot = state.consumption_log_totals
|
||||
if key_chosen not in tot:
|
||||
tot[key_chosen] = (cl, 0)
|
||||
nm, q = tot[key_chosen]
|
||||
tot[key_chosen] = (nm, q + 1)
|
||||
append_consumption_voice_resolution_line(
|
||||
replace_pending_line_with_voice_resolution(
|
||||
surgery_id=surgery_id,
|
||||
confirmation_id=confirmation_id,
|
||||
name_to_code=state.name_to_code,
|
||||
chosen_label=cl,
|
||||
doctor_id=self._s.video_voice_confirm_doctor_id,
|
||||
|
||||
Reference in New Issue
Block a user