diff --git a/frontend/src/pages/MatrixBoard.tsx b/frontend/src/pages/MatrixBoard.tsx index b5a0692..23c091a 100644 --- a/frontend/src/pages/MatrixBoard.tsx +++ b/frontend/src/pages/MatrixBoard.tsx @@ -3,33 +3,46 @@ * Y 轴 = 规格型号,X 轴 = 人员 或 工序,单元格 = 该交叉点的在制品设备数 */ import { useEffect, useMemo, useState } from "react"; -import { Radio, Table, DatePicker, Button } from "antd"; +import { Radio, Table, DatePicker } from "antd"; import { Loader2 } from "lucide-react"; -import type { Dayjs } from "dayjs"; +import dayjs, { type Dayjs } from "dayjs"; import { fetchWipMatrix, type WipMatrixRow } from "../services/dashboardApi"; const { RangePicker } = DatePicker; -// 每块最多显示的人员/工序列数,超过则分块垂直排列,避免横向超长 +// 每块最多显示的工序列数,超过则分块垂直排列,避免横向超长 const CHUNK_MATRIX = 6; +// ⏰ 时间筛选(与全局概览一致) +type DateRangeKey = "today" | "7d" | "30d" | "custom"; +function rangeToParams(key: DateRangeKey, customRange: [Dayjs, Dayjs] | null) { + if (key === "custom" && customRange) { + return { + since: customRange[0].startOf("day").toISOString(), + until: customRange[1].endOf("day").toISOString(), + }; + } + const since = dayjs().startOf("day"); + if (key === "7d") return { since: since.subtract(7, "day").toISOString() }; + if (key === "30d") return { since: since.subtract(30, "day").toISOString() }; + return { since: since.toISOString() }; +} + export default function MatrixBoard() { - const [dimension, setDimension] = useState<"assignee" | "task_name">("assignee"); - const [range, setRange] = useState<[Dayjs, Dayjs] | null>(null); + // 固定按工序分布(已取消按人员分布) + const [dateKey, setDateKey] = useState("today"); + const [customRange, setCustomRange] = useState<[Dayjs, Dayjs] | null>(null); const [data, setData] = useState([]); const [loading, setLoading] = useState(false); useEffect(() => { setLoading(true); - fetchWipMatrix( - dimension, - range ? range[0].startOf("day").toISOString() : undefined, - range ? range[1].endOf("day").toISOString() : undefined, - ) + const { since, until } = rangeToParams(dateKey, customRange); + fetchWipMatrix("task_name", since, until) .then(setData) .catch(() => setData([])) .finally(() => setLoading(false)); - }, [dimension, range]); + }, [dateKey, customRange]); // 🔧 核心:扁平数组 → 动态交叉表(规格型号为行、dimension_key 为列) // 列数超过 CHUNK_MATRIX 时分块垂直排列,避免一行十几个人员横向超长 @@ -96,21 +109,31 @@ export default function MatrixBoard() {

📊 WIP 分布矩阵

-

生产分布透视表:规格型号 × {dimension === "assignee" ? "人员" : "工序"} · 含在库/完成

+

生产分布透视表:规格型号 × 工序 · 含在库/完成

-
- + { setDateKey(e.target.value); setCustomRange(null); }} size="small" - value={range as any} - onChange={(dates) => setRange(dates as [Dayjs, Dayjs] | null)} - style={{ width: 240 }} - placeholder={["开始日期", "结束日期"]} - /> - {range && } - setDimension(e.target.value)} optionType="button" buttonStyle="solid"> - 按人员分布 - 按工序分布 + optionType="button" + buttonStyle="solid" + > + 今天 + 近7天 + 近30天 + 自定义 + {dateKey === "custom" && ( + setCustomRange(dates as [Dayjs, Dayjs] | null)} + style={{ width: 240 }} + placeholder={["开始", "结束"]} + /> + )}