|
|
@@ -1,106 +1,113 @@
|
|
|
<template>
|
|
|
- <div class="map-index">
|
|
|
- <div id="mapChart"></div>
|
|
|
- <div class="map-left">
|
|
|
- <div class="left-title">模型列表</div>
|
|
|
- <div class="left-tree">
|
|
|
- <el-card v-for="config in bizDataShowConfigList" class="biz-data-config-container">
|
|
|
- <div style="height: 200px;">
|
|
|
- <biz-display :config="config"></biz-display>
|
|
|
- </div>
|
|
|
- </el-card>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="map-right">
|
|
|
- <div class="right-title">模型数据展示</div>
|
|
|
- <div class="right-top-title">
|
|
|
- <img src="@/assets/map/img/站点.png"/>
|
|
|
- <span>预报站点信息</span>
|
|
|
- </div>
|
|
|
- <div class="station-table">
|
|
|
- <el-scrollbar style="height: 100%;">
|
|
|
- <table>
|
|
|
- <thead>
|
|
|
- <tr>
|
|
|
- <td class="table-index">序号</td>
|
|
|
- <td class="table-head">站码</td>
|
|
|
- <td class="table-head">站名</td>
|
|
|
- <td class="table-head">实时潮位</td>
|
|
|
- <td class="table-head">发生时间</td>
|
|
|
- <td class="table-head">警戒潮位</td>
|
|
|
- <td class="table-head">距离警戒</td>
|
|
|
- <td class="table-head">预报潮位</td>
|
|
|
- <td class="table-head">发生时间</td>
|
|
|
- <td class="table-head">距离警戒</td>
|
|
|
- </tr>
|
|
|
- </thead>
|
|
|
- <tbody>
|
|
|
- <tr
|
|
|
- v-for="(item,index) in StnmData.data"
|
|
|
- :key="index"
|
|
|
- >
|
|
|
- <td class="table-index">{{ index + 1 }}</td>
|
|
|
- <td class="table-tbody">{{ item.stationName }}</td>
|
|
|
- <td class="table-tbody">{{ item.stationCode }}</td>
|
|
|
- <td class="table-tbody"></td>
|
|
|
- <td class="table-tbody"></td>
|
|
|
- <td class="table-tbody"></td>
|
|
|
- <td class="table-tbody"></td>
|
|
|
- <td class="table-tbody"></td>
|
|
|
- <td class="table-tbody"></td>
|
|
|
- <td class="table-tbody"></td>
|
|
|
- </tr>
|
|
|
- </tbody>
|
|
|
- </table>
|
|
|
- </el-scrollbar>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 可拖拽图标组 -->
|
|
|
- <div class="map-fcicon" :style="{ left: fcPosition.x + 'px', top: fcPosition.y + 'px' }" v-show="showIcon"
|
|
|
- @mousedown="startDrag"></div>
|
|
|
- <div class="dialog" v-if="showDialog" :style="{ left: dialogPosition.x + 'px', top: dialogPosition.y + 'px' }">
|
|
|
- <div class="dialog-header" @mousedown="startDialogDrag">风场
|
|
|
- <button class="close-btn" @click="closeDialog">×</button>
|
|
|
- </div>
|
|
|
- <div class="dialog-body"></div>
|
|
|
- </div>
|
|
|
+ <div class="map-container">
|
|
|
+ <gw-map ref="mapRef" :config="mapConfig"></gw-map>
|
|
|
+ <biz-data-card v-for="bizDataShowConfig in bizDataShowConfigList" :key="bizDataShowConfig.id"
|
|
|
+ :config="bizDataShowConfig"></biz-data-card>
|
|
|
</div>
|
|
|
</template>
|
|
|
<script setup>
|
|
|
-import 'ol/css';
|
|
|
-import {defaults as defaultControls} from 'ol/control';
|
|
|
-import Map from 'ol/Map';
|
|
|
-import View from 'ol/View';
|
|
|
-import TileLayer from "ol/layer/Tile";
|
|
|
-import {Vector as VectorSource, XYZ} from 'ol/source.js';
|
|
|
-import VectorLayer from "ol/layer/Vector";
|
|
|
-import {Point} from "ol/geom";
|
|
|
-import {Icon, Style} from 'ol/style';
|
|
|
-import Feature from 'ol/Feature';
|
|
|
-import Overlay from 'ol/Overlay';
|
|
|
-import StnmData from "@/assets/map/json/stnmData.json";
|
|
|
-import red_trangle from "@/assets/map/img/Ⅳ.png";
|
|
|
import {getBizDataShowConfigList} from "@/api/standardization/bizDataShowConfig.js";
|
|
|
-import BizDisplay from "@/views/standardization/bizDataShowConfig/show/index.vue";
|
|
|
-
|
|
|
+import BizDataCard from "@/views/map/components/bizDataCard.vue";
|
|
|
+import GwMap from "./components/map.vue"
|
|
|
|
|
|
const bizDataShowConfigList = ref([]);
|
|
|
|
|
|
-const mapChart = ref(null);
|
|
|
-const mapCenter = ref([121.472644, 31.231706]);
|
|
|
-const mapZoom = ref(9);
|
|
|
-const stnmVectorLayer = ref(null);
|
|
|
-const popupOverlays = ref([]);// 存储弹窗的引用
|
|
|
-const showIcon = ref(true);
|
|
|
-const showDialog = ref(false);
|
|
|
-const isDragging = ref(false);
|
|
|
-
|
|
|
-const fcPosition = ref({x: 280, y: 40});
|
|
|
-const dialogPosition = ref({x: 0, y: 0});
|
|
|
-
|
|
|
-const dragStartPosition = ref({x: 0, y: 0});
|
|
|
-const isDraggingDialog = ref(false);
|
|
|
-const dialogDragStart = ref({x: 0, y: 0});
|
|
|
+const mapRef = ref(null);
|
|
|
+const mapConfig = ref({
|
|
|
+ zoom: 9,
|
|
|
+ center: [116.397428, 39.90923],
|
|
|
+ layers: [
|
|
|
+ {
|
|
|
+ id: 'weather-stations',
|
|
|
+ type: 'vector', // 指定为矢量图层
|
|
|
+ name: '行政区划面图层',
|
|
|
+ source: {
|
|
|
+ type: 'api', // 数据源类型为API
|
|
|
+ url: 'http://localhost:8082/SCSSFM/getCalResultsByStation',
|
|
|
+ method: 'POST',
|
|
|
+ body: [
|
|
|
+ {key: 'projectId', value: '230103', type: 'string'},
|
|
|
+ {key: 'forecastSchemeId', value: '2301031', type: 'string'},
|
|
|
+ {key: 'calSchemeIds', value: ["20421b55-5383-4ef0-a"], type: 'array'},
|
|
|
+ ],
|
|
|
+ headers: [
|
|
|
+ {
|
|
|
+ key: 'authorization',
|
|
|
+ value: 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjBhOTE3ZDdhLTUwODktNDg1MC05YTUyLTk1NzRjZWUzYWU5ZSJ9.QuFdSq-_mLFwOlM249-ledRlM4U2_qIRVfdOzGIOnf38XY-QXyaP0k-me2gT1wf5LCjOW0z-zJnO-SnNo78eOg',
|
|
|
+ type: 'string'
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ responseResolution: "$.data",
|
|
|
+ // 定义数据映射规则
|
|
|
+ mapping: {
|
|
|
+ // 指定哪些字段包含几何信息(经度、纬度)
|
|
|
+ geometry: {
|
|
|
+ type: 'Point', // 几何类型
|
|
|
+ coordinates: {
|
|
|
+ longitude: 'lgtd', // 接口中的经度字段名
|
|
|
+ latitude: 'lttd' // 接口中的纬度字段名
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 定义要保留的属性字段
|
|
|
+ properties: {
|
|
|
+ '测站编码': 'stationCode', // 目标属性名: 源数据字段名
|
|
|
+ '测站名称': 'stationName',
|
|
|
+ '预报最大水位': 'calSchemeInfos[0].results[0].maxData.value',
|
|
|
+ '预报最大水位时间': 'calSchemeInfos[0].results[0].maxData.tm',
|
|
|
+ '预报最小水位': 'calSchemeInfos[0].results[0].minData.value',
|
|
|
+ '预报最小水位时间': 'calSchemeInfos[0].results[0].minData.tm',
|
|
|
+ '预报平均水位': 'calSchemeInfos[0].results[0].average',
|
|
|
+ '警戒水位': 'alarmValue',
|
|
|
+ '预报潮位': 'calSchemeInfos[0].results[0].datas',
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 轮询更新(可选)
|
|
|
+ refreshInterval: 30000 // 30秒刷新一次
|
|
|
+ },
|
|
|
+ visible: true,
|
|
|
+ zIndex: 1000,
|
|
|
+ style: {
|
|
|
+ // 点要素样式
|
|
|
+ point: {
|
|
|
+ image: {
|
|
|
+ type: 'icon', // circle|icon
|
|
|
+ // type: 'circle', // circle|icon
|
|
|
+ name: 'red_trangle',
|
|
|
+ radius: 8,
|
|
|
+ fill: {color: '#FF5722'},
|
|
|
+ stroke: {color: '#fff', width: 2}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 线要素样式
|
|
|
+ line: {
|
|
|
+ stroke: {
|
|
|
+ color: '#0066ff',
|
|
|
+ width: 3,
|
|
|
+ lineDash: [5, 5]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 面要素样式
|
|
|
+ polygon: {
|
|
|
+ fill: {color: 'rgba(0, 102, 255, 0.2)'},
|
|
|
+ stroke: {color: '#0066ff', width: 2}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ events: {
|
|
|
+ click: {
|
|
|
+ action: 'popup', // 点击触发弹窗
|
|
|
+ popupConfig: {
|
|
|
+ // 弹窗模板ID
|
|
|
+ template: 'SCSSFM_POPUP',
|
|
|
+ offset: [0, -20]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // hover: {
|
|
|
+ // action: 'highlight' // 悬停高亮
|
|
|
+ // }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ ]
|
|
|
+});
|
|
|
|
|
|
function getBizDataConfigList() {
|
|
|
getBizDataShowConfigList().then(res => {
|
|
|
@@ -110,197 +117,21 @@ function getBizDataConfigList() {
|
|
|
|
|
|
onMounted(() => {
|
|
|
getBizDataConfigList();
|
|
|
- initMap();
|
|
|
-});
|
|
|
-
|
|
|
-const initMap = () => {
|
|
|
- let vecLayer = new TileLayer({
|
|
|
- source: new XYZ({
|
|
|
- url: "http://t0.tianditu.gov.cn/vec_w/wmts?" +
|
|
|
- "SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +
|
|
|
- "&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}" +
|
|
|
- "&tk=9bb941214f10fbf9a3eab43f45cb2b7e",
|
|
|
- }),
|
|
|
- });
|
|
|
- let cvaLayer = new TileLayer({
|
|
|
- source: new XYZ({
|
|
|
- url: "http://t0.tianditu.gov.cn/cva_w/wmts?" +
|
|
|
- "SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +
|
|
|
- "&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}" +
|
|
|
- "&tk=9bb941214f10fbf9a3eab43f45cb2b7e",
|
|
|
- }),
|
|
|
- });
|
|
|
- mapChart.value = new Map({
|
|
|
- target: 'mapChart',
|
|
|
- view: new View({
|
|
|
- center: mapCenter.value,
|
|
|
- zoom: mapZoom.value,
|
|
|
- minZoom: 3,
|
|
|
- maxZoom: 16,
|
|
|
- projection: 'EPSG:4326',
|
|
|
- }),
|
|
|
- layers: [vecLayer, cvaLayer],
|
|
|
- controls: defaultControls({
|
|
|
- zoom: false,//不显示放大放小按钮
|
|
|
- rotate: false,//不显示指北针控件
|
|
|
- attribution: false,//不显示右下角的地图信息控件
|
|
|
- scaleLine: false,//不显示比例尺控件
|
|
|
- })
|
|
|
- });
|
|
|
- addStnm();
|
|
|
-};
|
|
|
-const addStnm = () => {
|
|
|
- let features = [];
|
|
|
- let stationPopData = [];
|
|
|
- const targetStations = ['绿华山', '横沙', '崇西闸', '金山嘴'];
|
|
|
- StnmData.data.forEach(item => {
|
|
|
- targetStations.includes(item.stationName) && stationPopData.push(item);
|
|
|
- let point = new Point([item.lgtd, item.lttd]);
|
|
|
- let feature = new Feature({
|
|
|
- geometry: point,
|
|
|
- name: item.stationName,
|
|
|
- properties: item,
|
|
|
- });
|
|
|
- var style = new Style({
|
|
|
- image: new Icon({
|
|
|
- anchor: [0.5, 0.5],
|
|
|
- scale: 0.08,
|
|
|
- src: red_trangle,
|
|
|
- }),
|
|
|
- });
|
|
|
- feature.setStyle(style);
|
|
|
- features.push(feature);
|
|
|
- })
|
|
|
- let vectorSource = new VectorSource({
|
|
|
- features: features,
|
|
|
- });
|
|
|
- stnmVectorLayer.value = new VectorLayer({
|
|
|
- source: vectorSource,
|
|
|
- });
|
|
|
- mapChart.value.addLayer(stnmVectorLayer.value);
|
|
|
- showPopupInfo(stationPopData);
|
|
|
-};
|
|
|
-// 显示地图坐标信息
|
|
|
-const showPopupInfo = (data) => {
|
|
|
- data.forEach((station, index) => {
|
|
|
- // 创建弹窗元素
|
|
|
- const popupElement = document.createElement('div');
|
|
|
- popupElement.className = 'custom-popup';
|
|
|
- popupElement.id = `popup_${station.stationCode}`;
|
|
|
- // 设置弹窗内容
|
|
|
- popupElement.innerHTML = `
|
|
|
- <div class="popup-title">${station.stationName} (${station.stationCode})</div>
|
|
|
- <div class="popup-top">
|
|
|
- <span>实时潮位:<span></span></span>
|
|
|
- <span>发生时间:<span></span></span>
|
|
|
- <span>警戒潮位:<span></span></span>
|
|
|
- <span>距离警戒:<span></span></span>
|
|
|
- </div>
|
|
|
- <div class="popup-bottom">
|
|
|
- <span>预报潮位:<span></span></span>
|
|
|
- <span>发生时间:<span></span></span>
|
|
|
- <span>距离警戒:<span></span></span>
|
|
|
- </div>
|
|
|
- `;
|
|
|
- let popupOverlay = new Overlay({
|
|
|
- element: popupElement,
|
|
|
- positioning: "top-center",
|
|
|
- stopEvent: false,
|
|
|
- offset: [0, -200],
|
|
|
- });
|
|
|
- const coordinate = [station.lgtd, station.lttd];
|
|
|
- popupOverlay.setPosition(coordinate);
|
|
|
- mapChart.value.addOverlay(popupOverlay);
|
|
|
- // 保存引用
|
|
|
- popupOverlays.value.push(popupOverlay);
|
|
|
- });
|
|
|
-};
|
|
|
-// 清除所有弹窗
|
|
|
-const clearPopups = () => {
|
|
|
- popupOverlays.value.forEach(overlay => {
|
|
|
- mapChart.value.removeOverlay(overlay);
|
|
|
- });
|
|
|
- popupOverlays.value = [];
|
|
|
-};
|
|
|
-
|
|
|
-const startDrag = (event) => {
|
|
|
- isDragging.value = true;
|
|
|
- dragStartPosition.value = {
|
|
|
- x: event.clientX - fcPosition.value.x,
|
|
|
- y: event.clientY - fcPosition.value.y
|
|
|
- };
|
|
|
-
|
|
|
- window.addEventListener('mousemove', onMouseMove);
|
|
|
- window.addEventListener('mouseup', onMouseUp);
|
|
|
-};
|
|
|
-const onMouseMove = (event) => {
|
|
|
- if (!isDragging.value) return;
|
|
|
-
|
|
|
- fcPosition.value = {
|
|
|
- x: event.clientX - dragStartPosition.value.x,
|
|
|
- y: event.clientY - dragStartPosition.value.y
|
|
|
- };
|
|
|
- dialogPosition.value = {
|
|
|
- x: fcPosition.value.x,
|
|
|
- y: fcPosition.value.y
|
|
|
- }
|
|
|
-};
|
|
|
-const onMouseUp = () => {
|
|
|
- if (isDragging.value) {
|
|
|
- showIcon.value = false;
|
|
|
- showDialog.value = true;
|
|
|
- isDragging.value = false;
|
|
|
- window.removeEventListener('mousemove', onMouseMove);
|
|
|
- window.removeEventListener('mouseup', onMouseUp);
|
|
|
- }
|
|
|
-};
|
|
|
-const startDialogDrag = (event) => {
|
|
|
- isDraggingDialog.value = true;
|
|
|
- dialogDragStart.value = {
|
|
|
- x: event.clientX - dialogPosition.value.x,
|
|
|
- y: event.clientY - dialogPosition.value.y
|
|
|
- };
|
|
|
-
|
|
|
- window.addEventListener('mousemove', onDialogMouseMove);
|
|
|
- window.addEventListener('mouseup', onDialogMouseUp);
|
|
|
-};
|
|
|
-const onDialogMouseMove = (event) => {
|
|
|
- if (!isDraggingDialog.value) return;
|
|
|
-
|
|
|
- dialogPosition.value = {
|
|
|
- x: event.clientX - dialogDragStart.value.x,
|
|
|
- y: event.clientY - dialogDragStart.value.y
|
|
|
- };
|
|
|
-};
|
|
|
-
|
|
|
-const onDialogMouseUp = () => {
|
|
|
- isDraggingDialog.value = false;
|
|
|
- window.removeEventListener('mousemove', onDialogMouseMove);
|
|
|
- window.removeEventListener('mouseup', onDialogMouseUp);
|
|
|
-};
|
|
|
-
|
|
|
-const closeDialog = () => {
|
|
|
- showDialog.value = false;
|
|
|
- showIcon.value = true;
|
|
|
- fcPosition.value = {
|
|
|
- x: 280,
|
|
|
- y: 40
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-onUnmounted(() => {
|
|
|
- window.removeEventListener('mousemove', onMouseMove);
|
|
|
- window.removeEventListener('mouseup', onMouseUp);
|
|
|
- window.removeEventListener('mousemove', onDialogMouseMove);
|
|
|
- window.removeEventListener('mouseup', onDialogMouseUp);
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-.biz-data-config-container {
|
|
|
+.map-container {
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .biz-data-config-container {
|
|
|
+
|
|
|
+ & + .biz-data-config-container {
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
|
|
|
- & + .biz-data-config-container {
|
|
|
- margin-top: 10px;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
@@ -320,274 +151,4 @@ onUnmounted(() => {
|
|
|
--el-scrollbar-bg-color: rgba(58, 100, 179);
|
|
|
--el-scrollbar-hover-bg-color: rgba(58, 100, 179);
|
|
|
}
|
|
|
-
|
|
|
-.map-index {
|
|
|
- height: 100%;
|
|
|
- width: 100%;
|
|
|
- position: relative;
|
|
|
-
|
|
|
- #mapChart {
|
|
|
- height: 100%;
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- .map-left {
|
|
|
- position: absolute;
|
|
|
- top: 1%;
|
|
|
- left: 0.5%;
|
|
|
- height: 98%;
|
|
|
- width: 260px;
|
|
|
- background: rgba(255, 255, 255, 0.9);
|
|
|
- border-radius: 8px;
|
|
|
-
|
|
|
- .left-title {
|
|
|
- width: 100%;
|
|
|
- height: 36px;
|
|
|
- background: url("@/assets/map/img/left-title.png") no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- font-size: 16px;
|
|
|
- font-family: 'PuHuiTi', sans-serif;
|
|
|
- font-weight: bolder;
|
|
|
- color: #fff;
|
|
|
- text-align: center;
|
|
|
- line-height: 34px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .map-right {
|
|
|
- position: absolute;
|
|
|
- top: 1%;
|
|
|
- right: 0.5%;
|
|
|
- height: 98%;
|
|
|
- width: 400px;
|
|
|
- background: rgba(255, 255, 255, 0.9);
|
|
|
- border-radius: 8px;
|
|
|
-
|
|
|
- .right-title {
|
|
|
- width: 100%;
|
|
|
- height: 36px;
|
|
|
- background: url("@/assets/map/img/left-title.png") no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- font-size: 16px;
|
|
|
- font-family: 'PuHuiTi', sans-serif;
|
|
|
- font-weight: bolder;
|
|
|
- color: #fff;
|
|
|
- text-align: center;
|
|
|
- line-height: 34px;
|
|
|
- }
|
|
|
-
|
|
|
- .right-top-title {
|
|
|
- width: 100%;
|
|
|
- line-height: 30px;
|
|
|
- padding: 10px;
|
|
|
- display: flex;
|
|
|
-
|
|
|
- img {
|
|
|
- width: 30px;
|
|
|
- height: 30px;
|
|
|
- }
|
|
|
-
|
|
|
- span {
|
|
|
- color: #000;
|
|
|
- font-size: 16px;
|
|
|
- font-family: 'PuHuiTi', sans-serif;
|
|
|
- font-weight: bolder;
|
|
|
- margin-left: 10px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.station-table {
|
|
|
- width: 94%;
|
|
|
- margin: 0 3%;
|
|
|
-
|
|
|
- .table-index {
|
|
|
- width: 40px;
|
|
|
- }
|
|
|
-
|
|
|
- .table-head {
|
|
|
- width: 80px;
|
|
|
- }
|
|
|
-
|
|
|
- table {
|
|
|
- width: 100%;
|
|
|
- border-spacing: 0px;
|
|
|
- border-collapse: collapse; /* 设置表格边框合并为单线 */
|
|
|
- border-top: 2px solid #82bcfd;
|
|
|
- border-bottom: 2px solid #82bcfd;
|
|
|
-
|
|
|
- thead {
|
|
|
- background-image: -webkit-linear-gradient(top, #ebf5ff, #fff);
|
|
|
- color: #000;
|
|
|
- font-size: 14px;
|
|
|
- font-family: 'PuHuiTi', sans-serif;
|
|
|
- font-weight: bold;
|
|
|
- width: 100%;
|
|
|
- border-left: 1px solid #d3e8f9;
|
|
|
- border-right: 1px solid #d3e8f9;
|
|
|
- border-bottom: 1px solid #d3e8f9;
|
|
|
-
|
|
|
- td {
|
|
|
- text-align: center;
|
|
|
- padding: 10px 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- tbody {
|
|
|
- color: #000;
|
|
|
- font-size: 12px;
|
|
|
- font-family: 'PuHuiTi', sans-serif;
|
|
|
- width: 100%;
|
|
|
- border: 1px solid #d3e8f9;
|
|
|
- border-top: none;
|
|
|
-
|
|
|
- tr {
|
|
|
- line-height: 28px;
|
|
|
- background-image: -webkit-linear-gradient(top, #d7eaff, #fff);
|
|
|
- }
|
|
|
-
|
|
|
- td {
|
|
|
- /* border-bottom: 1px solid #d4f0fc; */
|
|
|
- text-align: center;
|
|
|
- padding: 5px 0;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- table tbody {
|
|
|
- display: block;
|
|
|
- height: 20vh !important;
|
|
|
- overflow-y: scroll;
|
|
|
- }
|
|
|
-
|
|
|
- table thead, tbody tr {
|
|
|
- display: table;
|
|
|
- width: 100%;
|
|
|
- table-layout: fixed;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.map-fcicon {
|
|
|
- position: absolute;
|
|
|
- width: 40px;
|
|
|
- height: 40px;
|
|
|
- background-image: url("@/assets/map/img/风场.png");
|
|
|
- background-repeat: no-repeat;
|
|
|
- background-size: 50%;
|
|
|
- background-position: center;
|
|
|
- background-color: rgba(72, 174, 228);
|
|
|
- color: white;
|
|
|
- border-radius: 50%;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- cursor: grab;
|
|
|
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
|
- transition: transform 0.2s, box-shadow 0.2s;
|
|
|
- z-index: 10;
|
|
|
-
|
|
|
- .fc-img {
|
|
|
- width: 25px;
|
|
|
- height: 25px;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.map-fcicon:hover {
|
|
|
- transform: scale(1.1);
|
|
|
- box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
|
|
|
-}
|
|
|
-
|
|
|
-.map-fcicon:active {
|
|
|
- cursor: grabbing;
|
|
|
-}
|
|
|
-
|
|
|
-.dialog {
|
|
|
- position: absolute;
|
|
|
- width: 300px;
|
|
|
- background: white;
|
|
|
- border-radius: 10px;
|
|
|
- box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
|
|
- overflow: hidden;
|
|
|
- z-index: 100;
|
|
|
-}
|
|
|
-
|
|
|
-.dialog-header {
|
|
|
- padding: 5px;
|
|
|
- background: rgba(52, 152, 219, 0.8);
|
|
|
- color: white;
|
|
|
- cursor: move;
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
-}
|
|
|
-
|
|
|
-.dialog-body {
|
|
|
- padding: 20px;
|
|
|
- color: #2c3e50;
|
|
|
-}
|
|
|
-
|
|
|
-.close-btn {
|
|
|
- background: none;
|
|
|
- border: none;
|
|
|
- color: white;
|
|
|
- font-size: 20px;
|
|
|
- cursor: pointer;
|
|
|
-}
|
|
|
-
|
|
|
-.drop-indicator {
|
|
|
- position: absolute;
|
|
|
- bottom: 20px;
|
|
|
- left: 50%;
|
|
|
- transform: translateX(-50%);
|
|
|
- padding: 10px 20px;
|
|
|
- background: #2ecc71;
|
|
|
- color: white;
|
|
|
- border-radius: 20px;
|
|
|
- opacity: 0;
|
|
|
- transition: opacity 0.3s;
|
|
|
-}
|
|
|
-
|
|
|
-.drop-indicator.visible {
|
|
|
- opacity: 1;
|
|
|
-}
|
|
|
</style>
|
|
|
-<style lang="scss">
|
|
|
-.custom-popup {
|
|
|
- background: rgba(255, 255, 255, 0.95);
|
|
|
- border-radius: 8px;
|
|
|
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
|
|
- border: 1px solid #3498db;
|
|
|
- width: 172px;
|
|
|
-
|
|
|
- .popup-title {
|
|
|
- width: 100%;
|
|
|
- line-height: 15px;
|
|
|
- background-color: rgba(255, 23, 0);
|
|
|
- padding: 10px;
|
|
|
- text-align: center;
|
|
|
- color: #fff;
|
|
|
- font-size: 16px;
|
|
|
- }
|
|
|
-
|
|
|
- .popup-top {
|
|
|
- padding: 5px 10px;
|
|
|
- width: 100%;
|
|
|
- background-color: rgba(58, 100, 179);
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- color: #fff;
|
|
|
- font-size: 14px;
|
|
|
- }
|
|
|
-
|
|
|
- .popup-bottom {
|
|
|
- padding: 5px 10px;
|
|
|
- width: 100%;
|
|
|
- background-color: rgba(71, 146, 211);
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- color: #fff;
|
|
|
- font-size: 14px;
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|