| | |
| | | const [isInitLoaded, setIsInitLoaded] = useState(false); |
| | | const searchSeqRef = useRef(0); |
| | | const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null); |
| | | const pendingSearchValueRef = useRef(''); |
| | | |
| | | // 拉取附近站点 |
| | | const fetchNearbySites = async (lat: number, lon: number, electronicAreaId?: string) => { |
| | | const fetchNearbySites = async ( |
| | | lat: number, |
| | | lon: number, |
| | | electronicAreaId?: string, |
| | | canUpdate?: () => boolean |
| | | ) => { |
| | | const selectedCity = Taro.getStorageSync('selectedCity'); |
| | | try { |
| | | const res = await getNearestSite({ |
| | |
| | | longitude: Number(lon), |
| | | electronicAreaId |
| | | }); |
| | | if (canUpdate && !canUpdate()) { |
| | | return; |
| | | } |
| | | const points = Array.isArray(res?.points) ? res.points : []; |
| | | setNearbySiteList(points.map(normalizeSiteItem)); |
| | | } catch { |
| | | if (canUpdate && !canUpdate()) { |
| | | return; |
| | | } |
| | | setNearbySiteList([]); |
| | | } |
| | | }; |
| | |
| | | // 搜索输入防抖 |
| | | const debouncedSearch = useMemo(() => { |
| | | return (val: string) => { |
| | | pendingSearchValueRef.current = val; |
| | | if (debounceTimerRef.current) { |
| | | clearTimeout(debounceTimerRef.current); |
| | | } |
| | | debounceTimerRef.current = setTimeout(() => { |
| | | debounceTimerRef.current = null; |
| | | searchSiteRef.current(val); |
| | | }, 300); |
| | | }; |
| | |
| | | clearTimeout(debounceTimerRef.current); |
| | | debounceTimerRef.current = null; |
| | | } |
| | | pendingSearchValueRef.current = ''; |
| | | }; |
| | | |
| | | // 立即执行待触发的防抖搜索 |
| | | const flushDebouncedSearch = () => { |
| | | if (!debounceTimerRef.current) { |
| | | return; |
| | | } |
| | | const pendingValue = pendingSearchValueRef.current; |
| | | clearTimeout(debounceTimerRef.current); |
| | | debounceTimerRef.current = null; |
| | | pendingSearchValueRef.current = ''; |
| | | searchSiteRef.current(pendingValue); |
| | | }; |
| | | |
| | | // 清空搜索结果列表 |
| | |
| | | const { pageType: type, latitude: lat, longitude: lon, electronicAreaId } = deps.router.params; |
| | | const initTasks: Promise<unknown>[] = []; |
| | | if (lat && lon) { |
| | | initTasks.push(fetchNearbySites(Number(lat), Number(lon), electronicAreaId)); |
| | | initTasks.push( |
| | | fetchNearbySites( |
| | | Number(lat), |
| | | Number(lon), |
| | | electronicAreaId, |
| | | () => !isUnmounted |
| | | ) |
| | | ); |
| | | } |
| | | initTasks.push((async () => { |
| | | try { |
| | |
| | | searchSite, |
| | | debouncedSearch, |
| | | cancelDebouncedSearch, |
| | | flushDebouncedSearch, |
| | | clearSearchResults |
| | | }; |
| | | } |