fix: 完善报工归属输出安全性

This commit is contained in:
souplearn
2026-07-25 04:39:25 +08:00
parent b0cb217ce3
commit bb9ce5601c
4 changed files with 239 additions and 10 deletions
+5
View File
@@ -192,6 +192,7 @@ def _dashboard_rows(
"product_name": item.product_name,
"process_name": process_name,
"report_ids": set(),
"source_report_dates": set(),
"effective_minutes": 0.0,
"shift_day_minutes": 0.0,
"shift_overtime_minutes": 0.0,
@@ -230,6 +231,7 @@ def _dashboard_rows(
allocated_minutes = 0 if is_cleaning else (as_float(item.allocated_minutes) or fallback_minutes)
expected_workload = allocated_minutes * 60 / standard_beat if standard_beat > 0 else 0
group["report_ids"].add(report.id)
group["source_report_dates"].add(report.report_date)
group["effective_minutes"] += allocated_minutes
group["expected_workload"] += expected_workload
group["shift_day_minutes"] += as_float(getattr(item, "_shift_day_minutes", 0))
@@ -277,11 +279,14 @@ def _dashboard_rows(
"overtime": group["shift_overtime_minutes"],
"night": group["shift_night_minutes"],
}
source_report_dates = sorted(group["source_report_dates"])
rows.append(
DashboardRow(
id=group["id"],
attendance_point_name=group["attendance_point_name"],
report_date=group["report_date"],
source_report_date=source_report_dates[-1] if source_report_dates else group["report_date"],
source_report_dates=source_report_dates,
employee_phone=group["employee_phone"],
employee_name=group["employee_name"],
worker_type=group["worker_type"],
+31 -4
View File
@@ -1,7 +1,9 @@
from datetime import datetime
from datetime import date, datetime
from sqlalchemy import select
from sqlalchemy import inspect, select
from sqlalchemy.exc import NoInspectionAvailable
from sqlalchemy.orm import Session
from sqlalchemy.orm.attributes import NO_VALUE
from app.models import (
AttendancePoint,
@@ -358,7 +360,31 @@ def report_allocation_out(row) -> ReportAllocationOut:
)
def _loaded_relationship_rows(obj, relationship_name: str) -> list:
try:
state = inspect(obj)
except NoInspectionAvailable:
return list(getattr(obj, relationship_name, []) or [])
if relationship_name not in state.attrs:
return list(getattr(obj, relationship_name, []) or [])
relationship_state = state.attrs[relationship_name]
if relationship_state.loaded_value is NO_VALUE:
return []
return list(relationship_state.value or [])
def _sorted_allocation_rows(rows) -> list:
return sorted(
list(rows or []),
key=lambda row: (
getattr(row, "allocation_date", None) or date.min,
getattr(row, "id", None) or 0,
),
)
def report_item_out(item: ProductionReportItem, corrections: dict | None = None) -> ReportItemOut:
allocation_rows = _sorted_allocation_rows(_loaded_relationship_rows(item, "allocations"))
return ReportItemOut(
id=item.id,
attendance_point_name=item.attendance_point_name,
@@ -384,7 +410,7 @@ def report_item_out(item: ProductionReportItem, corrections: dict | None = None)
is_continuous_die=is_continuous_die_item(item),
is_multi_person=is_multi_person_item(item),
remark=item.remark,
allocations=[report_allocation_out(row) for row in getattr(item, "allocations", []) or []],
allocations=[report_allocation_out(row) for row in allocation_rows],
corrections=corrections or {},
)
@@ -423,6 +449,7 @@ def _cleaning_report_metrics(report: ProductionReport) -> dict:
def report_out(report: ProductionReport, schedule: WorkScheduleConfig | None = None) -> ReportOut:
allocation_rows = _sorted_allocation_rows(_loaded_relationship_rows(report, "allocations"))
is_cleaning_report = _report_is_cleaning(report)
calculated_metrics = (
_cleaning_report_metrics(report)
@@ -504,6 +531,6 @@ def report_out(report: ProductionReport, schedule: WorkScheduleConfig | None = N
if is_cleaning_report
else ("处理杂活已提交,等待管理员审核" if _report_is_misc_only(report) else build_result_text(metrics))
),
allocation_summary_text=allocation_summary_text(list(getattr(report, "allocations", []) or [])),
allocation_summary_text=allocation_summary_text(allocation_rows),
corrections=report_corrections,
)