You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
904 lines
27 KiB
904 lines
27 KiB
import React, { useState, useEffect, useReducer, useRef } from "react";
|
|
import Qmmap from "../../qmmap/index";
|
|
import { useHistory, useLocation } from "react-router-dom";
|
|
import { getMallInfo, post } from "../../js/helpers/data-helper";
|
|
import "./Index.scss";
|
|
import Floors from "../../components/Floors/Floors";
|
|
import HeadBar from "../../components/HeadBar/HeadBar";
|
|
import Popup from "../../components/Popup/Popup";
|
|
import pos from "./pos.png";
|
|
import offline from "./offline.png";
|
|
import compass from "./compass.png";
|
|
import Shops from "../Shops/Shops";
|
|
import NavBottom from "../../components/NavBottom/NavBottom";
|
|
import Modal from "react-modal";
|
|
import DefaultPopup, {
|
|
DefaultPopupStates,
|
|
} from "../../components/DefaultPopup/DefaultPopup";
|
|
import More from "../../components/More/More";
|
|
import arpng from "./ar.png";
|
|
import Car from "../Car/Car";
|
|
import axios from "axios";
|
|
import Activities from "../Activities/Activities";
|
|
import Coupons from "../Coupons/Coupons";
|
|
import TabMap from "./tabs/Tabs";
|
|
import ShopCoupons from "../ShopCoupons/ShopCoupons";
|
|
|
|
export const MallCode = React.createContext(null);
|
|
// const vConsole = new window.VConsole();
|
|
let focusdDevice;
|
|
let memberID;
|
|
let isShop;
|
|
|
|
const Index = () => {
|
|
const history = useHistory();
|
|
const [mapId] = useState("id" + new Date().getTime());
|
|
const [shop, setShop] = useState(null);
|
|
const [mallInfo, setMallInfo] = useState(null);
|
|
const mall = mallInfo ? mallInfo.mall : null;
|
|
const config = mallInfo ? mallInfo.config : null;
|
|
const images = mallInfo ? mallInfo.images : null;
|
|
const [map, setMap] = useState(null);
|
|
const [sceneIndex, setSceneIndex] = useState(null);
|
|
const params = new URLSearchParams(useLocation().search);
|
|
const [mallCode, setMallCode] = useState(null);
|
|
const startParams = params.get("s");
|
|
let endId = params.get("e");
|
|
const openid = params.get("openid");
|
|
if (params.get("memberID")) memberID = params.get("memberID");
|
|
if (params.get("isShop")) isShop = params.get("isShop");
|
|
const plate = params.get("plate");
|
|
const [navigation, setNavigation] = useState(false);
|
|
const [inAnimation, setInAnimation] = useState(false);
|
|
const [displayMode, setDisplayMode] = useState(1);
|
|
const [searchType, setSearchType] = useState(0);
|
|
const [showOptions, setShowOptions] = useState(false);
|
|
const [showShops, setShowShops] = useState(false);
|
|
const [routeSearchText, setRouteSearchText] = useState("");
|
|
const [percent, setPercent] = useState(0);
|
|
const [elevations, setElevations] = useState([]);
|
|
const [paused, setPaused] = useState(false);
|
|
const [playAudio, setPlayAudio] = useState(false);
|
|
const [online, setOnline] = useState(true);
|
|
const [azimuthAngle, setAzimuthAngle] = useState(0);
|
|
const [follow, setFollow] = useState(false);
|
|
const [facilities, setFacilities] = useState(null);
|
|
const [defaultPopupState, setDefaultPopupState] = useState(
|
|
DefaultPopupStates.init
|
|
);
|
|
const [start, _setStart] = useState(null);
|
|
const [end, _setEnd] = useState(null);
|
|
const [isPick, _setIsPick] = useState(false);
|
|
const [doFocus, _setDoFocus] = useState(0);
|
|
const [showARPrompt, setShowARPrompt] = useState(false);
|
|
const [ARshop, setARShop] = useState(null);
|
|
const [isTyping, setIsTyping] = useState(null);
|
|
const [showFindCar, setShowFindCar] = useState(false);
|
|
const [showActivities, setShowActivities] = useState(false);
|
|
const [showCoupon, setShowCoupon] = useState(false);
|
|
const [tab, setTab] = useState("地图");
|
|
const [couponShop, setCouponShop] = useState(null);
|
|
const [initActivity, setInitActivity] = useState(null);
|
|
const showShopCoupons = !!couponShop;
|
|
|
|
const hasTab = mall && mall.menu.length > 1;
|
|
const setStatistics = mall
|
|
? ({ userId, navType, pointType, objectCode, objectName, floorName }) =>
|
|
userId &&
|
|
userId !== "null" &&
|
|
axios.post(mall.baseUrl + "/api/ar/v1/applet/AddGuideRecord", {
|
|
mallCode: mall.code,
|
|
userId,
|
|
navType,
|
|
pointType,
|
|
objectCode,
|
|
objectName,
|
|
floorName,
|
|
})
|
|
: undefined;
|
|
useEffect(() => {
|
|
if (shop) {
|
|
const e = shop.houseNum
|
|
? shop.houseNum
|
|
: shop.isDevice
|
|
? `${shop.floorOrder}_${shop.navPoint}_${shop.name}`
|
|
: encodeURIComponent(shop.id);
|
|
history.replace(
|
|
`/?openid=${openid}&e=${e}&name=${shop.name}${
|
|
shop.floorName ? "(" + shop.floorName + ")" : ""
|
|
}`
|
|
);
|
|
}
|
|
}, [shop]);
|
|
|
|
useEffect(() => {
|
|
if (!map) return;
|
|
let start;
|
|
let end;
|
|
if (startParams) {
|
|
const startParamList = startParams.split("_");
|
|
if (startParamList.length === 3) {
|
|
let [sfloororder, spoint, sname] = startParamList;
|
|
sfloororder = Number(sfloororder);
|
|
spoint = Number(spoint);
|
|
start = {
|
|
isDevice: true,
|
|
name: sname,
|
|
navPoint: spoint,
|
|
yaxis: spoint,
|
|
floorOrder: sfloororder,
|
|
};
|
|
setStart(start);
|
|
}
|
|
}
|
|
if (!endId) return;
|
|
if (endId === "findcar") return setShowFindCar(true);
|
|
if (endId === "me") return setTab("我的");
|
|
if (endId.startsWith && endId.startsWith("activities")) {
|
|
setTab("活动");
|
|
if (endId === "activities") return;
|
|
else {
|
|
const code = endId.replace("activities", "");
|
|
const activity = mall.activities.find((act) => act.code === code);
|
|
if (activity) setInitActivity(activity);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (mall.mcShopIDHouseNumMap && mall.mcShopIDHouseNumMap[endId])
|
|
endId = mall.mcShopIDHouseNumMap[endId];
|
|
const shop = map.getShopByHouseNum(endId);
|
|
const p = map.getPByHouseNum(endId) ? map.getPByHouseNum(endId).data : null;
|
|
const fac = map.getFacilityById(endId) ? map.getFacilityById(endId) : null;
|
|
const endParamList = endId.split("_");
|
|
let endPoint = null;
|
|
if (endParamList.length === 3) {
|
|
let [efloororder, epoint, ename] = endParamList;
|
|
efloororder = Number(efloororder);
|
|
epoint = Number(epoint);
|
|
endPoint = {
|
|
isDevice: true,
|
|
name: ename,
|
|
navPoint: epoint,
|
|
yaxis: epoint,
|
|
floorOrder: efloororder,
|
|
};
|
|
}
|
|
end = shop ? shop : p ? p : fac ? fac : endPoint;
|
|
if (!start) {
|
|
setDoFocus(2);
|
|
shop
|
|
? map.focusShopByHouseNum(endId)
|
|
: p
|
|
? map.focusPByHouseNum(endId)
|
|
: fac
|
|
? map.focusFacilityById(endId)
|
|
: map.addDeviceAndFocus(end).then((device) => {
|
|
focusdDevice = device;
|
|
setShop(end);
|
|
});
|
|
return;
|
|
}
|
|
if (start && end) {
|
|
setEnd(end);
|
|
map.startNavigate({
|
|
start,
|
|
end,
|
|
});
|
|
}
|
|
}, [map]);
|
|
|
|
useEffect(() => {
|
|
map && map.setStart(start);
|
|
}, [start]);
|
|
|
|
useEffect(() => {
|
|
map && map.setEnd(end);
|
|
}, [end]);
|
|
|
|
const doFocusRef = useRef(doFocus);
|
|
const setDoFocus = (data) => {
|
|
doFocusRef.current = data;
|
|
_setDoFocus(data);
|
|
};
|
|
|
|
const startRef = useRef(start);
|
|
const setStart = (data) => {
|
|
startRef.current = data;
|
|
_setStart(data);
|
|
};
|
|
|
|
const endRef = useRef(end);
|
|
const setEnd = (data) => {
|
|
endRef.current = data;
|
|
_setEnd(data);
|
|
};
|
|
|
|
const isPickRef = useRef(isPick);
|
|
const setIsPick = (data) => {
|
|
isPickRef.current = data;
|
|
_setIsPick(data);
|
|
};
|
|
|
|
useEffect(() => {
|
|
let offlineListener = () => setOnline(false);
|
|
let onlineListener = () => setOnline(true);
|
|
window.addEventListener("offline", offlineListener);
|
|
window.addEventListener("online", onlineListener);
|
|
return () => {
|
|
window.removeEventListener("online", onlineListener);
|
|
window.removeEventListener("offline", offlineListener);
|
|
};
|
|
});
|
|
|
|
const [_, dispatchLS] = useReducer(
|
|
({ lastSearch }, { type, data }) => {
|
|
switch (type) {
|
|
case "set":
|
|
return { lastSearch: data };
|
|
case "addLine":
|
|
lastSearch &&
|
|
lastSearch.forEach(({ floorOrder, addLine }) => {
|
|
Number(floorOrder) === data && addLine();
|
|
});
|
|
return { lastSearch };
|
|
default:
|
|
throw new Error();
|
|
}
|
|
},
|
|
{
|
|
lastSearch: null,
|
|
}
|
|
);
|
|
|
|
const handleFocus = ({ data, preventDefault }) => {
|
|
const start = startRef.current;
|
|
const end = endRef.current;
|
|
const isPick = isPickRef.current;
|
|
const doFocus = doFocusRef.current;
|
|
if (doFocus === 2) {
|
|
setDoFocus(1);
|
|
setShop(data);
|
|
return;
|
|
}
|
|
if (start && end) {
|
|
preventDefault();
|
|
} else if (((start && !end) || (!start && end)) && !isPick) {
|
|
preventDefault();
|
|
} else {
|
|
if (follow) {
|
|
map.setFollow(false);
|
|
setFollow(false);
|
|
}
|
|
setShop(data);
|
|
}
|
|
setDoFocus(0);
|
|
};
|
|
|
|
const swap = async () => {
|
|
if (navigation && start && end) await navigation.stop();
|
|
if (start && end) map.startNavigate({ start: end, end: start });
|
|
setStart(end);
|
|
setEnd(start);
|
|
};
|
|
|
|
const handleBlur = () => {
|
|
if (focusdDevice) {
|
|
focusdDevice.blur();
|
|
focusdDevice = null;
|
|
}
|
|
const doFocus = doFocusRef.current;
|
|
if (doFocus === 1) return;
|
|
history.replace(`/?openid=${openid}`);
|
|
setShop(null);
|
|
};
|
|
|
|
const loadMap = () => {
|
|
let img = new Image(100, 200);
|
|
img.src = offline;
|
|
const { scale, needSpotLight } = mall;
|
|
new Qmmap({
|
|
container: document.querySelector(`#${mapId}`),
|
|
config: {
|
|
...(config ? config : {}),
|
|
focusStyle: ["scale", "showText"],
|
|
focusColor: 0xff0000,
|
|
controller: "MapControls",
|
|
routeSearchAnimationType: 2,
|
|
routeSearchZoom: 2,
|
|
maxZoom: 4,
|
|
playAudio,
|
|
needSpotLight,
|
|
scale,
|
|
floorHeights: {
|
|
0: 10,
|
|
1: 10,
|
|
2: 10,
|
|
3: 10,
|
|
4: 10,
|
|
5: 10,
|
|
6: 10,
|
|
7: 10,
|
|
8: 10,
|
|
9: 10,
|
|
10: 10,
|
|
11: 10,
|
|
},
|
|
backgroundColor: null,
|
|
navIconTopColor: 0xffffff,
|
|
navIconMiddleColor: 0x437af7,
|
|
navIconBottomColor: 0xffffff,
|
|
pathMainColor: 0x437af7,
|
|
pathBorderColor: 0x5ea4f9,
|
|
pathArrowColor: 0xffffff,
|
|
addtionalFacilityCodeMap: mall.addtionalFacilityCodeMap,
|
|
autoRotate: false,
|
|
customTitleFacilityTypeMap: { 116: true },
|
|
wrapperWindowRatio: 0.9,
|
|
showShopLabel: false,
|
|
useFormatColor: false,
|
|
floorDiffMap: {
|
|
"3_5": 1,
|
|
"5_3": 1,
|
|
},
|
|
elevatorWaitCost: 7000,
|
|
elevatorCostPerFloor: 1000,
|
|
escalatorCostPerFloor: 7000,
|
|
},
|
|
mall,
|
|
onFocusShop: (data, stop) => {
|
|
handleFocus({ data, preventDefault: stop });
|
|
},
|
|
onBlurShop: handleBlur,
|
|
onFocusFacility: (data, stop) => {
|
|
handleFocus({ data, preventDefault: stop });
|
|
},
|
|
onBlurFacility: handleBlur,
|
|
onTapP(data, stop) {
|
|
handleFocus({ data, preventDefault: stop });
|
|
},
|
|
onBlurP: handleBlur,
|
|
onSearchStart: (navigation) => {
|
|
const { pathsByFloor } = navigation;
|
|
if (pathsByFloor.length === 1) setElevations([]);
|
|
else {
|
|
let result = [];
|
|
let acc = 0;
|
|
for (let i = 0; i < pathsByFloor.length - 1; i++) {
|
|
let { floorOrder: floorOrder1, distanceSum } = pathsByFloor[i];
|
|
let { floorOrder: floorOrder2 } = pathsByFloor[i + 1];
|
|
|
|
acc += distanceSum;
|
|
result.push({
|
|
isUp: Number(floorOrder2) > Number(floorOrder1),
|
|
floorOrder: floorOrder2,
|
|
percent: acc / navigation.totalDistance,
|
|
name: mall.floors[floorOrder2][1],
|
|
});
|
|
}
|
|
setElevations(result);
|
|
}
|
|
navigation.handleText = setRouteSearchText;
|
|
navigation.onPercentChange = setPercent;
|
|
navigation.onPausedChanged = setPaused;
|
|
setNavigation(navigation);
|
|
setInAnimation(true);
|
|
dispatchLS({ type: "set", data: pathsByFloor });
|
|
},
|
|
onSearchComplete: () => {
|
|
setInAnimation(false);
|
|
},
|
|
images,
|
|
onFloorChange: (floorOrder) => {
|
|
setDoFocus(0);
|
|
setSceneIndex(floorOrder);
|
|
dispatchLS({ type: "addLine", data: floorOrder });
|
|
},
|
|
onLoad: (map) => {
|
|
setDisplayMode(1);
|
|
setMap(map);
|
|
},
|
|
onAzimuthAngleChange: (angle) =>
|
|
setAzimuthAngle(Math.floor((angle / Math.PI) * 180)),
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!mallCode) {
|
|
getMallInfo({ memberID }).then((result) => {
|
|
if (!mallCode) setMallCode(result.mall.code);
|
|
setMallInfo(result);
|
|
});
|
|
}
|
|
}, [mallCode]);
|
|
|
|
const showPopup =
|
|
shop !== null &&
|
|
!isPick &&
|
|
defaultPopupState !== DefaultPopupStates.facList;
|
|
const hasCoupon = showPopup && shop && shop.hasCoupon;
|
|
const showHeadBar = (start || end) && !inAnimation;
|
|
const showHeadBarSearchType = showHeadBar && start && end;
|
|
const showNav = inAnimation && start && end;
|
|
const showDefaultPopup = !showPopup && !showHeadBar && !showNav && facilities;
|
|
const isNavEnd = showHeadBar && start && end;
|
|
|
|
const exitFromNav = () => {
|
|
map.setStart(null);
|
|
map.setEnd(null);
|
|
map.recycle();
|
|
setIsPick(false);
|
|
navigation && navigation.stop && navigation.stop();
|
|
dispatchLS({ type: "set", data: null });
|
|
setStart(null);
|
|
setEnd(null);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (navigation) {
|
|
if (openid) {
|
|
const isShop = "intro" in end;
|
|
const isP = end.isP;
|
|
const isDevice = end.isDevice;
|
|
setStatistics({
|
|
userId: openid,
|
|
navType: 2,
|
|
pointType: isShop || isDevice ? "1" : isP ? "3" : "2",
|
|
objectCode: isShop ? end.code : isP ? end.houseNum : end.Type,
|
|
objectName: end.name,
|
|
floorName: end.floorName || mall.floors[end.floorOrder][1],
|
|
});
|
|
}
|
|
}
|
|
}, [navigation]);
|
|
|
|
useEffect(() => {
|
|
if (mallInfo) {
|
|
setTab(mall.menu[0].name);
|
|
loadMap();
|
|
}
|
|
}, [mallInfo]);
|
|
|
|
useEffect(() => {
|
|
if (map) {
|
|
let facs = map.getAllFacilities();
|
|
facs = facs
|
|
.filter(({ url, typeName }) => url && typeName)
|
|
.reduce(
|
|
(acc, nxt) =>
|
|
acc[nxt.typeName]
|
|
? { ...acc, [nxt.typeName]: [...acc[nxt.typeName], nxt] }
|
|
: { ...acc, [nxt.typeName]: [nxt] },
|
|
{}
|
|
);
|
|
setFacilities(facs);
|
|
}
|
|
}, [map]);
|
|
|
|
useEffect(() => {
|
|
switch (tab) {
|
|
case "活动":
|
|
setShowFindCar(false);
|
|
setShowCoupon(false);
|
|
setShowActivities(true);
|
|
break;
|
|
case "地图":
|
|
setShowFindCar(false);
|
|
setShowCoupon(false);
|
|
setShowActivities(false);
|
|
break;
|
|
case "寻车":
|
|
setShowCoupon(false);
|
|
setShowActivities(false);
|
|
setShowFindCar(true);
|
|
break;
|
|
case "我的":
|
|
setShowActivities(false);
|
|
setShowFindCar(false);
|
|
setShowCoupon(true);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}, [tab]);
|
|
|
|
return (
|
|
<MallCode.Provider value={mallCode}>
|
|
<div
|
|
className={
|
|
`index ${hasTab ? "hasTab" : ""}` +
|
|
(showDefaultPopup
|
|
? defaultPopupState === DefaultPopupStates.init
|
|
? " t1"
|
|
: defaultPopupState === DefaultPopupStates.moreFac
|
|
? " t2"
|
|
: " t3"
|
|
: "")
|
|
}
|
|
>
|
|
{showShopCoupons && (
|
|
<Modal
|
|
isOpen={showShopCoupons}
|
|
ariaHideApp={false}
|
|
className="shopcoupon-wrapper"
|
|
>
|
|
<ShopCoupons
|
|
memberID={memberID}
|
|
mall={mall}
|
|
onBack={() => setCouponShop(null)}
|
|
shop={couponShop}
|
|
></ShopCoupons>
|
|
</Modal>
|
|
)}
|
|
{showActivities && (
|
|
<Modal
|
|
isOpen={showActivities}
|
|
style={{
|
|
overlay: {
|
|
background: "transparent",
|
|
pointerEvents: "none",
|
|
},
|
|
}}
|
|
ariaHideApp={false}
|
|
className="activity-modal"
|
|
>
|
|
<Activities
|
|
initActivity={initActivity}
|
|
setInitActivity={setInitActivity}
|
|
memberID={memberID}
|
|
mall={mall}
|
|
onBack={() => setTab("地图")}
|
|
facilities={facilities}
|
|
onGo={(fac) => {
|
|
setTab("地图");
|
|
map && map.focusFacilityById(fac.id);
|
|
}}
|
|
></Activities>
|
|
</Modal>
|
|
)}
|
|
{showFindCar && mall && (
|
|
<Modal
|
|
isOpen={!!(showFindCar && mall)}
|
|
style={{
|
|
overlay: {
|
|
background: "transparent",
|
|
pointerEvents: "none",
|
|
},
|
|
}}
|
|
ariaHideApp={false}
|
|
className="car-wrapper"
|
|
>
|
|
<Car
|
|
hasReverse={
|
|
mall.menu.find(({ name }) => name === "寻车")?.specialType === 1
|
|
}
|
|
plate={plate}
|
|
lots={mall.lots}
|
|
onBack={() => setTab("地图")}
|
|
onLot={(e) => {
|
|
setDoFocus(2);
|
|
map.focusPByHouseNum(e);
|
|
setTab("地图");
|
|
}}
|
|
></Car>
|
|
</Modal>
|
|
)}
|
|
{showARPrompt && (
|
|
<Modal
|
|
isOpen={showARPrompt}
|
|
style={{
|
|
overlay: { zIndex: 10001, background: `rgba(0, 0, 0, 0.6)` },
|
|
}}
|
|
ariaHideApp={false}
|
|
className="prompt"
|
|
>
|
|
<img className="icon" src={arpng} />
|
|
<div className="title">即将离开模拟导航 进入AR导航</div>
|
|
<div className="meta">是否要继续?</div>
|
|
<div className="btns">
|
|
<div className="btn2" onClick={() => setShowARPrompt(false)}>
|
|
取消
|
|
</div>
|
|
<div
|
|
className="btn1"
|
|
onClick={() => {
|
|
if (openid && openid !== "null") {
|
|
const isShop = "intro" in ARshop;
|
|
const isP = ARshop.isP;
|
|
const isDevice = ARshop.isDevice;
|
|
setStatistics({
|
|
userId: openid,
|
|
navType: 1,
|
|
pointType: isShop || isDevice ? "1" : isP ? "3" : "2",
|
|
objectCode: isShop
|
|
? ARshop.code
|
|
: isP
|
|
? ARshop.houseNum
|
|
: ARshop.Type,
|
|
objectName: ARshop.name,
|
|
floorName:
|
|
ARshop.floorName || mall.floors[ARshop.floorOrder][1],
|
|
});
|
|
}
|
|
setShowARPrompt(false);
|
|
window.wx.miniProgram.redirectTo({
|
|
url: `/pages/index/index?e=${
|
|
ARshop.houseNum
|
|
? ARshop.houseNum
|
|
: ARshop.isDevice
|
|
? `${ARshop.floorOrder}_${ARshop.navPoint}_${ARshop.name}`
|
|
: encodeURIComponent(ARshop.id)
|
|
}&searchType=${searchType}`,
|
|
});
|
|
}}
|
|
>
|
|
确定
|
|
</div>
|
|
</div>
|
|
</Modal>
|
|
)}
|
|
{!online && (
|
|
<Modal
|
|
isOpen={!online}
|
|
style={{ overlay: { zIndex: 10001, background: "#fff" } }}
|
|
ariaHideApp={false}
|
|
className="offline"
|
|
>
|
|
<img className="img" src={offline}></img>
|
|
</Modal>
|
|
)}
|
|
<Coupons
|
|
show={showCoupon}
|
|
memberID={memberID}
|
|
isShop={isShop}
|
|
mall={mall}
|
|
></Coupons>
|
|
<div className={"hud " + (isTyping ? "bg" : "")}>
|
|
{!(start || end) && (
|
|
<div
|
|
className="top-left"
|
|
onClick={async () => {
|
|
const { msg } = await post("/api/ar/v1/applet/GetUserAward", {
|
|
memberID,
|
|
poiCode: "97be8faa6ab34e08864bf2b1c231e6ab",
|
|
});
|
|
window.weui.toast(msg, {
|
|
className: "toast",
|
|
});
|
|
}}
|
|
>
|
|
<img alt="图左" src={pos} className="left"></img>
|
|
<span style={{ color: "#7A7E8D" }}>{mall && mall.city}</span>
|
|
<div className="border"></div>
|
|
<span>{mall && mall.name}</span>
|
|
</div>
|
|
)}
|
|
{showHeadBar && (
|
|
<HeadBar
|
|
mall={mall}
|
|
isPick={isPick}
|
|
setIsPick={setIsPick}
|
|
start={start}
|
|
end={end}
|
|
floors={mall.floors}
|
|
shop={shop}
|
|
exit={exitFromNav}
|
|
onSwap={swap}
|
|
onSetStart={(shop) => {
|
|
setStart(shop);
|
|
map.startNavigate({ start: shop, end });
|
|
}}
|
|
onSetEnd={(shop) => {
|
|
setEnd(shop);
|
|
map.startNavigate({ start, end: shop });
|
|
}}
|
|
blurMap={() => {
|
|
map.blurShop();
|
|
map.blurFacility();
|
|
}}
|
|
searchType={searchType}
|
|
onClickSearchType={(id) => {
|
|
if (id === searchType) return;
|
|
setSearchType(id);
|
|
map && map.changeSearchType(id);
|
|
}}
|
|
showSearchType={start && end}
|
|
onIsTypingChange={setIsTyping}
|
|
></HeadBar>
|
|
)}
|
|
|
|
{((!(start && end) && !isTyping) || showHeadBarSearchType) && (
|
|
<More
|
|
showHeadBar={showHeadBar}
|
|
displayMode={displayMode}
|
|
searchType={searchType}
|
|
playAudio={playAudio}
|
|
setShowOptions={setShowOptions}
|
|
onClickDisplayMode={(id) => {
|
|
if (id === displayMode) return;
|
|
setDisplayMode(id);
|
|
map && map.changeDisplayMode(id);
|
|
}}
|
|
onClickSearchType={(id) => {
|
|
if (id === searchType) return;
|
|
setSearchType(id);
|
|
map && map.changeSearchType(id);
|
|
}}
|
|
></More>
|
|
)}
|
|
{!isTyping && !showHeadBar && (
|
|
<>
|
|
<img
|
|
className={[
|
|
"compass",
|
|
showHeadBar ? "has-header-top" : "",
|
|
showNav ? "has-nav-text-top" : "",
|
|
start && end ? "has-search-type-top" : "",
|
|
].join(" ")}
|
|
src={compass}
|
|
style={{
|
|
transform: `rotate(${
|
|
azimuthAngle + (mall ? mall.offsetToNorth : 0)
|
|
}deg)`,
|
|
}}
|
|
onClick={() =>
|
|
map && !showNav && map.changeFloor(sceneIndex, true)
|
|
}
|
|
/>
|
|
</>
|
|
)}
|
|
</div>
|
|
<div className="qmmap" id={mapId}></div>
|
|
|
|
<Shops
|
|
mall={mall}
|
|
isOpen={showShops}
|
|
onRequestClose={() => setShowShops(false)}
|
|
onClick={({ houseNum }) => {
|
|
setShowShops(false);
|
|
setDoFocus(2);
|
|
map.focusShopByHouseNum(houseNum);
|
|
}}
|
|
onClose={() => setShowShops(false)}
|
|
></Shops>
|
|
<Popup
|
|
baseUrl={mall && mall.baseUrl}
|
|
showPopup={showPopup}
|
|
defaultPopup={
|
|
showDefaultPopup && (
|
|
<DefaultPopup
|
|
hasTab={hasTab}
|
|
state={defaultPopupState}
|
|
setState={setDefaultPopupState}
|
|
facilities={facilities}
|
|
onSearch={() => {
|
|
setShowShops(true);
|
|
}}
|
|
onClickFac={(id) => {
|
|
setDoFocus(2);
|
|
map && map.focusFacilityById(id);
|
|
}}
|
|
setEnd={(fac) => {
|
|
setEnd(fac);
|
|
setShop(null);
|
|
}}
|
|
blurMap={() => {
|
|
setShop(null);
|
|
map.blurShop();
|
|
map.blurFacility();
|
|
}}
|
|
mall={mall}
|
|
onClick={({ houseNum }) => {
|
|
setShowShops(false);
|
|
setDoFocus(2);
|
|
map.focusShopByHouseNum(houseNum);
|
|
}}
|
|
></DefaultPopup>
|
|
)
|
|
}
|
|
floors={
|
|
mall &&
|
|
sceneIndex !== null &&
|
|
(defaultPopupState !== DefaultPopupStates.moreFac ||
|
|
!showDefaultPopup) && (
|
|
<Floors
|
|
end={end}
|
|
clickable={map && !showNav}
|
|
showNav={showNav}
|
|
onClickFloor={map && map.changeFloor}
|
|
floors={mall.floors}
|
|
sceneIndex={sceneIndex}
|
|
setSceneIndex={setSceneIndex}
|
|
isNavEnd={isNavEnd}
|
|
onActivity={() => {
|
|
setShowActivities(true);
|
|
}}
|
|
mall={mall}
|
|
hasCoupon={hasCoupon}
|
|
></Floors>
|
|
)
|
|
}
|
|
shop={shop}
|
|
closePopup={() => {
|
|
setShop(null);
|
|
history.replace(`/?openid=${openid}`);
|
|
map.blurShop();
|
|
map.blurFacility();
|
|
}}
|
|
showDetail={() => setShop({ ...shop, showDetail: true })}
|
|
setEnd={() => {
|
|
setEnd(shop);
|
|
setShop(null);
|
|
}}
|
|
handleAR={(shop) => {
|
|
setARShop(shop);
|
|
setShowARPrompt(true);
|
|
}}
|
|
onClickCoupon={() => {
|
|
setCouponShop(shop);
|
|
}}
|
|
></Popup>
|
|
{showNav && (
|
|
<NavBottom
|
|
baseUrl={mall && mall.baseUrl}
|
|
routeSearchAnimationType={map.routeSearchAnimationType()}
|
|
switchType={() =>
|
|
map.changeRouteSearchAnimationType(
|
|
map.routeSearchAnimationType() === 1 ? 2 : 1
|
|
)
|
|
}
|
|
onExit={exitFromNav}
|
|
end={end}
|
|
meters={Math.floor(navigation.totalDistanceInMeter * (1 - percent))}
|
|
minutes={Math.floor(
|
|
(navigation.totalDistanceInMeter * (1 - percent)) / 1.4 / 60
|
|
)}
|
|
puaseOrResume={() => {
|
|
if (paused) navigation.resume();
|
|
else navigation.pause();
|
|
}}
|
|
paused={paused}
|
|
startText={mall.floors[start.floorOrder][1]}
|
|
routeSearchText={routeSearchText}
|
|
percent={percent}
|
|
elevations={elevations}
|
|
handleAR={(shop) => {
|
|
setARShop(shop);
|
|
setShowARPrompt(true);
|
|
}}
|
|
></NavBottom>
|
|
)}
|
|
{isNavEnd && (
|
|
<div
|
|
className="nav-button"
|
|
onClick={() => {
|
|
map.startNavigate({ start, end });
|
|
}}
|
|
>
|
|
开始导航
|
|
</div>
|
|
)}
|
|
{mall && mall.menu.length > 1 && (
|
|
<div className="tab-bar">
|
|
{mall.menu.map(({ name, alias }) => {
|
|
const isActive = tab === name;
|
|
return (
|
|
<div
|
|
key={name}
|
|
className={`tab ${isActive ? "active" : ""}`}
|
|
onClick={() => setTab(name)}
|
|
>
|
|
<img
|
|
src={isActive ? TabMap[name].logoActive : TabMap[name].logo}
|
|
></img>
|
|
{alias || name}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</MallCode.Provider>
|
|
);
|
|
};
|
|
export default Index;
|
|
|