2026-01-05 14:53:49 +08:00
|
|
|
|
import { useFullscreen, useMount } from "ahooks";
|
|
|
|
|
|
import { message } from "antd";
|
|
|
|
|
|
import autoFit from "autofit.js";
|
2026-07-20 14:23:04 +08:00
|
|
|
|
import { useEffect, useMemo, useReducer, useRef, useState } from "react";
|
2026-01-05 14:53:49 +08:00
|
|
|
|
import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
|
|
|
|
|
|
import BottomUtils from "./components/BottomUtils";
|
|
|
|
|
|
import CenterUtils from "./components/CenterUtils";
|
|
|
|
|
|
import Content from "./components/Content";
|
2026-07-20 14:23:04 +08:00
|
|
|
|
import CustomModal from "./components/Content/modal";
|
2026-01-05 14:53:49 +08:00
|
|
|
|
import Header from "./components/Header";
|
|
|
|
|
|
import RightUtils from "./components/RightUtils";
|
2026-07-16 10:38:54 +08:00
|
|
|
|
import { Context, initialMapState, MAP_ACTION, mapReducer } from "./js/context";
|
2026-07-15 09:26:35 +08:00
|
|
|
|
import useInitMap from "./js/initMap";
|
2026-01-05 14:53:49 +08:00
|
|
|
|
import mitt from "./js/mitt";
|
2026-01-07 13:51:33 +08:00
|
|
|
|
import {
|
|
|
|
|
|
changeCoverMaskVisibleMittKey,
|
|
|
|
|
|
clickBranchOfficePointMittKey,
|
2026-07-20 14:23:04 +08:00
|
|
|
|
clickMarkPointMittKey,
|
2026-01-07 13:51:33 +08:00
|
|
|
|
clickPortPointMittKey,
|
2026-07-16 10:38:54 +08:00
|
|
|
|
resetBottomUtilsMittKey,
|
2026-01-07 13:51:33 +08:00
|
|
|
|
} from "./js/mittKey";
|
2026-01-05 14:53:49 +08:00
|
|
|
|
import "./index.less";
|
|
|
|
|
|
|
2026-01-16 17:18:09 +08:00
|
|
|
|
function Map(props) {
|
2026-01-05 14:53:49 +08:00
|
|
|
|
const query = useGetUrlQuery();
|
2026-07-15 09:26:35 +08:00
|
|
|
|
const { viewer, mapMethods, initMap, externalEntryPort } = useInitMap();
|
2026-01-05 14:53:49 +08:00
|
|
|
|
|
2026-07-20 14:23:04 +08:00
|
|
|
|
const [isRenderContent, setIsRenderContent] = useState(false);
|
2026-01-05 14:53:49 +08:00
|
|
|
|
const fullscreenRef = useRef(null); // 全屏容器的ref
|
|
|
|
|
|
const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef);
|
2026-07-16 10:38:54 +08:00
|
|
|
|
const [state, dispatch] = useReducer(mapReducer, initialMapState);
|
2026-01-05 14:53:49 +08:00
|
|
|
|
|
2026-07-16 10:38:54 +08:00
|
|
|
|
// 页面组件只调用语义化 actions,不直接感知 reducer action 或 mitt 事件名。
|
|
|
|
|
|
const actions = useMemo(() => ({
|
|
|
|
|
|
selectPort: data => dispatch({ type: MAP_ACTION.SELECT_PORT, payload: data }),
|
|
|
|
|
|
selectBranchOffice: data => dispatch({ type: MAP_ACTION.SELECT_BRANCH_OFFICE, payload: data }),
|
2026-07-20 14:23:04 +08:00
|
|
|
|
selectMark: data => dispatch({ type: MAP_ACTION.SELECT_MARK, payload: data }),
|
|
|
|
|
|
resetMark: () => dispatch({ type: MAP_ACTION.RESET_MARK }),
|
2026-07-20 17:10:42 +08:00
|
|
|
|
setPortArea: portArea => dispatch({ type: MAP_ACTION.SET_PORT_AREA, payload: portArea }),
|
2026-07-16 10:38:54 +08:00
|
|
|
|
setBottomUtilsIndex: index => dispatch({ type: MAP_ACTION.SET_BOTTOM_UTILS_INDEX, payload: index }),
|
|
|
|
|
|
resetBottomUtils: () => dispatch({ type: MAP_ACTION.RESET_BOTTOM_UTILS }),
|
|
|
|
|
|
resetRightUtils: () => dispatch({ type: MAP_ACTION.RESET_RIGHT_UTILS }),
|
|
|
|
|
|
setPureMap: visible => dispatch({ type: MAP_ACTION.SET_PURE_MAP, payload: visible }),
|
|
|
|
|
|
setCoverMaskVisible: visible => dispatch({ type: MAP_ACTION.SET_COVER_MASK_VISIBLE, payload: visible }),
|
|
|
|
|
|
}), []);
|
2026-01-05 14:53:49 +08:00
|
|
|
|
|
|
|
|
|
|
useMount(() => {
|
|
|
|
|
|
autoFit.init({ dw: 1920, dh: 1080, el: "#contentContainer", resize: true });
|
|
|
|
|
|
|
2026-01-07 16:38:01 +08:00
|
|
|
|
sessionStorage.removeItem("mapCurrentBranchOfficeId");
|
|
|
|
|
|
|
2026-07-15 09:26:35 +08:00
|
|
|
|
initMap();
|
2026-01-05 14:53:49 +08:00
|
|
|
|
|
2026-07-20 14:35:04 +08:00
|
|
|
|
if (query.markType === "港口") {
|
2026-07-15 09:26:35 +08:00
|
|
|
|
const entered = externalEntryPort(query);
|
|
|
|
|
|
if (!entered)
|
|
|
|
|
|
message.warning("港口入口参数不完整,无法定位到对应港口");
|
2026-01-05 14:53:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
else {
|
2026-01-15 18:01:40 +08:00
|
|
|
|
setTimeout(() => {
|
2026-07-15 09:26:35 +08:00
|
|
|
|
mapMethods.current.flyTo();
|
|
|
|
|
|
mapMethods.current.addPortPoint();
|
2026-01-15 18:01:40 +08:00
|
|
|
|
}, 500);
|
2026-01-05 14:53:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-16 10:38:54 +08:00
|
|
|
|
// Cesium 工具层暂时通过 mitt 通知;所有事件在根组件统一转成 reducer action。
|
|
|
|
|
|
const handlePortClick = data => actions.selectPort(data);
|
|
|
|
|
|
const handleBranchOfficeClick = data => actions.selectBranchOffice(data);
|
2026-07-20 14:23:04 +08:00
|
|
|
|
const handleMarkClick = data => actions.selectMark(data);
|
2026-07-16 10:38:54 +08:00
|
|
|
|
const handleCoverMaskVisible = (visible) => {
|
|
|
|
|
|
actions.setCoverMaskVisible(visible);
|
|
|
|
|
|
if (!visible) {
|
2026-01-07 13:51:33 +08:00
|
|
|
|
message.success("地图绘制完成");
|
2026-01-05 14:53:49 +08:00
|
|
|
|
}
|
2026-07-16 10:38:54 +08:00
|
|
|
|
};
|
|
|
|
|
|
const handleResetBottomUtils = () => actions.resetBottomUtils();
|
|
|
|
|
|
mitt.on(clickPortPointMittKey, handlePortClick);
|
|
|
|
|
|
mitt.on(clickBranchOfficePointMittKey, handleBranchOfficeClick);
|
2026-07-20 14:23:04 +08:00
|
|
|
|
mitt.on(clickMarkPointMittKey, handleMarkClick);
|
2026-07-16 10:38:54 +08:00
|
|
|
|
mitt.on(changeCoverMaskVisibleMittKey, handleCoverMaskVisible);
|
|
|
|
|
|
mitt.on(resetBottomUtilsMittKey, handleResetBottomUtils);
|
2026-01-05 14:53:49 +08:00
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
autoFit.off();
|
2026-07-16 10:38:54 +08:00
|
|
|
|
mitt.off(clickPortPointMittKey, handlePortClick);
|
|
|
|
|
|
mitt.off(clickBranchOfficePointMittKey, handleBranchOfficeClick);
|
2026-07-20 14:23:04 +08:00
|
|
|
|
mitt.off(clickMarkPointMittKey, handleMarkClick);
|
2026-07-16 10:38:54 +08:00
|
|
|
|
mitt.off(changeCoverMaskVisibleMittKey, handleCoverMaskVisible);
|
|
|
|
|
|
mitt.off(resetBottomUtilsMittKey, handleResetBottomUtils);
|
2026-01-05 14:53:49 +08:00
|
|
|
|
};
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2026-01-19 14:09:05 +08:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
query.accessTicket && window.sessionStorage.setItem("accessTicket", query.accessTicket);
|
|
|
|
|
|
query.clientId && window.sessionStorage.setItem("clientId", query.clientId);
|
|
|
|
|
|
query.orgId && window.sessionStorage.setItem("orgId", query.orgId);
|
|
|
|
|
|
query.token && window.sessionStorage.setItem("token", query.token);
|
2026-07-20 14:23:04 +08:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
if (window.sessionStorage.getItem("token"))
|
|
|
|
|
|
setIsRenderContent(true);
|
|
|
|
|
|
});
|
2026-01-19 14:09:05 +08:00
|
|
|
|
}, []);
|
|
|
|
|
|
|
2026-01-05 14:53:49 +08:00
|
|
|
|
const providerValues = useMemo(
|
2026-07-16 10:38:54 +08:00
|
|
|
|
() => ({ viewer, mapMethods, ...state, actions }),
|
|
|
|
|
|
[viewer, mapMethods, state, actions],
|
2026-01-05 14:53:49 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div ref={fullscreenRef}>
|
|
|
|
|
|
<Context.Provider value={providerValues}>
|
|
|
|
|
|
<div id="cesiumContainer" />
|
|
|
|
|
|
<div id="contentContainer">
|
2026-07-20 14:23:04 +08:00
|
|
|
|
{isRenderContent && (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<Header />
|
|
|
|
|
|
<CenterUtils />
|
|
|
|
|
|
<RightUtils history={props.history} isFullscreen={isFullscreen} toggleFullscreen={toggleFullscreen} />
|
|
|
|
|
|
<BottomUtils />
|
|
|
|
|
|
<Content history={props.history} />
|
|
|
|
|
|
<CustomModal />
|
|
|
|
|
|
</>
|
|
|
|
|
|
)}
|
2026-01-05 14:53:49 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</Context.Provider>
|
|
|
|
|
|
<div
|
2026-07-16 10:38:54 +08:00
|
|
|
|
style={{ display: state.coverMaskVisible ? "block" : "none" }}
|
2026-01-05 14:53:49 +08:00
|
|
|
|
className="coverMaskContainer"
|
2026-01-07 13:51:33 +08:00
|
|
|
|
onClick={() => message.warning("正在绘制地图,请等待绘制完成在进行操作")}
|
2026-01-05 14:53:49 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default Map;
|