All files / app/(tabs)/scanner/hooks useScannerFlow.ts

97.05% Statements 33/34
83.33% Branches 5/6
100% Functions 7/7
97.05% Lines 33/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113                                              25x 25x 25x             25x 1x 1x           25x 2x 2x           25x 2x 2x           25x 5x   1x 1x   1x 1x   1x 1x   1x 1x   1x 1x 1x                 25x 1x 1x 1x 1x           25x 5x       25x                              
/**
 * 扫描流程管理 Hook
 */
 
import { useCallback, useState } from 'react';
 
import { ScanType } from '@/src/types/camera';
import type { CatFood } from '@/src/types/catFood';
 
import type { ScanFlowState } from '../types';
 
interface UseScannerFlowProps {
  setScanType: (type: ScanType) => void;
  resetBarcodeScan: () => void;
}
 
/**
 * 扫描流程管理 Hook
 *
 * @returns 流程状态和状态转换方法
 */
export function useScannerFlow({ setScanType, resetBarcodeScan }: UseScannerFlowProps) {
  // ==================== 状态管理 ====================
  const [flowState, setFlowState] = useState<ScanFlowState>('initial');
  const [selectedCatFood, setSelectedCatFood] = useState<CatFood | null>(null);
  const [scannedCode, setScannedCode] = useState<string | null>(null);
 
  // ==================== 流程控制方法 ====================
 
  /**
   * 开始扫描流程 - 直接进入条形码扫描
   */
  const startScan = useCallback(() => {
    setScanType(ScanType.BARCODE);
    setFlowState('taking-photo');
  }, [setScanType]);
 
  /**
   * 选择猫粮
   */
  const selectCatFood = useCallback((catFood: CatFood) => {
    setSelectedCatFood(catFood);
    setFlowState('selected-catfood');
  }, []);
 
  /**
   * 条形码扫描成功
   */
  const onBarcodeScanned = useCallback((code: string) => {
    setScannedCode(code);
    setFlowState('barcode-result');
  }, []);
 
  /**
   * 返回上一步
   */
  const goBack = useCallback(() => {
    switch (flowState) {
      case 'searching-catfood':
        setFlowState('initial');
        break;
      case 'taking-photo':
        setFlowState('initial');
        break;
      case 'photo-preview':
        setFlowState('taking-photo');
        break;
      case 'ocr-result':
        setFlowState('taking-photo');
        break;
      case 'barcode-result':
        setFlowState('taking-photo');
        resetBarcodeScan();
        break;
      default:
        break;
    }
  }, [flowState, resetBarcodeScan]);
 
  /**
   * 重置整个流程
   */
  const resetFlow = useCallback(() => {
    setFlowState('initial');
    setSelectedCatFood(null);
    setScannedCode(null);
    resetBarcodeScan();
  }, [resetBarcodeScan]);
 
  /**
   * 流程状态转换方法
   */
  const transitionTo = useCallback((state: ScanFlowState) => {
    setFlowState(state);
  }, []);
 
  // ==================== 返回值 ====================
  return {
    // 状态
    flowState,
    selectedCatFood,
    scannedCode,
 
    // 方法
    startScan,
    selectCatFood,
    onBarcodeScanned,
    goBack,
    resetFlow,
    transitionTo,
  };
}