fix: 效能分析flow时间筛选改为设备级(该时间有活动即入选),任务完整返回不切片
This commit is contained in:
@ -342,25 +342,10 @@ async def get_flow_compare(
|
||||
if not product_rows:
|
||||
return FlowResponse(devices=[], series=[])
|
||||
|
||||
devices = [
|
||||
FlowDevice(
|
||||
product_sn=r[1], external_serial=r[2],
|
||||
material_name=r[3] or "", spec_model=r[4] or "",
|
||||
lead_time=0.0,
|
||||
started_at="",
|
||||
)
|
||||
for r in product_rows
|
||||
]
|
||||
# 显式传入身份证时按输入顺序排列
|
||||
if product_sns:
|
||||
order = {sn: i for i, sn in enumerate(product_sns)}
|
||||
devices.sort(key=lambda d: order.get(d.product_sn, len(order)))
|
||||
|
||||
id_to_sn = {r[0]: r[1] for r in product_rows}
|
||||
sn_to_index = {d.product_sn: i for i, d in enumerate(devices)}
|
||||
product_ids = [r[0] for r in product_rows]
|
||||
|
||||
# ── 这些设备的全部任务(含工序名,用于区间图) ──
|
||||
# ── 候选设备的全部任务(含工序名,用于区间图) ──
|
||||
task_rows = (await db.execute(
|
||||
select(
|
||||
Task.product_id, Task.assignee_id, Task.task_name,
|
||||
@ -374,25 +359,57 @@ async def get_flow_compare(
|
||||
)
|
||||
)).all()
|
||||
|
||||
# ── 解析为区间记录,并计算每台设备的 T0(最早)与 max_end(最晚) ──
|
||||
# ── 设备级时间筛选 ──
|
||||
# 语义:时间筛选 = "在该时间有活动的设备",而非"把任务切片只保留该时间"。
|
||||
# 设备一旦入选,其任务必须完整返回(完整生命周期),绝不因设备在筛选中无新动作
|
||||
# 而把它的历史任务清空。
|
||||
if since is not None or until is not None:
|
||||
active_pids: set = set()
|
||||
for row in task_rows:
|
||||
pid = row[0]
|
||||
start = _to_bj(row[3] or row[4])
|
||||
end = _to_bj(row[5]) if row[5] else now
|
||||
if start is None:
|
||||
continue
|
||||
if since is not None and end < since:
|
||||
continue
|
||||
if until is not None and start > until:
|
||||
continue
|
||||
active_pids.add(pid)
|
||||
product_rows = [r for r in product_rows if r[0] in active_pids]
|
||||
if not product_rows:
|
||||
return FlowResponse(devices=[], series=[])
|
||||
|
||||
# 显式传入身份证时按输入顺序排列
|
||||
if product_sns:
|
||||
order = {sn: i for i, sn in enumerate(product_sns)}
|
||||
product_rows.sort(key=lambda r: order.get(r[1], len(order)))
|
||||
devices = [
|
||||
FlowDevice(
|
||||
product_sn=r[1], external_serial=r[2],
|
||||
material_name=r[3] or "", spec_model=r[4] or "",
|
||||
lead_time=0.0,
|
||||
started_at="",
|
||||
)
|
||||
for r in product_rows
|
||||
]
|
||||
sn_to_index = {d.product_sn: i for i, d in enumerate(devices)}
|
||||
kept_ids = {r[0] for r in product_rows}
|
||||
|
||||
# ── 解析为区间记录(完整生命周期,不再按时间切片) ──
|
||||
intervals: list[dict] = []
|
||||
t0_by_device: dict[int, datetime] = {}
|
||||
max_end_by_device: dict[int, datetime] = {}
|
||||
for row in task_rows:
|
||||
pid, assignee_id, task_name, received_at, created_at, completed_at, task_type = row
|
||||
sn = id_to_sn.get(pid)
|
||||
if sn is None or sn not in sn_to_index:
|
||||
if pid not in kept_ids:
|
||||
continue
|
||||
sn = id_to_sn[pid]
|
||||
idx = sn_to_index[sn]
|
||||
start = _to_bj(received_at or created_at)
|
||||
end = _to_bj(completed_at) if completed_at else now
|
||||
if start is None:
|
||||
continue
|
||||
# 时间筛选:任务区间与 [since, until] 有交集
|
||||
if since is not None and end is not None and end < since:
|
||||
continue
|
||||
if until is not None and start is not None and start > until:
|
||||
continue
|
||||
is_main = 0 if task_type == "SPAWN" else 1
|
||||
intervals.append({
|
||||
"idx": idx,
|
||||
|
||||
Reference in New Issue
Block a user