feat: Web端401队列拦截器 + 消息/任务/个人中心重写 + TabBar红点 + Admin页面完善
This commit is contained in:
@ -1,12 +1,14 @@
|
||||
/** 扫码干活页 — 编排摄像头扫码 + 手动输入 + 查询结果 */
|
||||
import { useState, useCallback } from "react";
|
||||
import { QrCode } from "lucide-react";
|
||||
import { useState, useCallback, Suspense, lazy } from "react";
|
||||
import { QrCode, Loader2 } from "lucide-react";
|
||||
import { scanProduct } from "../services/productApi";
|
||||
import type { ProductScanResponse } from "../types/api";
|
||||
import CameraScanner from "../components/scan/CameraScanner";
|
||||
import ManualInput from "../components/scan/ManualInput";
|
||||
import QueryResult from "../components/scan/QueryResult";
|
||||
|
||||
// 🚀 CameraScanner → QrScanner → html5-qrcode (~200KB),仅在首次点开摄像头时加载
|
||||
const CameraScanner = lazy(() => import("../components/scan/CameraScanner"));
|
||||
|
||||
export default function ScanPage() {
|
||||
const [cameraActive, setCameraActive] = useState(false);
|
||||
const [cameraError, setCameraError] = useState<string | null>(null);
|
||||
@ -18,7 +20,7 @@ export default function ScanPage() {
|
||||
|
||||
/** 通用查询 */
|
||||
const doQuery = useCallback(async (sn: string) => {
|
||||
if (sn.length < 8) { setError("序列号至少需要 8 位"); return; }
|
||||
if (sn.length < 8) { setError("产品身份证至少需要 8 位"); return; }
|
||||
setSerialNumber(sn);
|
||||
setLastScanned(sn);
|
||||
setLoading(true);
|
||||
@ -37,7 +39,7 @@ export default function ScanPage() {
|
||||
}
|
||||
}, []);
|
||||
|
||||
/** 扫码回调:提取纯序列号 */
|
||||
/** 扫码回调:提取纯产品身份证 */
|
||||
const handleScan = useCallback(
|
||||
(decodedText: string) => {
|
||||
setCameraError(null);
|
||||
@ -53,15 +55,23 @@ export default function ScanPage() {
|
||||
<h2 className="text-lg font-bold text-gray-800">扫码干活</h2>
|
||||
</div>
|
||||
|
||||
{/* 摄像头扫码 */}
|
||||
{/* 摄像头扫码 — 点击启动时才动态加载 html5-qrcode */}
|
||||
<div className="mt-3 px-4">
|
||||
<CameraScanner
|
||||
active={cameraActive}
|
||||
onToggle={setCameraActive}
|
||||
onScan={handleScan}
|
||||
error={cameraError}
|
||||
onError={setCameraError}
|
||||
/>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="flex items-center justify-center rounded-xl border border-gray-200 bg-white py-16 shadow-sm">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-blue-500" />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<CameraScanner
|
||||
active={cameraActive}
|
||||
onToggle={setCameraActive}
|
||||
onScan={handleScan}
|
||||
error={cameraError}
|
||||
onError={setCameraError}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
{/* 手动输入 */}
|
||||
|
||||
Reference in New Issue
Block a user