[fix/feat]:[FL-60][线路管理中走向图渲染不出来]
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -758,6 +758,7 @@
|
||||
- 支持按风险着色、塔号显隐、居中重置。
|
||||
- 走向图统计信息固定包含:有效坐标、缺失坐标、断点段数、线路估算长度(Haversine)。
|
||||
- 对序号断档采用分段折线渲染,避免缺失坐标导致的跨段误连线。
|
||||
- 当前部署默认启用 `NEXT_PUBLIC_APP_BASE_PATH=/fl`;Cesium 组件初始化时,`window.CESIUM_BASE_URL` 必须通过 `withBasePath("/cesium")` 生成,禁止硬编码根路径 `"/cesium"`,否则子路径部署下会因静态资源 404 导致 Viewer 初始化失败、页面空白。
|
||||
|
||||
## 雷电流数据管理口径(2026-04-25)
|
||||
|
||||
|
||||
@@ -30,3 +30,32 @@
|
||||
|
||||
- 风险与关注点:
|
||||
- 本次修复只绕开 BuildKit builder 镜像对 Docker Hub 的依赖;后续若 `Dockerfile` 里的基础镜像或 `docker build --pull` 仍指向不稳定上游,构建阶段仍可能出现其他网络相关失败。
|
||||
|
||||
## Work Log - 修复线路管理走向图在 `/fl` 子路径下无法渲染(2026-06-09)
|
||||
|
||||
- 背景:
|
||||
- Issue `FL-60` 反馈“线路管理中走向图渲染不出来”。
|
||||
- 仓库部署默认启用 `NEXT_PUBLIC_APP_BASE_PATH=/fl`,但多个 Cesium 组件初始化时仍把 `window.CESIUM_BASE_URL` 硬编码为 `"/cesium"`。
|
||||
- 这会导致页面在 `/fl/admin/power-lines` 等子路径下请求错误的静态资源地址,最终触发 Cesium Viewer 初始化失败。
|
||||
|
||||
- 本次处理:
|
||||
- `web/src/components/power-line-cesium-map.tsx`
|
||||
- 将走向图 Cesium 静态资源根路径改为 `withBasePath("/cesium")`,修复线路管理走向图在 `/fl` 部署下的资源寻址。
|
||||
- `web/src/components/elevation-preview-cesium-map.tsx`
|
||||
- 同步改为 `withBasePath("/cesium")`,避免高程预览图在相同部署口径下继续空白。
|
||||
- `web/src/components/lightning-distribution-map.tsx`
|
||||
- 同步改为 `withBasePath("/cesium")`,保持雷电分布图与项目子路径部署口径一致。
|
||||
- 顺手补齐 `Viewer` / `CesiumNamespace` / `Cartesian3[]` 显式类型,消除本地 lint 暴露的 `no-explicit-any` 问题。
|
||||
|
||||
- 验证:
|
||||
- 基线:
|
||||
- 代码检查确认 `power-line-cesium-map.tsx`、`elevation-preview-cesium-map.tsx`、`lightning-distribution-map.tsx` 都存在 `window.CESIUM_BASE_URL = "/cesium"` 硬编码。
|
||||
- 部署配置检查确认 `deploy/pro-deploy/.env` 与 compose / Dockerfile 默认均为 `NEXT_PUBLIC_APP_BASE_PATH=/fl`。
|
||||
- 初次本地 lint 尝试因未安装前端依赖失败;补充执行 `NPM_CONFIG_CACHE=/tmp/npm-cache npm ci` 后继续验证。
|
||||
- 修改后:
|
||||
- `NPM_CONFIG_CACHE=/tmp/npm-cache npm --workspace web exec eslint src/components/power-line-cesium-map.tsx src/components/elevation-preview-cesium-map.tsx src/components/lightning-distribution-map.tsx src/app/admin/power-lines/page.tsx --max-warnings=0` -> 通过。
|
||||
- `NEXT_PUBLIC_APP_BASE_PATH=/fl NPM_CONFIG_CACHE=/tmp/npm-cache npm run build:web` -> 通过。
|
||||
|
||||
- 风险与关注点:
|
||||
- 本次修复聚焦前端静态资源路径,不涉及后端接口、数据库或权限逻辑。
|
||||
- 若后续新增 Cesium 页面,必须继续复用 `withBasePath("/cesium")`,不能再硬编码根路径。
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { Alert, Empty, Spin } from "antd";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { withBasePath } from "@/lib/base-path";
|
||||
import { reloadOnceOnChunkError } from "@/lib/chunk-error";
|
||||
import type { ElevationDatasetPreviewCell, ElevationDatasetPreviewPoint } from "@/types/auth";
|
||||
|
||||
@@ -108,7 +109,7 @@ export function ElevationPreviewCesiumMap({
|
||||
async function initViewer() {
|
||||
if (!containerRef.current || viewerRef.current) return;
|
||||
try {
|
||||
window.CESIUM_BASE_URL = "/cesium";
|
||||
window.CESIUM_BASE_URL = withBasePath("/cesium");
|
||||
const Cesium = await import("cesium");
|
||||
if (cancelled || !containerRef.current) return;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { withBasePath } from "@/lib/base-path";
|
||||
import type {
|
||||
LightningDistributionGridCell,
|
||||
LightningDistributionScatterPoint,
|
||||
@@ -13,6 +14,8 @@ type LightningDistributionMapProps = {
|
||||
loading?: boolean;
|
||||
};
|
||||
|
||||
type CesiumNamespace = typeof import("cesium");
|
||||
|
||||
function hasValidCoord(lon: number, lat: number): boolean {
|
||||
if (Number.isNaN(lon) || Number.isNaN(lat)) return false;
|
||||
return lon >= -180 && lon <= 180 && lat >= -90 && lat <= 90;
|
||||
@@ -41,8 +44,8 @@ export function LightningDistributionMap({
|
||||
loading = false,
|
||||
}: LightningDistributionMapProps) {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const viewerRef = useRef<any>(null);
|
||||
const cesiumRef = useRef<any>(null);
|
||||
const viewerRef = useRef<import("cesium").Viewer | null>(null);
|
||||
const cesiumRef = useRef<CesiumNamespace | null>(null);
|
||||
const [error, setError] = useState("");
|
||||
const [ready, setReady] = useState(false);
|
||||
|
||||
@@ -72,7 +75,7 @@ export function LightningDistributionMap({
|
||||
const Cesium = await import("cesium");
|
||||
if (disposed || !containerRef.current) return;
|
||||
|
||||
(window as typeof window & { CESIUM_BASE_URL?: string }).CESIUM_BASE_URL = "/cesium";
|
||||
(window as typeof window & { CESIUM_BASE_URL?: string }).CESIUM_BASE_URL = withBasePath("/cesium");
|
||||
Cesium.Ion.defaultAccessToken = "";
|
||||
|
||||
const viewer = new Cesium.Viewer(containerRef.current, {
|
||||
@@ -137,7 +140,7 @@ export function LightningDistributionMap({
|
||||
});
|
||||
});
|
||||
|
||||
const positions: any[] = [];
|
||||
const positions: import("cesium").Cartesian3[] = [];
|
||||
safePoints.forEach((point) => {
|
||||
const absCurrent = point.abs_current_ka ?? (point.current_ka ? Math.abs(point.current_ka) : null);
|
||||
const color = Cesium.Color.fromCssColorString(pointColorByAbsCurrent(absCurrent));
|
||||
|
||||
@@ -4,6 +4,7 @@ import { AimOutlined, MinusOutlined, PlusOutlined } from "@ant-design/icons";
|
||||
import { Alert, Button, Checkbox, Empty, Spin, Typography } from "antd";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { withBasePath } from "@/lib/base-path";
|
||||
import { reloadOnceOnChunkError } from "@/lib/chunk-error";
|
||||
import type { LineTowerSummary } from "@/types/auth";
|
||||
|
||||
@@ -238,7 +239,7 @@ export function PowerLineCesiumMap({
|
||||
}
|
||||
|
||||
try {
|
||||
window.CESIUM_BASE_URL = "/cesium";
|
||||
window.CESIUM_BASE_URL = withBasePath("/cesium");
|
||||
const Cesium = await import("cesium");
|
||||
if (cancelled || !containerRef.current) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user