feat: 看板在制品点击跳转任务全景并自动展开流转树
Dashboard: WipRow 点击改为 nav(/admin/tasks?sn=xxx) AdminTasksPage: 读取 ?sn= 参数 → 自动搜索 → 产品加载后自动展开流转树
This commit is contained in:
@ -81,7 +81,7 @@ function WipRow({ t }: { t: WipTask }) {
|
|||||||
const nav = useNavigate();
|
const nav = useNavigate();
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
if (t.product_sn) {
|
if (t.product_sn) {
|
||||||
nav(`/scan?sn=${t.product_sn}`);
|
nav(`/admin/tasks?sn=${t.product_sn}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
/** 任务全景 Dashboard — 按订单聚合 + 关键词搜索 + 状态筛选 */
|
/** 任务全景 Dashboard — 按订单聚合 + 关键词搜索 + 状态筛选 */
|
||||||
import { useState, useEffect, useMemo, useCallback } from "react";
|
import { useState, useEffect, useMemo, useCallback } from "react";
|
||||||
|
import { useSearchParams } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
Search, Loader2, Package, ChevronDown, ChevronRight,
|
Search, Loader2, Package, ChevronDown, ChevronRight,
|
||||||
Warehouse, GitBranch, X,
|
Warehouse, GitBranch, X,
|
||||||
@ -35,6 +36,7 @@ interface OrderGroup {
|
|||||||
export default function AdminTasksPage() {
|
export default function AdminTasksPage() {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { user: currentUser } = useAuth();
|
const { user: currentUser } = useAuth();
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
|
||||||
// 搜索 & 筛选
|
// 搜索 & 筛选
|
||||||
const [keyword, setKeyword] = useState("");
|
const [keyword, setKeyword] = useState("");
|
||||||
@ -57,6 +59,9 @@ export default function AdminTasksPage() {
|
|||||||
const [submitting, setSubmitting] = useState(false);
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const [qrSerial, setQrSerial] = useState<string | null>(null); // 🔧 QR弹窗
|
const [qrSerial, setQrSerial] = useState<string | null>(null); // 🔧 QR弹窗
|
||||||
|
|
||||||
|
// 从看板跳转: ?sn=xxx → 自动搜索 + 自动展开流转树
|
||||||
|
const autoSn = searchParams.get("sn") || "";
|
||||||
|
|
||||||
// ---- 加载产品列表(始终拉全量,不做服务端状态过滤) ----
|
// ---- 加载产品列表(始终拉全量,不做服务端状态过滤) ----
|
||||||
async function loadProducts(kw: string) {
|
async function loadProducts(kw: string) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@ -66,14 +71,27 @@ export default function AdminTasksPage() {
|
|||||||
if (kw.trim()) params.keyword = kw.trim();
|
if (kw.trim()) params.keyword = kw.trim();
|
||||||
const { data } = await api.get<ProductResponse[]>("/products/", { params });
|
const { data } = await api.get<ProductResponse[]>("/products/", { params });
|
||||||
setProducts(data);
|
setProducts(data);
|
||||||
|
return data;
|
||||||
} catch {
|
} catch {
|
||||||
setError("加载产品列表失败,请检查后端服务");
|
setError("加载产品列表失败,请检查后端服务");
|
||||||
|
return [];
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
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) {
|
function handleSearch(e?: React.FormEvent) {
|
||||||
e?.preventDefault();
|
e?.preventDefault();
|
||||||
|
|||||||
Reference in New Issue
Block a user