refactor(透视表): 取消按人员分布,时间筛选对齐全局概览
- 移除按人员/按工序切换,固定按工序分布 - 时间筛选改为与全局概览一致: 今天/近7天/近30天/自定义(Radio+RangePicker)
This commit is contained in:
@ -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<DateRangeKey>("today");
|
||||
const [customRange, setCustomRange] = useState<[Dayjs, Dayjs] | null>(null);
|
||||
const [data, setData] = useState<WipMatrixRow[]>([]);
|
||||
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() {
|
||||
<div className="mb-4 flex flex-wrap items-center justify-between gap-3">
|
||||
<div>
|
||||
<h2 className="text-xl font-bold text-gray-800">📊 WIP 分布矩阵</h2>
|
||||
<p className="mt-1 text-sm text-gray-500">生产分布透视表:规格型号 × {dimension === "assignee" ? "人员" : "工序"} · 含在库/完成</p>
|
||||
<p className="mt-1 text-sm text-gray-500">生产分布透视表:规格型号 × 工序 · 含在库/完成</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<RangePicker
|
||||
{/* ⏰ 时间筛选(与全局概览一致) */}
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Radio.Group
|
||||
value={dateKey}
|
||||
onChange={e => { 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 && <Button size="small" onClick={() => setRange(null)}>全部</Button>}
|
||||
<Radio.Group value={dimension} onChange={(e) => setDimension(e.target.value)} optionType="button" buttonStyle="solid">
|
||||
<Radio.Button value="assignee">按人员分布</Radio.Button>
|
||||
<Radio.Button value="task_name">按工序分布</Radio.Button>
|
||||
optionType="button"
|
||||
buttonStyle="solid"
|
||||
>
|
||||
<Radio.Button value="today">今天</Radio.Button>
|
||||
<Radio.Button value="7d">近7天</Radio.Button>
|
||||
<Radio.Button value="30d">近30天</Radio.Button>
|
||||
<Radio.Button value="custom">自定义</Radio.Button>
|
||||
</Radio.Group>
|
||||
{dateKey === "custom" && (
|
||||
<RangePicker
|
||||
size="small"
|
||||
value={customRange as any}
|
||||
onChange={dates => setCustomRange(dates as [Dayjs, Dayjs] | null)}
|
||||
style={{ width: 240 }}
|
||||
placeholder={["开始", "结束"]}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user