feat: 看板在制品点击跳转任务全景并自动展开流转树

Dashboard: WipRow 点击改为 nav(/admin/tasks?sn=xxx)
AdminTasksPage: 读取 ?sn= 参数 → 自动搜索 → 产品加载后自动展开流转树
This commit is contained in:
2026-08-12 15:00:37 +08:00
parent fd289db0fc
commit 9b59521746
2 changed files with 20 additions and 2 deletions

View File

@ -81,7 +81,7 @@ function WipRow({ t }: { t: WipTask }) {
const nav = useNavigate();
const handleClick = () => {
if (t.product_sn) {
nav(`/scan?sn=${t.product_sn}`);
nav(`/admin/tasks?sn=${t.product_sn}`);
}
};
return (

View File

@ -1,5 +1,6 @@
/** 任务全景 Dashboard — 按订单聚合 + 关键词搜索 + 状态筛选 */
import { useState, useEffect, useMemo, useCallback } from "react";
import { useSearchParams } from "react-router-dom";
import {
Search, Loader2, Package, ChevronDown, ChevronRight,
Warehouse, GitBranch, X,
@ -35,6 +36,7 @@ interface OrderGroup {
export default function AdminTasksPage() {
const { toast } = useToast();
const { user: currentUser } = useAuth();
const [searchParams] = useSearchParams();
// 搜索 & 筛选
const [keyword, setKeyword] = useState("");
@ -57,6 +59,9 @@ export default function AdminTasksPage() {
const [submitting, setSubmitting] = useState(false);
const [qrSerial, setQrSerial] = useState<string | null>(null); // 🔧 QR弹窗
// 从看板跳转: ?sn=xxx → 自动搜索 + 自动展开流转树
const autoSn = searchParams.get("sn") || "";
// ---- 加载产品列表(始终拉全量,不做服务端状态过滤) ----
async function loadProducts(kw: string) {
setLoading(true);
@ -66,14 +71,27 @@ export default function AdminTasksPage() {
if (kw.trim()) params.keyword = kw.trim();
const { data } = await api.get<ProductResponse[]>("/products/", { params });
setProducts(data);
return data;
} catch {
setError("加载产品列表失败,请检查后端服务");
return [];
} finally {
setLoading(false);
}
}
useEffect(() => { loadProducts(keyword); }, []); // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
if (autoSn) {
setKeyword(autoSn);
loadProducts(autoSn).then((data) => {
// 产品加载完成后自动展开流转树
const found = data.find((p: ProductResponse) => p.serial_number === autoSn);
if (found) toggleProductTree(found.serial_number);
});
} else {
loadProducts(keyword);
}
}, []); // eslint-disable-line react-hooks/exhaustive-deps
function handleSearch(e?: React.FormEvent) {
e?.preventDefault();