import api from "./api"; // ============================================================ // 效能分析看板 — 前后端数据契约类型 + API // 对应后端 app/services/analytics_service.py 的 Pydantic Schema // ============================================================ // ─── 个人能力图谱(单机颗粒度分组柱状图) ────────────────── export interface CapabilityDataPoint { value: number | null; // 该人员在该设备上的总耗时(未触及为 null,真实 0 为 0) spec_model: string; // 规格型号 status: string; // 该设备当前状态 WIP/PENDING/COMPLETED/— first_received_at: string; // 最早接收时间 YYYY-MM-DD HH:mm last_completed_at: string; // 最后完成时间 YYYY-MM-DD HH:mm(无则空串) } export interface CapabilityDevice { product_sn: string; // 身份证 external_serial: string | null; // 产品序列号(业务序列号) spec_model: string; material_name: string; // 物料名称 } export interface CapabilitySeries { name: string; // 人员姓名 assignee_id: string; // 人员ID data: CapabilityDataPoint[]; // 与 categories 严格对齐,未触及设备补 0 } export interface CapabilityResponse { categories: string[]; // X 轴:设备身份证(按时间升序) devices: CapabilityDevice[]; // 与 categories 对齐的设备元数据 series: CapabilitySeries[]; } // ─── 设备流转对比(堆叠柱状) ────────────────────────────── export interface FlowDevice { product_sn: string; external_serial: string | null; material_name: string; spec_model: string; lead_time: number; // 设备生命周期总时长(小时) started_at: string; // 设备最早介入时间(T0),MM-DD HH:mm total_days: number; // 设备生产总天数(自然天) total_workdays: number; // 设备生产总天数(工作日) } // 时间区间:deviceIndex, taskName, isMain, // startNat, endNat, startWork, endWork, durationTotal(自然), durationWork(工作日) export type FlowInterval = [number, string, number, number, number, number, number, number, number]; export interface FlowSeries { name: string; // 人员姓名 data: FlowInterval[]; // 该人员的任务时间区间列表(同一设备可多次出现) } export interface FlowResponse { devices: FlowDevice[]; series: FlowSeries[]; } // ─── 设备备注记录(弹窗下钻) ────────────────────────────── export interface DeviceRecord { task_name: string; // 工序名 assignee_name: string; // 负责人姓名 status: string; // 任务状态 remark: string | null; // 备注 images: string[]; // 图片 URL 列表 created_at: string; // 记录时间 ISO } // ─── 顶部下拉选项 ────────────────────────────────────────── export interface AssigneeOption { id: string; name: string; } export interface SpecModelOption { spec_model: string; material_name: string; } export interface DeviceOption { product_sn: string; external_serial: string | null; material_name: string; spec_model: string; } export interface AnalyticsOptions { assignees: AssigneeOption[]; spec_models: SpecModelOption[]; devices: DeviceOption[]; } // ─── 查询参数 ────────────────────────────────────────────── export interface CapabilityQuery { assignee_ids?: string[]; spec_models?: string[]; since?: string; until?: string; mode?: "natural" | "workdays"; } export interface FlowQuery { product_sns?: string[]; spec_models?: string[]; mode?: "natural" | "workdays"; since?: string; until?: string; } // ============================================================ // API 方法 // ============================================================ export async function fetchCapabilityProfile(query: CapabilityQuery): Promise { const params: Record = {}; if (query.assignee_ids?.length) params.assignee_ids = query.assignee_ids.join(","); if (query.spec_models?.length) params.spec_models = query.spec_models.join(","); if (query.since) params.since = query.since; if (query.until) params.until = query.until; if (query.mode) params.mode = query.mode; const { data } = await api.get("/analytics/capability", { params }); return data; } export async function fetchFlowData(query: FlowQuery): Promise { const params: Record = {}; if (query.product_sns?.length) params.product_sns = query.product_sns.join(","); if (query.spec_models?.length) params.spec_models = query.spec_models.join(","); if (query.mode) params.mode = query.mode; if (query.since) params.since = query.since; if (query.until) params.until = query.until; const { data } = await api.get("/analytics/flow", { params }); return data; } export async function fetchDeviceRecords(product_sn: string, assigneeIds?: string[]): Promise { const params: Record = { product_sn }; if (assigneeIds?.length) params.assignee_ids = assigneeIds.join(","); const { data } = await api.get("/analytics/device-records", { params }); return data; } export async function fetchAnalyticsOptions(assigneeIds?: string[], specModels?: string[]): Promise { const params: Record = {}; if (assigneeIds?.length) params.assignee_ids = assigneeIds.join(","); if (specModels?.length) params.spec_models = specModels.join(","); const { data } = await api.get("/analytics/options", { params }); return data; }