import { __awaiter } from "tslib"; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState, } from "react"; import { Amap, Marker } from "@amap/amap-react"; import { AutoComplete, Button, Input, Space, message } from "antd"; import { debounce, isNumber } from "lodash"; import { DageMapGeocoder } from "./plugins"; import { getAmapInputTips } from "./utils"; export const DageMap = forwardRef(({ latitude, longitude, disabled, address, city, onlyCityArea, inputTipsApi, outCityAreaMessage, onAddressChange, onLngLatChange, onMapComplete, onError, }, ref) => { const mapRef = useRef(); /** 是否禁用坐标解析地址 */ const geocoderDisabled = useRef(false); const [loaded, setLoaded] = useState(false); /** 上一个坐标地址 */ const prevPosition = useRef([longitude, latitude]); /** 输入框经度 */ const [lng, setLng] = useState(longitude); /** 输入框纬度 */ const [lat, setLat] = useState(latitude); const [options, setOptions] = useState([]); const [position, setPosition] = useState([longitude, latitude]); useImperativeHandle(ref, () => ({ mapRef: mapRef.current, })); useEffect(() => { if (longitude === lng && latitude === lat) return; // 外部改动经纬度,不需要解析地址 geocoderDisabled.current = true; setPosition([longitude, latitude]); setLat(latitude); setLng(longitude); prevPosition.current = [longitude, latitude]; }, [longitude, latitude]); const handleSearch = useCallback(debounce((value) => __awaiter(void 0, void 0, void 0, function* () { if (!value) { setOptions([]); return; } const { tips } = yield getAmapInputTips(inputTipsApi, value, city); setOptions(tips || []); }), 500), [city]); const handleClick = useCallback((e, data) => { if (disabled) return; const { lng, lat } = data.lnglat; geocoderDisabled.current = false; setLat(lat); setLng(lng); setPosition([lng, lat]); onLngLatChange === null || onLngLatChange === void 0 ? void 0 : onLngLatChange({ lat, lng, }); }, [disabled, onLngLatChange]); /** * 地图初始化完成 */ const handleComplete = useCallback(() => { var _a; setLoaded(true); (_a = mapRef.current) === null || _a === void 0 ? void 0 : _a.setCenter([longitude, latitude], false, 1000); onMapComplete === null || onMapComplete === void 0 ? void 0 : onMapComplete(); }, [longitude, latitude, onMapComplete]); const handleMarker = useCallback(debounce((e) => { const [lng, lat] = e._position; geocoderDisabled.current = false; setLat(lat); setLng(lng); onLngLatChange === null || onLngLatChange === void 0 ? void 0 : onLngLatChange({ lat, lng, }); setPosition(e._position); }, 200), [onLngLatChange]); const handlePosition = useCallback((long = lng, lati = lat) => { var _a; if (!long || !lati) return; onLngLatChange === null || onLngLatChange === void 0 ? void 0 : onLngLatChange({ lat: lati, lng: long, }); setPosition([long, lati]); (_a = mapRef.current) === null || _a === void 0 ? void 0 : _a.setCenter([long, lati], false, 1000); }, [lng, lat, onLngLatChange]); /** * 坐标搜索 */ const handleLngLatSearch = useCallback(() => { geocoderDisabled.current = false; handlePosition(); }, [handlePosition]); const handleSelect = useCallback((val, opts) => { const [lng, lat] = opts.location.split(",").map((i) => Number(i)); setLng(lng); setLat(lat); geocoderDisabled.current = true; handlePosition(lng, lat); onLngLatChange === null || onLngLatChange === void 0 ? void 0 : onLngLatChange({ lat, lng, }); prevPosition.current = [lng, lat]; }, [handlePosition, onLngLatChange]); const handleAutoCompleteChange = useCallback((val) => { onAddressChange === null || onAddressChange === void 0 ? void 0 : onAddressChange(val); }, [onAddressChange]); const handleGeocoderAddress = (res) => { if (geocoderDisabled.current) return; if (onlyCityArea && isNumber(city) && !res.regeocode.addressComponent.adcode.startsWith(city.toString().substring(0, 2))) { // 超出市区范围 handleOutCityAreaError(); return; } onAddressChange === null || onAddressChange === void 0 ? void 0 : onAddressChange(res.regeocode.formattedAddress); prevPosition.current = [lng, lat]; }; const handleOutCityAreaError = () => { outCityAreaMessage && message.error(outCityAreaMessage, 2); onError === null || onError === void 0 ? void 0 : onError(); setTimeout(() => { setLat(prevPosition.current[1]); setLng(prevPosition.current[0]); handlePosition(prevPosition.current[0], prevPosition.current[1]); }, 2000); }; return (_jsxs(_Fragment, { children: [_jsx("div", { children: _jsx(AutoComplete, { allowClear: true, disabled: disabled, value: address, style: { width: 450 }, options: options.map((i) => (Object.assign(Object.assign({}, i), { value: i.name }))), onSearch: handleSearch, onSelect: handleSelect, onChange: handleAutoCompleteChange, children: _jsx(Input, { allowClear: true, placeholder: "\u8BF7\u8F93\u5165\u8BE6\u7EC6\u63CF\u8FF0" }) }) }), _jsxs(Space, { style: { margin: "15px 0" }, children: [_jsx(Input, { readOnly: disabled, value: lng, type: "number", placeholder: "\u8BF7\u8F93\u5165\u7ECF\u5EA6", onChange: (e) => setLng(Number(e.target.value)) }), _jsx(Input, { readOnly: disabled, value: lat, type: "number", placeholder: "\u8BF7\u8F93\u5165\u7EAC\u5EA6", onChange: (e) => setLat(Number(e.target.value)) }), !disabled && (_jsx(Button, { type: "primary", onClick: handleLngLatSearch, children: "\u67E5\u8BE2" }))] }), _jsx("div", { style: { width: 650, height: 400 }, children: _jsx(Amap, { ref: mapRef, zoom: 17, onComplete: handleComplete, onClick: handleClick, children: loaded && position ? (_jsxs(_Fragment, { children: [_jsx(Marker, { position: position, draggable: !disabled, onDragging: handleMarker }), !disabled && (_jsx(DageMapGeocoder, { city: city, position: position, onChange: handleGeocoderAddress, onError: handleOutCityAreaError }))] })) : (_jsx(_Fragment, {})) }) })] })); }); export * from "./types"; export * from "./utils";