添加地图点击基地,数据填报bug修改
This commit is contained in:
parent
2eb818b61d
commit
7ab91f158e
@ -22,7 +22,9 @@
|
|||||||
<a-button v-else type="primary" size="small" class="mr-2" @click="saveBtn">
|
<a-button v-else type="primary" size="small" class="mr-2" @click="saveBtn">
|
||||||
保存信息
|
保存信息
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button type="primary" size="small"> 修改记录 </a-button>
|
<a-button type="primary" size="small" @click="recordBtn">
|
||||||
|
修改记录
|
||||||
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-left" v-if="item.visible">
|
<div class="col-left" v-if="item.visible">
|
||||||
@ -69,6 +71,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
<a-modal
|
||||||
|
v-model:open="visible"
|
||||||
|
title="修改记录"
|
||||||
|
:footer="null"
|
||||||
|
width="900px"
|
||||||
|
:zIndex="2000"
|
||||||
|
>
|
||||||
|
123
|
||||||
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</template>
|
</template>
|
||||||
@ -87,7 +98,7 @@ const props = defineProps({
|
|||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const value1 = ref(dayjs("2009-04-01"));
|
const visible = ref(false);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const tabledata = ref([]);
|
const tabledata = ref([]);
|
||||||
console.log(BasicColumns);
|
console.log(BasicColumns);
|
||||||
@ -114,6 +125,9 @@ const saveBtn = () => {
|
|||||||
isEdit.value = false;
|
isEdit.value = false;
|
||||||
console.log(tabledata.value);
|
console.log(tabledata.value);
|
||||||
};
|
};
|
||||||
|
const recordBtn = () => {
|
||||||
|
visible.value = true;
|
||||||
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const data = {
|
const data = {
|
||||||
|
|||||||
@ -24,12 +24,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<template #rightExtra>
|
<template #rightExtra>
|
||||||
<a-tooltip :title="!isEngConfig ? '' : '该电站无专题配置'">
|
<a-tooltip :title="!isEngConfig ? '' : '该电站无专题配置'">
|
||||||
<a-button type="primary" :disabled="isEngConfig">
|
<a-button type="primary" :disabled="isEngConfig">
|
||||||
<i class="icon iconfont icon-topic mr-[5px]"></i>
|
<i class="icon iconfont icon-topic mr-[5px]"></i>
|
||||||
电站专题
|
电站专题
|
||||||
</a-button
|
</a-button></a-tooltip
|
||||||
></a-tooltip>
|
>
|
||||||
</template>
|
</template>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
@ -68,12 +68,11 @@ const props = defineProps<{
|
|||||||
// 添加 'update:activeKey' 以支持 v-model:active-key
|
// 添加 'update:activeKey' 以支持 v-model:active-key
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "update:visible", value: boolean): void;
|
(e: "update:visible", value: boolean): void;
|
||||||
(e: "update:activeKey", key: string): void;
|
|
||||||
(e: "change", key: string): void;
|
(e: "change", key: string): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// 内部维护的 activeKey
|
// 内部维护的 activeKey
|
||||||
const currentActiveKey = ref<string>(props.activeKey || "");
|
const currentActiveKey = ref<string>("");
|
||||||
|
|
||||||
// 监听外部传入的 activeKey 变化,同步到内部状态
|
// 监听外部传入的 activeKey 变化,同步到内部状态
|
||||||
watch(
|
watch(
|
||||||
@ -89,6 +88,8 @@ watch(
|
|||||||
() => modelStore.params,
|
() => modelStore.params,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
tabsConfig.value = handleTabs(newVal);
|
tabsConfig.value = handleTabs(newVal);
|
||||||
|
let value = tabsConfig.value.find((item: any) => item.default);
|
||||||
|
currentActiveKey.value = value?.key;
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
@ -96,7 +97,6 @@ watch(
|
|||||||
const onTabChange = (key: string) => {
|
const onTabChange = (key: string) => {
|
||||||
currentActiveKey.value = key;
|
currentActiveKey.value = key;
|
||||||
// 通知父组件更新 activeKey (支持 v-model)
|
// 通知父组件更新 activeKey (支持 v-model)
|
||||||
emit("update:activeKey", key);
|
|
||||||
// 通知父组件发生了切换事件 (用于业务逻辑,如加载数据)
|
// 通知父组件发生了切换事件 (用于业务逻辑,如加载数据)
|
||||||
emit("change", key);
|
emit("change", key);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,7 +17,8 @@ const ENGTabs: Array<any> = [
|
|||||||
name: '基础信息',
|
name: '基础信息',
|
||||||
key: 'basicInfo',
|
key: 'basicInfo',
|
||||||
type: 'basic',
|
type: 'basic',
|
||||||
url: '/bbi/siteBipc/getSiteBasicInfo'
|
url: '/bbi/siteBipc/getSiteBasicInfo',
|
||||||
|
default: true // 默认显示
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '阶段属性',
|
name: '阶段属性',
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -67,7 +67,9 @@ export class MapOl implements MapInterface {
|
|||||||
private pointLayerRegistry: Map<string, VectorLayer> = new Map();
|
private pointLayerRegistry: Map<string, VectorLayer> = new Map();
|
||||||
geoJsonData: any = null;
|
geoJsonData: any = null;
|
||||||
geoJsonData1: any = null;
|
geoJsonData1: any = null;
|
||||||
|
// ✅ 新增:声明用于存储 mask 事件监听器的引用,以便后续移除
|
||||||
|
private _maskPrerender: any = null;
|
||||||
|
private _maskPostrender: any = null;
|
||||||
// private BASEID: string = '01';
|
// private BASEID: string = '01';
|
||||||
constructor() {
|
constructor() {
|
||||||
this.loadGeoJsonData();
|
this.loadGeoJsonData();
|
||||||
@ -75,18 +77,31 @@ export class MapOl implements MapInterface {
|
|||||||
}
|
}
|
||||||
private async loadGeoJsonData(): Promise<void> {
|
private async loadGeoJsonData(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/data/geoJson.json')
|
const response = await fetch('/data/geoJson.json');
|
||||||
this.geoJsonData = await response.json()
|
this.geoJsonData = await response.json();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('配置加载失败:', error)
|
console.error('配置加载失败:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async loadGeoJsonData1(): Promise<void> {
|
private async loadGeoJsonData1(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/data/geoJson1.json')
|
const response = await fetch('/data/geoJson1.json');
|
||||||
this.geoJsonData1 = await response.json()
|
let res = await response.json();
|
||||||
|
let json1 = {
|
||||||
|
crs: res.crs,
|
||||||
|
features: [],
|
||||||
|
totalFeatures: res.totalFeatures,
|
||||||
|
type: res.type
|
||||||
|
};
|
||||||
|
for (let i = 0; i < res.features.length; i++) {
|
||||||
|
if (res.features[i].properties.BASEID === '12') {
|
||||||
|
json1.features.push(res.features[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(json1);
|
||||||
|
this.geoJsonData1 = json1;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('配置加载失败:', error)
|
console.error('配置加载失败:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//地图初始化
|
//地图初始化
|
||||||
@ -238,14 +253,7 @@ export class MapOl implements MapInterface {
|
|||||||
const features: Feature[] = [];
|
const features: Feature[] = [];
|
||||||
|
|
||||||
dataArray.forEach((item: any) => {
|
dataArray.forEach((item: any) => {
|
||||||
const {
|
const { lgtd, lttd, stnm, iconCode, titleName, ennm } = item;
|
||||||
lgtd,
|
|
||||||
lttd,
|
|
||||||
stnm,
|
|
||||||
iconCode,
|
|
||||||
titleName,
|
|
||||||
ennm
|
|
||||||
} = item;
|
|
||||||
|
|
||||||
if (lgtd == null || lttd == null) {
|
if (lgtd == null || lttd == null) {
|
||||||
return;
|
return;
|
||||||
@ -317,7 +325,7 @@ export class MapOl implements MapInterface {
|
|||||||
// 如果 currentResolution 变小 (放大地图),ratio 变大 -> icon 变大
|
// 如果 currentResolution 变小 (放大地图),ratio 变大 -> icon 变大
|
||||||
// 限制最大和最小缩放,防止过大或过小
|
// 限制最大和最小缩放,防止过大或过小
|
||||||
// let dynamicScale = baseScale * (baseResolution / (currentResolution || 1));
|
// let dynamicScale = baseScale * (baseResolution / (currentResolution || 1));
|
||||||
const currentZoom:any = this.view ? this.view.getZoom() : 4.5;
|
const currentZoom: any = this.view ? this.view.getZoom() : 4.5;
|
||||||
let dynamicScale = 0.7 + (currentZoom - 4.5) * 0.08;
|
let dynamicScale = 0.7 + (currentZoom - 4.5) * 0.08;
|
||||||
|
|
||||||
// 限制范围:最小 0.5,最大 3.0 (可根据需求调整)
|
// 限制范围:最小 0.5,最大 3.0 (可根据需求调整)
|
||||||
@ -464,32 +472,34 @@ export class MapOl implements MapInterface {
|
|||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
// ✅ 3. 调整 zIndex,确保在底图之上可见
|
// ✅ 3. 调整 zIndex,确保在底图之上可见
|
||||||
zIndex: 100,
|
zIndex: 101,
|
||||||
visible: true
|
visible: true
|
||||||
});
|
});
|
||||||
// 监听数据加载完成事件
|
// 监听数据加载完成事件
|
||||||
// vectorSource.on('featuresloadend', () => {
|
vectorSource.on('featuresloadend', () => {
|
||||||
// // 获取所有加载的要素
|
// 获取所有加载的要素
|
||||||
// const features = vectorSource.getFeatures();
|
const features = vectorSource.getFeatures();
|
||||||
// const feature = features[0];
|
const feature = features[0];
|
||||||
// const geometry = feature.getGeometry();
|
const geometry = feature.getGeometry();
|
||||||
// console.log(geometry)
|
console.log(geometry);
|
||||||
// // this.addClipToRasterLayer(this.layerRegistry.get(this.REGISTRY_KEY), geometry);
|
// this.addClipToRasterLayer(this.layerRegistry.get(this.REGISTRY_KEY), geometry);
|
||||||
// // this.applyMapMask(geometry);
|
// this.applyMapMask(geometry);
|
||||||
// });
|
});
|
||||||
// 4. 注册与添加
|
// 4. 注册与添加
|
||||||
this.layerRegistry.set(layer.key, vectorLayer);
|
this.layerRegistry.set(layer.key, vectorLayer);
|
||||||
this.map.addLayer(vectorLayer);
|
// this.map.addLayer(vectorLayer);
|
||||||
layer._layer = vectorLayer;
|
layer._layer = vectorLayer;
|
||||||
|
const targetBaseLayer = this.layerRegistry.get(this.REGISTRY_KEY);
|
||||||
|
this.applyMapMask(targetBaseLayer as TileLayer, this.geoJsonData1);
|
||||||
|
|
||||||
console.log(`矢量图层 [${layer.key}] 已加载: ${layer.url}`);
|
console.log(`矢量图层 [${layer.key}] 已加载: ${layer.url}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 为栅格图层添加裁切效果
|
* 为栅格图层添加裁切效果
|
||||||
* @param layer 栅格图层(TileLayer)
|
* @param layer 栅格图层(TileLayer)
|
||||||
* @param clipGeometry 裁切几何(Polygon 或 MultiPolygon,EPSG:3857 投影)
|
* @param clipGeometry 裁切几何(Polygon 或 MultiPolygon,EPSG:3857 投影)
|
||||||
*/
|
*/
|
||||||
// private addClipToRasterLayer(layer: TileLayer<any>, clipGeometry: Geometry): void {
|
// private addClipToRasterLayer(layer: TileLayer<any>, clipGeometry: Geometry): void {
|
||||||
// if (!layer || !clipGeometry) return;
|
// if (!layer || !clipGeometry) return;
|
||||||
|
|
||||||
@ -570,6 +580,24 @@ export class MapOl implements MapInterface {
|
|||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
// 在 addBaseDataLayer 方法的 vector 分支末尾,或者专门提供一个方法来激活遮罩
|
||||||
|
enableNortheastMask(): void {
|
||||||
|
// 1. 获取全量底图图层
|
||||||
|
const baseLayer = this.layerRegistry.get(this.REGISTRY_KEY);
|
||||||
|
|
||||||
|
// 2. 检查是否已加载东北边界数据
|
||||||
|
if (!this.geoJsonData1) {
|
||||||
|
console.warn('东北边界数据尚未加载');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baseLayer && baseLayer instanceof TileLayer) {
|
||||||
|
console.log('正在应用东北区域遮罩...');
|
||||||
|
this.applyMapMask(baseLayer, this.geoJsonData1);
|
||||||
|
} else {
|
||||||
|
console.warn('未找到全量底图图层或图层类型错误');
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 控制特定区域图层的显示(互斥显示)
|
* 控制特定区域图层的显示(互斥显示)
|
||||||
* @param regionId 区域ID (例如 "hebei", "13", "01" 等,需与图层 Key 或属性对应)
|
* @param regionId 区域ID (例如 "hebei", "13", "01" 等,需与图层 Key 或属性对应)
|
||||||
@ -1188,7 +1216,156 @@ export class MapOl implements MapInterface {
|
|||||||
container.appendChild(closeBtn);
|
container.appendChild(closeBtn);
|
||||||
this.map.addOverlay(overlay);
|
this.map.addOverlay(overlay);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 为栅格图层添加基于矢量的裁切效果
|
||||||
|
* @param rasterLayer 需要被裁切的底图图层 (TileLayer)
|
||||||
|
* @param clipGeoJson GeoJSON 格式的裁切边界数据
|
||||||
|
*/
|
||||||
|
private applyMapMask(rasterLayer: TileLayer, clipGeoJson: any): void {
|
||||||
|
if (!rasterLayer || !clipGeoJson) return;
|
||||||
|
|
||||||
|
// 1. 解析 GeoJSON
|
||||||
|
const features = new GeoJSON().readFeatures(clipGeoJson, {
|
||||||
|
dataProjection: 'EPSG:4326',
|
||||||
|
featureProjection: 'EPSG:3857'
|
||||||
|
});
|
||||||
|
|
||||||
|
// if (!features || features.length === 0) {
|
||||||
|
// console.warn('裁切数据为空');
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // ✅ 调试:添加绿线图层
|
||||||
|
// const debugVectorSource = new VectorSource({ features: features });
|
||||||
|
// let debugLayer = this.map!.getLayers()
|
||||||
|
// .getArray()
|
||||||
|
// .find((l: any) => l.get('isDebugMask'));
|
||||||
|
// if (debugLayer) {
|
||||||
|
// this.map!.removeLayer(debugLayer);
|
||||||
|
// }
|
||||||
|
// debugLayer = new VectorLayer({
|
||||||
|
// source: debugVectorSource,
|
||||||
|
// style: new Style({
|
||||||
|
// stroke: new Stroke({ color: '#00FF00', width: 2 }),
|
||||||
|
// fill: new Fill({ color: 'rgba(0, 255, 0, 0.1)' })
|
||||||
|
// }),
|
||||||
|
// zIndex: 9999,
|
||||||
|
// visible: true
|
||||||
|
// });
|
||||||
|
// debugLayer.set('isDebugMask', true);
|
||||||
|
// this.map!.addLayer(debugLayer);
|
||||||
|
|
||||||
|
// 移除旧监听器
|
||||||
|
if (this._maskPrerender) {
|
||||||
|
rasterLayer.un('prerender', this._maskPrerender);
|
||||||
|
}
|
||||||
|
if (this._maskPostrender) {
|
||||||
|
rasterLayer.un('postrender', this._maskPostrender);
|
||||||
|
}
|
||||||
|
|
||||||
|
const maskPrerender = (event: any) => {
|
||||||
|
const context = event.context;
|
||||||
|
if (!context || !this.map) return;
|
||||||
|
|
||||||
|
const frameState = event.frameState;
|
||||||
|
if (!frameState) return;
|
||||||
|
|
||||||
|
context.save();
|
||||||
|
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
context.beginPath();
|
||||||
|
|
||||||
|
let hasPath = false;
|
||||||
|
|
||||||
|
for (const feature of features) {
|
||||||
|
const geom: any = feature.getGeometry();
|
||||||
|
if (!geom) continue;
|
||||||
|
|
||||||
|
const type = geom.getType();
|
||||||
|
if (type === 'Polygon') {
|
||||||
|
const rings = geom.getCoordinates() as number[][][];
|
||||||
|
for (const ring of rings) {
|
||||||
|
// ✅ 传递 frameState 给 drawRing
|
||||||
|
this.drawRing(context, ring, frameState);
|
||||||
|
hasPath = true;
|
||||||
|
}
|
||||||
|
} else if (type === 'MultiPolygon') {
|
||||||
|
const polygons = geom.getCoordinates() as number[][][][];
|
||||||
|
for (const polygonRings of polygons) {
|
||||||
|
for (const ring of polygonRings) {
|
||||||
|
// ✅ 传递 frameState 给 drawRing
|
||||||
|
this.drawRing(context, ring, frameState);
|
||||||
|
hasPath = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasPath) {
|
||||||
|
context.strokeStyle = 'red';
|
||||||
|
context.lineWidth = 2;
|
||||||
|
context.stroke();
|
||||||
|
context.fillStyle = 'rgba(255, 255, 0, 0.2)';
|
||||||
|
context.fill();
|
||||||
|
// context.clip();
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
|
||||||
|
const maskPostrender = (event: any) => {
|
||||||
|
if (event.context) {
|
||||||
|
event.context.restore();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this._maskPrerender = maskPrerender;
|
||||||
|
this._maskPostrender = maskPostrender;
|
||||||
|
|
||||||
|
rasterLayer.on('prerender', this._maskPrerender);
|
||||||
|
rasterLayer.on('postrender', this._maskPostrender);
|
||||||
|
|
||||||
|
rasterLayer.changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private drawRing(
|
||||||
|
context: CanvasRenderingContext2D,
|
||||||
|
ring: number[][],
|
||||||
|
frameState: any
|
||||||
|
) {
|
||||||
|
if (!ring || ring.length === 0) return;
|
||||||
|
|
||||||
|
// ✅ 关键:获取当前 Canvas 的像素比(高清屏通常为 2)
|
||||||
|
// frameState.pixelRatio 是 OL 内部使用的像素比
|
||||||
|
const pixelRatio = frameState.pixelRatio || window.devicePixelRatio || 1;
|
||||||
|
|
||||||
|
for (let i = 0; i < ring.length; i++) {
|
||||||
|
const coord = ring[i];
|
||||||
|
|
||||||
|
if (!this.map || !Array.isArray(coord) || typeof coord[0] !== 'number')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// ✅ 1. 获取相对于地图容器的 CSS 像素坐标
|
||||||
|
const cssPixel = this.map.getPixelFromCoordinate(
|
||||||
|
coord as [number, number]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!cssPixel) continue;
|
||||||
|
|
||||||
|
// ✅ 2. 转换为 Canvas 内部物理像素坐标
|
||||||
|
// 因为我们在 maskPrerender 中执行了 context.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
// 此时 Canvas 的原点是左上角,单位是物理像素。
|
||||||
|
// 而 getPixelFromCoordinate 返回的是 CSS 像素。
|
||||||
|
// 所以必须乘以 pixelRatio。
|
||||||
|
const canvasX = cssPixel[0] * pixelRatio;
|
||||||
|
const canvasY = cssPixel[1] * pixelRatio;
|
||||||
|
|
||||||
|
if (i === 0) {
|
||||||
|
context.moveTo(canvasX, canvasY);
|
||||||
|
} else {
|
||||||
|
context.lineTo(canvasX, canvasY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.closePath();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 格式化长度输出 (米)
|
* 格式化长度输出 (米)
|
||||||
*/
|
*/
|
||||||
@ -1206,10 +1383,10 @@ export class MapOl implements MapInterface {
|
|||||||
return '面积:' + areaSqKm.toFixed(3) + 'km²';
|
return '面积:' + areaSqKm.toFixed(3) + 'km²';
|
||||||
}
|
}
|
||||||
|
|
||||||
mdLayerShowOrHidden(): void { }
|
mdLayerShowOrHidden(): void {}
|
||||||
switchView(): void { }
|
switchView(): void {}
|
||||||
fitBounds(): void { }
|
fitBounds(): void {}
|
||||||
flyTopanto(): void { }
|
flyTopanto(): void {}
|
||||||
/**
|
/**
|
||||||
* 移除地图对象,释放资源
|
* 移除地图对象,释放资源
|
||||||
*/
|
*/
|
||||||
@ -1219,9 +1396,11 @@ export class MapOl implements MapInterface {
|
|||||||
// 1. 清除量算相关资源
|
// 1. 清除量算相关资源
|
||||||
this.removeQueryLayer();
|
this.removeQueryLayer();
|
||||||
|
|
||||||
|
this._maskPrerender = null;
|
||||||
|
this._maskPostrender = null;
|
||||||
// 2. 清除所有通过 layerRegistry 管理的图层
|
// 2. 清除所有通过 layerRegistry 管理的图层
|
||||||
if (this.layerRegistry) {
|
if (this.layerRegistry) {
|
||||||
this.layerRegistry.forEach((layer) => {
|
this.layerRegistry.forEach(layer => {
|
||||||
if (this.map && this.map.getLayers().getArray().includes(layer)) {
|
if (this.map && this.map.getLayers().getArray().includes(layer)) {
|
||||||
this.map.removeLayer(layer);
|
this.map.removeLayer(layer);
|
||||||
}
|
}
|
||||||
@ -1231,7 +1410,7 @@ export class MapOl implements MapInterface {
|
|||||||
|
|
||||||
// ✅ 3. 清除点图层 Registry
|
// ✅ 3. 清除点图层 Registry
|
||||||
if (this.pointLayerRegistry) {
|
if (this.pointLayerRegistry) {
|
||||||
this.pointLayerRegistry.forEach((layer) => {
|
this.pointLayerRegistry.forEach(layer => {
|
||||||
if (this.map && this.map.getLayers().getArray().includes(layer)) {
|
if (this.map && this.map.getLayers().getArray().includes(layer)) {
|
||||||
this.map.removeLayer(layer);
|
this.map.removeLayer(layer);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useTagsViewStore } from "@/store/modules/tagsView";
|
|||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import MapModal from "@/components/MapModal/index.vue";
|
import MapModal from "@/components/MapModal/index.vue";
|
||||||
import { useModelStore } from "@/store/modules/model";
|
import { useModelStore } from "@/store/modules/model";
|
||||||
// import GisView from "@/components/gis/GisView.vue";
|
import GisView from "@/components/gis/GisView.vue";
|
||||||
|
|
||||||
const modelStore = useModelStore();
|
const modelStore = useModelStore();
|
||||||
|
|
||||||
@ -29,7 +29,6 @@ const routeKey = computed(() => router.path + Math.random());
|
|||||||
|
|
||||||
<MapModal
|
<MapModal
|
||||||
v-model:visible="modelStore.modalVisible"
|
v-model:visible="modelStore.modalVisible"
|
||||||
v-model:active-key="modelStore.currentTabKey"
|
|
||||||
:title="modelStore.title"
|
:title="modelStore.title"
|
||||||
:tabs-config="modelStore.tabList"
|
:tabs-config="modelStore.tabList"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -9,7 +9,27 @@ NProgress.configure({ showSpinner: false });
|
|||||||
const permissionStore = usePermissionStoreHook();
|
const permissionStore = usePermissionStoreHook();
|
||||||
|
|
||||||
// 白名单路由
|
// 白名单路由
|
||||||
const whiteList = ['/login','/register']; //login
|
const whiteList = ['/login', '/register']; //login
|
||||||
|
|
||||||
|
// ✅ 新增:递归标准化路由路径,确保所有 path 以 '/' 开头
|
||||||
|
function normalizeRoutes(routes: any[]): any[] {
|
||||||
|
return routes.map(route => {
|
||||||
|
// 创建副本以避免直接修改原始数据(可选,视具体需求而定)
|
||||||
|
const normalizedRoute = { ...route };
|
||||||
|
|
||||||
|
// 修正当前路由的 path
|
||||||
|
if (normalizedRoute.path && !normalizedRoute.path.startsWith('/')) {
|
||||||
|
normalizedRoute.path = `/${normalizedRoute.path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归修正子路由
|
||||||
|
if (normalizedRoute.children && normalizedRoute.children.length > 0) {
|
||||||
|
normalizedRoute.children = normalizeRoutes(normalizedRoute.children);
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizedRoute;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 查找第一个可用路由
|
// 查找第一个可用路由
|
||||||
function findFirstAvailableRoute(routes: any[]): string | undefined {
|
function findFirstAvailableRoute(routes: any[]): string | undefined {
|
||||||
@ -35,11 +55,11 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
|
|
||||||
if (userStore.Token) {
|
if (userStore.Token) {
|
||||||
// 登录成功,跳转到首页
|
// 登录成功,跳转到首页
|
||||||
if (to.path === '/login') {//login
|
if (to.path === '/login') {
|
||||||
|
//login
|
||||||
next({ path: '/' });
|
next({ path: '/' });
|
||||||
NProgress.done();
|
NProgress.done();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const hasGetUserInfo = userStore.roles.length > 0;
|
const hasGetUserInfo = userStore.roles.length > 0;
|
||||||
if (hasGetUserInfo) {
|
if (hasGetUserInfo) {
|
||||||
// 已获取用户信息,检查路由匹配
|
// 已获取用户信息,检查路由匹配
|
||||||
@ -60,7 +80,11 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const { roles } = await userStore.getInfo();
|
const { roles } = await userStore.getInfo();
|
||||||
const accessRoutes: RouteRecordRaw[] = await permissionStore.generateRoutes(roles);
|
let accessRoutes: RouteRecordRaw[] =
|
||||||
|
await permissionStore.generateRoutes(roles);
|
||||||
|
|
||||||
|
// ✅ 关键修复:在添加路由前,标准化所有路径
|
||||||
|
accessRoutes = normalizeRoutes(accessRoutes);
|
||||||
|
|
||||||
accessRoutes.forEach((route: any) => {
|
accessRoutes.forEach((route: any) => {
|
||||||
router.addRoute(route);
|
router.addRoute(route);
|
||||||
@ -85,7 +109,6 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 未登录可以访问白名单页面
|
// 未登录可以访问白名单页面
|
||||||
if (whiteList.indexOf(to.path) !== -1) {
|
if (whiteList.indexOf(to.path) !== -1) {
|
||||||
|
|||||||
@ -15,27 +15,27 @@ const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
|
|||||||
// ✅ 保存原始名称到 meta,用于菜单显示
|
// ✅ 保存原始名称到 meta,用于菜单显示
|
||||||
tmp.meta = {
|
tmp.meta = {
|
||||||
...tmp.meta,
|
...tmp.meta,
|
||||||
title: tmp.name || tmp.menuName, // 原始名称用于显示
|
title: tmp.name || tmp.menuName // 原始名称用于显示
|
||||||
};
|
};
|
||||||
// ✅ name 使用路径生成唯一值
|
// ✅ name 使用路径生成唯一值
|
||||||
tmp.name = tmp.path || tmp.opturl;
|
tmp.name = tmp.path || tmp.opturl;
|
||||||
|
|
||||||
// if (hasPermission(roles, tmp)) {
|
// if (hasPermission(roles, tmp)) {
|
||||||
tmp.path = tmp.opturl;
|
tmp.path = tmp.opturl;
|
||||||
if (tmp.type == '0') {
|
if (tmp.type == '0') {
|
||||||
tmp.component = Layout;
|
tmp.component = Layout;
|
||||||
|
} else {
|
||||||
|
const component = modules[`../../views${tmp.opturl}.vue`] as any;
|
||||||
|
if (component) {
|
||||||
|
tmp.component = component;
|
||||||
} else {
|
} else {
|
||||||
const component = modules[`../../views${tmp.opturl}.vue`] as any;
|
tmp.component = modules[`../../views/error-page/404.vue`];
|
||||||
if (component) {
|
|
||||||
tmp.component = component;
|
|
||||||
} else {
|
|
||||||
tmp.component = modules[`../../views/error-page/404.vue`];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res.push(tmp)
|
|
||||||
if (tmp.children) {
|
|
||||||
tmp.children = filterAsyncRoutes(tmp.children, roles);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
res.push(tmp);
|
||||||
|
if (tmp.children) {
|
||||||
|
tmp.children = filterAsyncRoutes(tmp.children, roles);
|
||||||
|
}
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
@ -57,7 +57,7 @@ export const usePermissionStore = defineStore('permission', () => {
|
|||||||
return new Promise<RouteRecordRaw[]>((resolve, reject) => {
|
return new Promise<RouteRecordRaw[]>((resolve, reject) => {
|
||||||
listRoutes()
|
listRoutes()
|
||||||
.then(response => {
|
.then(response => {
|
||||||
const asyncRoutes :any = response;
|
const asyncRoutes: any = response;
|
||||||
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
|
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
|
||||||
setRoutes(accessedRoutes);
|
setRoutes(accessedRoutes);
|
||||||
resolve(accessedRoutes);
|
resolve(accessedRoutes);
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import router from '@/router';
|
|||||||
// 创建 axios 实例
|
// 创建 axios 实例
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||||
timeout: 300000, // 5分钟
|
timeout: 15000, // 15秒
|
||||||
headers: { 'Content-Type': 'application/json;charset=utf-8' }
|
headers: { 'Content-Type': 'application/json;charset=utf-8' }
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -36,9 +36,9 @@ service.interceptors.response.use(
|
|||||||
const { status, msg } = response;
|
const { status, msg } = response;
|
||||||
if (status === 200) {
|
if (status === 200) {
|
||||||
if (response.data.code == 401) {
|
if (response.data.code == 401) {
|
||||||
message.error(response.data.msg||'请求失败');
|
message.error(response.data.msg || '请求失败');
|
||||||
return;
|
return;
|
||||||
}else if(response.data.code == 1){
|
} else if (response.data.code == 1) {
|
||||||
message.error(response.data.msg);
|
message.error(response.data.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ service.interceptors.response.use(
|
|||||||
if (response.data instanceof ArrayBuffer) {
|
if (response.data instanceof ArrayBuffer) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
message.error( msg || '系统出错');
|
message.error(msg || '系统出错');
|
||||||
return Promise.reject(new Error(msg || 'Error'));
|
return Promise.reject(new Error(msg || 'Error'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -58,15 +58,15 @@ service.interceptors.response.use(
|
|||||||
// token 过期,重新登录
|
// token 过期,重新登录
|
||||||
if (status === '403') {
|
if (status === '403') {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: "提示",
|
title: '提示',
|
||||||
content: "当前页面已失效,请重新登录",
|
content: '当前页面已失效,请重新登录',
|
||||||
okText: "确定",
|
okText: '确定',
|
||||||
cancelButtonProps: { disabled: false },
|
cancelButtonProps: { disabled: false },
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
router.push('/login');
|
router.push('/login');
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
message.error(msg || '当前页面已失效');
|
message.error(msg || '当前页面已失效');
|
||||||
|
|||||||
@ -34,7 +34,7 @@ const showMapModal = () => {
|
|||||||
};
|
};
|
||||||
const showMapModal1 = () => {
|
const showMapModal1 = () => {
|
||||||
modelStore.modalVisible = true;
|
modelStore.modalVisible = true;
|
||||||
modelStore.params.sttp = "ENG";
|
modelStore.params.sttp = "zh";
|
||||||
modelStore.title = "三峡222 详情信息";
|
modelStore.title = "三峡222 详情信息";
|
||||||
modelStore.currentTabKey = "basicInfo";
|
modelStore.currentTabKey = "basicInfo";
|
||||||
modelStore.isBasicEdit = false;
|
modelStore.isBasicEdit = false;
|
||||||
@ -53,7 +53,7 @@ const showMapModal1 = () => {
|
|||||||
<div class="rightContent">
|
<div class="rightContent">
|
||||||
<RightDrawer>
|
<RightDrawer>
|
||||||
<!-- <a-button @click="showMapModal">打开电站地图弹窗</a-button>
|
<!-- <a-button @click="showMapModal">打开电站地图弹窗</a-button>
|
||||||
<a-button @click="showMapModal1">打开地图弹窗1</a-button> -->
|
<a-button @click="showMapModal1">打开地图弹窗1</a-button> -->
|
||||||
|
|
||||||
<jidiInfoMod />
|
<jidiInfoMod />
|
||||||
<shuidianhuangjingjieruMod />
|
<shuidianhuangjingjieruMod />
|
||||||
|
|||||||
@ -723,6 +723,7 @@ const fileChange = (file: File) => {
|
|||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
await importFishZip(formData);
|
await importFishZip(formData);
|
||||||
|
if (visible.value) importBtn();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// 获取文件列表
|
// 获取文件列表
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user