升级openlayers;新增骨架图,提供即时视觉反馈
This commit is contained in:
8
package-lock.json
generated
8
package-lock.json
generated
@@ -32,7 +32,7 @@
|
|||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"next": "^15.2.4",
|
"next": "^15.2.4",
|
||||||
"next-auth": "^4.24.5",
|
"next-auth": "^4.24.5",
|
||||||
"ol": "^10.6.1",
|
"ol": "^10.7.0",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
@@ -15391,9 +15391,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ol": {
|
"node_modules/ol": {
|
||||||
"version": "10.6.1",
|
"version": "10.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/ol/-/ol-10.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/ol/-/ol-10.7.0.tgz",
|
||||||
"integrity": "sha512-xp174YOwPeLj7c7/8TCIEHQ4d41tgTDDhdv6SqNdySsql5/MaFJEJkjlsYcvOPt7xA6vrum/QG4UdJ0iCGT1cg==",
|
"integrity": "sha512-122U5gamPqNgLpLOkogFJhgpywvd/5en2kETIDW+Ubfi9lPnZ0G9HWRdG+CX0oP8od2d6u6ky3eewIYYlrVczw==",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/rbush": "4.0.0",
|
"@types/rbush": "4.0.0",
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"next": "^15.2.4",
|
"next": "^15.2.4",
|
||||||
"next-auth": "^4.24.5",
|
"next-auth": "^4.24.5",
|
||||||
"ol": "^10.6.1",
|
"ol": "^10.7.0",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
|
|||||||
5
src/app/(main)/burst-pipe-analysis/loading.tsx
Normal file
5
src/app/(main)/burst-pipe-analysis/loading.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { MapSkeleton } from "@components/loading/MapSkeleton";
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <MapSkeleton />;
|
||||||
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
import React from "react";
|
import React, { Suspense } from "react";
|
||||||
import { RefineContext } from "../_refine_context";
|
import { RefineContext } from "../_refine_context";
|
||||||
|
|
||||||
import authOptions from "@app/api/auth/[...nextauth]/options";
|
import authOptions from "@app/api/auth/[...nextauth]/options";
|
||||||
import { Header } from "@components/header";
|
import { Header } from "@components/header";
|
||||||
import { Title } from "@components/title";
|
import { Title } from "@components/title";
|
||||||
|
import { MapSkeleton } from "@components/loading/MapSkeleton";
|
||||||
import { ThemedLayout } from "@refinedev/mui";
|
import { ThemedLayout } from "@refinedev/mui";
|
||||||
import { getServerSession } from "next-auth/next";
|
import { getServerSession } from "next-auth/next";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
@@ -43,7 +44,9 @@ export default async function MainLayout({
|
|||||||
sx: { height: "100%" },
|
sx: { height: "100%" },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
<Suspense fallback={<MapSkeleton />}>
|
||||||
|
{children}
|
||||||
|
</Suspense>
|
||||||
</ThemedLayout>
|
</ThemedLayout>
|
||||||
</RefineContext>
|
</RefineContext>
|
||||||
);
|
);
|
||||||
|
|||||||
5
src/app/(main)/monitoring-place-optimization/loading.tsx
Normal file
5
src/app/(main)/monitoring-place-optimization/loading.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { MapSkeleton } from "@components/loading/MapSkeleton";
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <MapSkeleton />;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { MapSkeleton } from "@components/loading/MapSkeleton";
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <MapSkeleton />;
|
||||||
|
}
|
||||||
5
src/app/(main)/network-simulation/loading.tsx
Normal file
5
src/app/(main)/network-simulation/loading.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { MapSkeleton } from "@components/loading/MapSkeleton";
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <MapSkeleton />;
|
||||||
|
}
|
||||||
5
src/app/(main)/scada-data-cleaning/loading.tsx
Normal file
5
src/app/(main)/scada-data-cleaning/loading.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { MapSkeleton } from "@components/loading/MapSkeleton";
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <MapSkeleton />;
|
||||||
|
}
|
||||||
174
src/components/loading/MapSkeleton.tsx
Normal file
174
src/components/loading/MapSkeleton.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user