升级openlayers;新增骨架图,提供即时视觉反馈

This commit is contained in:
JIANG
2025-11-10 09:49:55 +08:00
parent 6f014cbdd3
commit 5b4fcaa446
9 changed files with 209 additions and 7 deletions

8
package-lock.json generated
View File

@@ -32,7 +32,7 @@
"js-cookie": "^3.0.5",
"next": "^15.2.4",
"next-auth": "^4.24.5",
"ol": "^10.6.1",
"ol": "^10.7.0",
"postcss": "^8.5.6",
"react": "^19.1.0",
"react-dom": "^19.1.0",
@@ -15391,9 +15391,9 @@
}
},
"node_modules/ol": {
"version": "10.6.1",
"resolved": "https://registry.npmjs.org/ol/-/ol-10.6.1.tgz",
"integrity": "sha512-xp174YOwPeLj7c7/8TCIEHQ4d41tgTDDhdv6SqNdySsql5/MaFJEJkjlsYcvOPt7xA6vrum/QG4UdJ0iCGT1cg==",
"version": "10.7.0",
"resolved": "https://registry.npmjs.org/ol/-/ol-10.7.0.tgz",
"integrity": "sha512-122U5gamPqNgLpLOkogFJhgpywvd/5en2kETIDW+Ubfi9lPnZ0G9HWRdG+CX0oP8od2d6u6ky3eewIYYlrVczw==",
"license": "BSD-2-Clause",
"dependencies": {
"@types/rbush": "4.0.0",

View File

@@ -37,7 +37,7 @@
"js-cookie": "^3.0.5",
"next": "^15.2.4",
"next-auth": "^4.24.5",
"ol": "^10.6.1",
"ol": "^10.7.0",
"postcss": "^8.5.6",
"react": "^19.1.0",
"react-dom": "^19.1.0",

View File

@@ -0,0 +1,5 @@
import { MapSkeleton } from "@components/loading/MapSkeleton";
export default function Loading() {
return <MapSkeleton />;
}

View File

@@ -1,11 +1,12 @@
import type { Metadata } from "next";
import { cookies } from "next/headers";
import React from "react";
import React, { Suspense } from "react";
import { RefineContext } from "../_refine_context";
import authOptions from "@app/api/auth/[...nextauth]/options";
import { Header } from "@components/header";
import { Title } from "@components/title";
import { MapSkeleton } from "@components/loading/MapSkeleton";
import { ThemedLayout } from "@refinedev/mui";
import { getServerSession } from "next-auth/next";
import { redirect } from "next/navigation";
@@ -43,7 +44,9 @@ export default async function MainLayout({
sx: { height: "100%" },
}}
>
{children}
<Suspense fallback={<MapSkeleton />}>
{children}
</Suspense>
</ThemedLayout>
</RefineContext>
);

View File

@@ -0,0 +1,5 @@
import { MapSkeleton } from "@components/loading/MapSkeleton";
export default function Loading() {
return <MapSkeleton />;
}

View File

@@ -0,0 +1,5 @@
import { MapSkeleton } from "@components/loading/MapSkeleton";
export default function Loading() {
return <MapSkeleton />;
}

View File

@@ -0,0 +1,5 @@
import { MapSkeleton } from "@components/loading/MapSkeleton";
export default function Loading() {
return <MapSkeleton />;
}

View File

@@ -0,0 +1,5 @@
import { MapSkeleton } from "@components/loading/MapSkeleton";
export default function Loading() {
return <MapSkeleton />;
}

View File

@@ -0,0 +1,174 @@
import { Box, Skeleton } from "@mui/material";
/**
* 地图页面骨架屏组件
* 提供即时视觉反馈,模拟地图界面布局
*/
export function MapSkeleton() {
return (
<Box
sx={{
width: "100%",
height: "100%",
position: "relative",
bgcolor: "background.default",
overflow: "hidden",
}}
>
{/* 主地图区域骨架 */}
<Skeleton
variant="rectangular"
animation="wave"
sx={{
width: "100%",
height: "100%",
bgcolor: "action.hover",
}}
/>
{/* 左侧工具栏骨架 */}
<Box
sx={{
position: "absolute",
top: 20,
left: 20,
display: "flex",
flexDirection: "column",
gap: 1,
}}
>
{[1, 2, 3, 4, 5].map((i) => (
<Skeleton
key={i}
variant="rectangular"
width={48}
height={48}
animation="wave"
sx={{ borderRadius: 1 }}
/>
))}
</Box>
{/* 右侧控制面板骨架 */}
<Box
sx={{
position: "absolute",
top: 20,
right: 20,
width: 320,
bgcolor: "background.paper",
borderRadius: 2,
p: 2,
boxShadow: 3,
}}
>
<Skeleton width="60%" height={32} animation="wave" sx={{ mb: 2 }} />
<Skeleton width="100%" height={24} animation="wave" sx={{ mb: 1 }} />
<Skeleton width="80%" height={24} animation="wave" sx={{ mb: 1 }} />
<Skeleton width="90%" height={24} animation="wave" sx={{ mb: 2 }} />
<Skeleton
variant="rectangular"
width="100%"
height={200}
animation="wave"
sx={{ borderRadius: 1 }}
/>
</Box>
{/* 底部时间轴骨架 */}
<Box
sx={{
position: "absolute",
bottom: 20,
left: "50%",
transform: "translateX(-50%)",
width: "60%",
bgcolor: "background.paper",
borderRadius: 2,
p: 2,
boxShadow: 3,
}}
>
<Skeleton width="100%" height={40} animation="wave" />
</Box>
{/* 缩放控制骨架 */}
<Box
sx={{
position: "absolute",
bottom: 100,
right: 20,
display: "flex",
flexDirection: "column",
gap: 1,
}}
>
<Skeleton
variant="rectangular"
width={40}
height={40}
animation="wave"
sx={{ borderRadius: 1 }}
/>
<Skeleton
variant="rectangular"
width={40}
height={40}
animation="wave"
sx={{ borderRadius: 1 }}
/>
</Box>
{/* 比例尺骨架 */}
<Box
sx={{
position: "absolute",
bottom: 20,
left: 20,
}}
>
<Skeleton width={120} height={24} animation="wave" />
</Box>
</Box>
);
}
/**
* 简化版骨架屏 - 用于非地图页面
*/
export function SimpleSkeleton() {
return (
<Box
sx={{
width: "100%",
height: "100%",
p: 3,
bgcolor: "background.default",
}}
>
<Skeleton width="40%" height={40} animation="wave" sx={{ mb: 3 }} />
<Skeleton width="100%" height={60} animation="wave" sx={{ mb: 2 }} />
<Skeleton width="100%" height={300} animation="wave" sx={{ mb: 2 }} />
<Box sx={{ display: "flex", gap: 2, mb: 2 }}>
<Skeleton
variant="rectangular"
width="30%"
height={150}
animation="wave"
/>
<Skeleton
variant="rectangular"
width="30%"
height={150}
animation="wave"
/>
<Skeleton
variant="rectangular"
width="30%"
height={150}
animation="wave"
/>
</Box>
</Box>
);
}