fix: 效能分析flow时间筛选改为设备级(该时间有活动即入选),任务完整返回不切片
This commit is contained in:
@ -342,25 +342,10 @@ async def get_flow_compare(
|
|||||||
if not product_rows:
|
if not product_rows:
|
||||||
return FlowResponse(devices=[], series=[])
|
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}
|
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]
|
product_ids = [r[0] for r in product_rows]
|
||||||
|
|
||||||
# ── 这些设备的全部任务(含工序名,用于区间图) ──
|
# ── 候选设备的全部任务(含工序名,用于区间图) ──
|
||||||
task_rows = (await db.execute(
|
task_rows = (await db.execute(
|
||||||
select(
|
select(
|
||||||
Task.product_id, Task.assignee_id, Task.task_name,
|
Task.product_id, Task.assignee_id, Task.task_name,
|
||||||
@ -374,25 +359,57 @@ async def get_flow_compare(
|
|||||||
)
|
)
|
||||||
)).all()
|
)).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] = []
|
intervals: list[dict] = []
|
||||||
t0_by_device: dict[int, datetime] = {}
|
t0_by_device: dict[int, datetime] = {}
|
||||||
max_end_by_device: dict[int, datetime] = {}
|
max_end_by_device: dict[int, datetime] = {}
|
||||||
for row in task_rows:
|
for row in task_rows:
|
||||||
pid, assignee_id, task_name, received_at, created_at, completed_at, task_type = row
|
pid, assignee_id, task_name, received_at, created_at, completed_at, task_type = row
|
||||||
sn = id_to_sn.get(pid)
|
if pid not in kept_ids:
|
||||||
if sn is None or sn not in sn_to_index:
|
|
||||||
continue
|
continue
|
||||||
|
sn = id_to_sn[pid]
|
||||||
idx = sn_to_index[sn]
|
idx = sn_to_index[sn]
|
||||||
start = _to_bj(received_at or created_at)
|
start = _to_bj(received_at or created_at)
|
||||||
end = _to_bj(completed_at) if completed_at else now
|
end = _to_bj(completed_at) if completed_at else now
|
||||||
if start is None:
|
if start is None:
|
||||||
continue
|
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
|
is_main = 0 if task_type == "SPAWN" else 1
|
||||||
intervals.append({
|
intervals.append({
|
||||||
"idx": idx,
|
"idx": idx,
|
||||||
|
|||||||
Reference in New Issue
Block a user