feat: 管理层数据大屏(后端聚合接口 + 前端全屏页面)
PC 管理端新增独立全屏数据大屏,供管理层查看直通率/产量趋势/不良分布, 替代原 AdminDashboard 上零散的手工下钻。 后端: - endpoints/screen.py + services/screen_service.py: 大屏聚合接口 (复用 lifecycle 的售后工序归一,保证统计口径与展示一致) - router.py: 注册 screen_router 前端: - pages/admin/ScreenDashboard.tsx: 全屏大屏页(自带鉴权守卫,无侧边栏) - services/screenApi.ts: 大屏数据接口封装 - components/admin/UserOperationDetailDrawer.tsx: 人员操作明细抽屉, 由 AdminDashboard 的原生 state 抽成独立组件(含命令式 handle) - AdminDashboard.tsx: 改为使用该抽屉组件,移除内联的下钻状态 - MatrixBoard.tsx / App.tsx / AdminLayout.tsx: 挂载路由与导航入口 - BaseEChart.tsx: 注册 GaugeChart 与 GraphicComponent (graphic 需显式注册,否则饼图中心文字静默不渲染)
This commit is contained in:
62
frontend/src/services/screenApi.ts
Normal file
62
frontend/src/services/screenApi.ts
Normal file
@ -0,0 +1,62 @@
|
||||
/** 管理层数据大屏 — 前后端数据契约类型 + API
|
||||
* 对应后端 app/services/screen_service.py 的 Pydantic Schema
|
||||
*/
|
||||
import api from "./api";
|
||||
|
||||
// ─── 当月吞吐(顶部数字卡) ────────────────────────────────
|
||||
export interface MonthlyMetrics {
|
||||
month: string; // "2026-09"
|
||||
month_start: string; // "2026-09-01"(北京时间)
|
||||
month_production: number; // 本月有流转记录或新建的生产态设备数
|
||||
month_inbound: number; // 本月扫码入库数
|
||||
month_outbound: number; // 本月扫码出库数
|
||||
month_returned: number; // 本月进入售后/回流状态的设备数
|
||||
}
|
||||
|
||||
// ─── 工序积压分布(柱状图) ────────────────────────────────
|
||||
export interface WipStage {
|
||||
stage: string;
|
||||
phase: "PRODUCTION" | "AFTER_SALES";
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface WipDistributionResponse {
|
||||
total: number;
|
||||
items: WipStage[];
|
||||
}
|
||||
|
||||
// ─── 系统使用活跃度 ────────────────────────────────────────
|
||||
export interface ActiveUser {
|
||||
user_id: string;
|
||||
user_name: string;
|
||||
receive_count: number;
|
||||
transfer_count: number;
|
||||
record_count: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface ActiveUsersResponse {
|
||||
month: string;
|
||||
items: ActiveUser[];
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// API 方法
|
||||
// ============================================================
|
||||
|
||||
export async function fetchMonthlyMetrics(): Promise<MonthlyMetrics> {
|
||||
const { data } = await api.get<MonthlyMetrics>("/screen/monthly-metrics");
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function fetchWipDistribution(): Promise<WipDistributionResponse> {
|
||||
const { data } = await api.get<WipDistributionResponse>("/screen/wip-distribution");
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function fetchActiveUsers(topN = 5): Promise<ActiveUsersResponse> {
|
||||
const { data } = await api.get<ActiveUsersResponse>("/screen/active-users", {
|
||||
params: { top_n: topN },
|
||||
});
|
||||
return data;
|
||||
}
|
||||
Reference in New Issue
Block a user