Files
track/frontend/src/services/analyticsApi.ts

153 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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; // 设备最早介入时间T0MM-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<CapabilityResponse> {
const params: Record<string, string> = {};
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<CapabilityResponse>("/analytics/capability", { params });
return data;
}
export async function fetchFlowData(query: FlowQuery): Promise<FlowResponse> {
const params: Record<string, string> = {};
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<FlowResponse>("/analytics/flow", { params });
return data;
}
export async function fetchDeviceRecords(product_sn: string, assigneeIds?: string[]): Promise<DeviceRecord[]> {
const params: Record<string, string> = { product_sn };
if (assigneeIds?.length) params.assignee_ids = assigneeIds.join(",");
const { data } = await api.get<DeviceRecord[]>("/analytics/device-records", { params });
return data;
}
export async function fetchAnalyticsOptions(assigneeIds?: string[], specModels?: string[]): Promise<AnalyticsOptions> {
const params: Record<string, string> = {};
if (assigneeIds?.length) params.assignee_ids = assigneeIds.join(",");
if (specModels?.length) params.spec_models = specModels.join(",");
const { data } = await api.get<AnalyticsOptions>("/analytics/options", { params });
return data;
}