协议样本、生产产出和盘点明细按行更新并保留原 id;补齐存储证明质检预填、离职人员显示名,以及样本采集通知模板字段。 Co-authored-by: Cursor <cursoragent@cursor.com>
207 lines
6.8 KiB
Python
207 lines
6.8 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List, Optional, Tuple
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.crud import qc_item_param as param_svc
|
|
from app.crud.child_row_sync import sync_child_rows
|
|
from app.crud.qc_task import get_task
|
|
from app.models.models import BizQcWorkOrderLabItem, BizQcWorkOrderThirdItem
|
|
from app.models.qc_param import BizQcTaskResult
|
|
|
|
|
|
def _row_to_dict(r: BizQcTaskResult) -> Dict[str, Any]:
|
|
return {
|
|
"id": r.id,
|
|
"paramId": r.param_id or "",
|
|
"paramName": r.param_name,
|
|
"paramCode": r.param_code or "",
|
|
"paramUnit": r.param_unit or "",
|
|
"paramType": r.param_type or "text",
|
|
"paramValue": r.param_value or "",
|
|
}
|
|
|
|
|
|
def _list_saved_results_by_task(
|
|
db: Session, task_id: str, tenant_no: str, *, user_info=None
|
|
) -> List[Dict[str, Any]]:
|
|
q = db.query(BizQcTaskResult).filter(
|
|
BizQcTaskResult.task_id == task_id,
|
|
BizQcTaskResult.tenant_no == tenant_no,
|
|
BizQcTaskResult.del_flag == 0,
|
|
)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q = apply_data_scope(q, BizQcTaskResult, user_info, db, tenant_no)
|
|
rows = q.order_by(BizQcTaskResult.create_time.asc()).all()
|
|
return [_row_to_dict(r) for r in rows]
|
|
|
|
|
|
def _resolve_task_item_ref(db: Session, task) -> Tuple[Optional[str], Optional[str]]:
|
|
"""返回 (item_source, item_id) 供 biz_qc_item_param 查询。"""
|
|
if task.task_type == "sysz":
|
|
line = (
|
|
db.query(BizQcWorkOrderLabItem)
|
|
.filter(
|
|
BizQcWorkOrderLabItem.id == task.source_line_id,
|
|
BizQcWorkOrderLabItem.del_flag == 0,
|
|
)
|
|
.first()
|
|
)
|
|
if line:
|
|
return "lab", line.lab_test_item_id
|
|
elif task.task_type == "dsfjc":
|
|
line = (
|
|
db.query(BizQcWorkOrderThirdItem)
|
|
.filter(
|
|
BizQcWorkOrderThirdItem.id == task.source_line_id,
|
|
BizQcWorkOrderThirdItem.del_flag == 0,
|
|
)
|
|
.first()
|
|
)
|
|
if line:
|
|
return "third_party", line.third_party_item_id
|
|
return None, None
|
|
|
|
|
|
def _merge_saved_into_template(
|
|
templates: List[Dict[str, Any]], saved: List[Dict[str, Any]]
|
|
) -> List[Dict[str, Any]]:
|
|
by_id = {s["paramId"]: s for s in saved if s.get("paramId")}
|
|
by_code = {s["paramCode"]: s for s in saved if s.get("paramCode")}
|
|
out: List[Dict[str, Any]] = []
|
|
for p in templates:
|
|
pid = p.get("id") or ""
|
|
code = p.get("paramCode") or ""
|
|
hit = by_id.get(pid) or (by_code.get(code) if code else None)
|
|
saved_value = (hit.get("paramValue") if hit else "") or ""
|
|
default_value = (p.get("defaultValue") or "").strip()
|
|
param_type = p.get("paramType", "text")
|
|
if not saved_value and param_type == "select" and default_value:
|
|
saved_value = default_value
|
|
out.append(
|
|
{
|
|
"paramId": pid,
|
|
"paramName": p.get("paramName", ""),
|
|
"paramCode": code,
|
|
"paramUnit": p.get("paramUnit", ""),
|
|
"paramType": param_type,
|
|
"options": p.get("options", ""),
|
|
"defaultValue": default_value,
|
|
"paramValue": saved_value,
|
|
"requiredFlag": p.get("requiredFlag", "0"),
|
|
}
|
|
)
|
|
return out
|
|
|
|
|
|
def list_saved_results_by_task_ids(
|
|
db: Session, task_ids: List[str], tenant_no: str
|
|
) -> Dict[str, List[Dict[str, Any]]]:
|
|
"""按任务 ID 批量返回已保存检测参数(只读展示用,不合并模板空项)。"""
|
|
ids = list({(x or "").strip() for x in task_ids if (x or "").strip()})
|
|
if not ids or not tenant_no:
|
|
return {}
|
|
rows = (
|
|
db.query(BizQcTaskResult)
|
|
.filter(
|
|
BizQcTaskResult.task_id.in_(ids),
|
|
BizQcTaskResult.tenant_no == tenant_no,
|
|
BizQcTaskResult.del_flag == 0,
|
|
)
|
|
.order_by(BizQcTaskResult.create_time.asc())
|
|
.all()
|
|
)
|
|
grouped: Dict[str, List[Dict[str, Any]]] = {i: [] for i in ids}
|
|
for r in rows:
|
|
tid = (r.task_id or "").strip()
|
|
if tid in grouped:
|
|
grouped[tid].append(_row_to_dict(r))
|
|
return grouped
|
|
|
|
|
|
def list_results_by_task(
|
|
db: Session, task_id: str, tenant_no: str, *, user_info=None
|
|
) -> List[Dict[str, Any]]:
|
|
"""返回任务结果填写表单:项目参数模板 + 已保存值(无模板时仅返回已保存记录)。"""
|
|
saved = _list_saved_results_by_task(db, task_id, tenant_no, user_info=user_info)
|
|
task = get_task(db, task_id, tenant_no=tenant_no)
|
|
if not task:
|
|
return saved
|
|
item_source, item_id = _resolve_task_item_ref(db, task)
|
|
if not item_source or not item_id:
|
|
return saved
|
|
templates = param_svc.list_params_by_item(db, item_source, item_id, tenant_no)
|
|
if not templates:
|
|
return saved
|
|
return _merge_saved_into_template(templates, saved)
|
|
|
|
|
|
def save_results_for_task(
|
|
db: Session,
|
|
task_id: str,
|
|
results: List[Dict[str, Any]],
|
|
tenant_no: str,
|
|
user_id: Optional[str] = None,
|
|
*,
|
|
commit: bool = True,
|
|
) -> List[Dict[str, Any]]:
|
|
task = get_task(db, task_id, tenant_no=tenant_no)
|
|
if not task:
|
|
raise ValueError("任务不存在")
|
|
now = datetime.now()
|
|
|
|
def _result_key(item: Dict[str, Any]) -> str:
|
|
param_id = (item.get("paramId") or "").strip()
|
|
if param_id:
|
|
return "id:" + param_id
|
|
return "code:" + (item.get("paramCode") or "").strip()
|
|
|
|
def build_row(row_id):
|
|
return BizQcTaskResult(
|
|
id=row_id,
|
|
task_id=task_id,
|
|
param_name="",
|
|
param_type="text",
|
|
tenant_no=tenant_no,
|
|
create_by=user_id,
|
|
create_dept_id="",
|
|
create_time=now,
|
|
)
|
|
|
|
def apply_row(row, res, _idx, _now):
|
|
row.param_id = res.get("paramId") or None
|
|
row.param_name = res.get("paramName", "")
|
|
row.param_code = res.get("paramCode") or None
|
|
row.param_unit = res.get("paramUnit") or None
|
|
row.param_type = res.get("paramType", "text")
|
|
row.param_value = res.get("paramValue") or None
|
|
|
|
sync_child_rows(
|
|
db,
|
|
BizQcTaskResult,
|
|
parent_attr="task_id",
|
|
parent_id=task_id,
|
|
tenant_no=tenant_no,
|
|
items=results,
|
|
user_id=user_id,
|
|
now=now,
|
|
build_row=build_row,
|
|
apply_fields=apply_row,
|
|
natural_key=_result_key,
|
|
row_natural_key=lambda row: (
|
|
"id:" + row.param_id.strip()
|
|
if (row.param_id or "").strip()
|
|
else "code:" + (row.param_code or "").strip()
|
|
),
|
|
duplicate_message="检测结果重复",
|
|
foreign_message="检测结果不属于当前任务",
|
|
)
|
|
if commit:
|
|
db.commit()
|
|
else:
|
|
db.flush()
|
|
return list_results_by_task(db, task_id, tenant_no)
|