factory/mcp_server/tools/batch_stats.py

105 lines
3.2 KiB
Python

from typing import Any
from django.db.models import Q
from apps.wpm.models import BatchLog, BatchSt
from mcp_server.context import authenticated_factory_user
from mcp_server.tools.common import json_safe_result, validate_result_size
def _base_queryset():
return BatchSt.objects.select_related("material_start")
def _batch_summary(batch_stat: BatchSt) -> dict[str, Any]:
material = batch_stat.material_start
return {
"id": str(batch_stat.id),
"batch": batch_stat.batch,
"version": batch_stat.version,
"zt_batch": batch_stat.zt_batch,
"first_time": batch_stat.first_time,
"last_time": batch_stat.last_time,
"material_start": (
{
"id": str(material.id),
"name": material.name,
"model": material.model,
"specification": material.specification,
}
if material
else None
),
"data_keys": sorted((batch_stat.data or {}).keys()),
"update_time": batch_stat.update_time,
}
def search_batch_stats(
query: str = "",
zt_batch: str = "",
material_id: str | None = None,
version: int | None = 1,
limit: int = 20,
) -> dict[str, Any]:
"""搜索批次统计;摘要仅返回数据分组名称,不返回完整统计数据。"""
authenticated_factory_user()
safe_limit = max(1, min(limit, 100))
queryset = _base_queryset()
if query.strip():
queryset = queryset.filter(batch__icontains=query.strip())
if zt_batch.strip():
queryset = queryset.filter(zt_batch=zt_batch.strip())
if material_id:
queryset = queryset.filter(material_start_id=material_id)
if version is not None:
queryset = queryset.filter(version=version)
items = [
_batch_summary(item)
for item in queryset.order_by("batch", "version")[:safe_limit]
]
result = json_safe_result({"items": items, "limit": safe_limit})
validate_result_size(result)
return result
def get_batch_stat(
batch: str,
version: int = 1,
include_relations: bool = True,
) -> dict[str, Any]:
"""读取指定批次版本的完整统计数据,并可附带直接拆合批关系。"""
authenticated_factory_user()
try:
batch_stat = _base_queryset().get(batch=batch, version=version)
except BatchSt.DoesNotExist as exc:
raise ValueError(f"未找到批次统计:{batch} v{version}") from exc
result = _batch_summary(batch_stat)
result["data"] = batch_stat.data
if include_relations:
result["relations"] = list(
BatchLog.objects.filter(Q(source=batch_stat) | Q(target=batch_stat))
.select_related("source", "target")
.values(
"id",
"relation_type",
"source_id",
"source__batch",
"source__version",
"target_id",
"target__batch",
"target__version",
"handover_id",
"mlog_id",
)
)
result = json_safe_result(result)
validate_result_size(result)
return result
def register_batch_stat_tools(server) -> None:
server.tool()(search_batch_stats)
server.tool()(get_batch_stat)