站点配置功能完善

master
zhangliang 7 months ago
parent dde0252d27
commit cd3c612d63

@ -6,35 +6,34 @@
</template> </template>
</j-input> </j-input>
<div v-if="admin" class="add-btn"> <div v-if="admin" class="add-btn">
<j-row :style="{ marginTop: '10px' }"> <j-row :style="{ marginTop: '10px' }">
<j-button type="primary" @click="visible = true"> <j-button type="primary" @click="visible = true">
新增站点 新增站点
</j-button> </j-button>
</j-row> </j-row>
</div> </div>
<div class="tree"> <div class="tree" :style="{ height: 'calc(100vh - 332px)' }">
<j-spin :spinning='loading'> <j-spin :spinning='loading'>
<j-tree :tree-data="treeData" v-if="treeData.length" draggable @dragstart="dragstart" <j-tree :tree-data="treeData" v-if="treeData.length" draggable @dragstart="dragstart"
:fieldNames="{ title: 'nodeName', key: 'id', children: 'children' }" blockNode :fieldNames="{ title: 'nodeName', key: 'id', children: 'children' }" blockNode
:default-expanded-keys="defaultExpandedKeys" :showLine="{ showLeafIcon: false }" :showIcon="true"> :default-expanded-keys="defaultExpandedKeys" :showLine="{ showLeafIcon: false }" :showIcon="true">
<template #title="{ nodeName, data, level, type, positionX, parentId, nodeType }"> <template #title="{ nodeName, data, positionX, parentId, nodeType }">
<div v-if="selectId === data.id"> <div v-if="selectId === data.id">
<j-input v-model:value="addName" @blur="() => saveGroup(data)" ref="inputRef" <j-input v-model:value="addName" @blur="() => saveGroup(data)" ref="inputRef"
:maxlength="64"></j-input> :maxlength="64"></j-input>
</div> </div>
<span v-else class='department-tree-item-content'> <span v-else class='department-tree-item-content'>
<span class='title' :style="{ <span class='title' :style="{
width: nodeType == '1' ? '80px' : '110px', width: '100px',
marginRight: nodeType == '0' ? '120px' : '120px',
}"> }">
<j-ellipsis> <j-ellipsis>
<AIcon v-if="nodeType == '1'" type="HeartFilled" /> <AIcon :style="{ color: positionX?'#315efb':''}" v-if="nodeType == '1'" type="HeartFilled" />
&nbsp;{{ nodeName }} &nbsp;{{ nodeName }}
</j-ellipsis> </j-ellipsis>
</span> </span>
<span class="func-btns" :style="{ <span class="func-btns" :style="{
width: nodeType == '0' ? '120px' : '100px', width: nodeType == '0' ? '120px' : '120px',
}" @click="(e) => e.stopPropagation()"> }" @click="(e) => e.stopPropagation()">
<PermissionButton type="link" :tooltip="{ title: '编辑' }" @click="editGroup(data)"> <PermissionButton type="link" :tooltip="{ title: '编辑' }" @click="editGroup(data)">
<AIcon type="EditOutlined" /> <AIcon type="EditOutlined" />
@ -67,7 +66,7 @@
<j-empty v-else description="暂无数据" /> <j-empty v-else description="暂无数据" />
</j-spin> </j-spin>
</div> </div>
<j-row :gutter="10"> <j-row :style="{ marginTop: '10px' }" :gutter="10">
<j-col :span="12"> <j-col :span="12">
<j-button type="primary" @click="visible = true"> <j-button type="primary" @click="visible = true">
导入站点 导入站点
@ -345,7 +344,7 @@ onMounted(() => {
.title { .title {
flex: 1; flex: 1;
margin-right: 80px; //margin-right: 80px;
} }
.func-btns { .func-btns {
@ -369,4 +368,22 @@ onMounted(() => {
} }
} }
} }
:deep(.ant-btn-primary) {
width: 100%;
}
::-webkit-scrollbar {
height: 6px;
}
/* 滚动槽 */
::-webkit-scrollbar-track {
background: #f2f2f2;
border-radius: 4px;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
background: #cecece;
border-radius: 4px;
}
</style> </style>

@ -1,16 +1,22 @@
<template> <template>
<div @dragenter.prevent="onDragEnter" @dragover.prevent="onDragOver" @dragleave="onDragLeave" @drop="drop" id="map" <j-card :style="{ width: '100%', height: 'calc(100vh - 120px)', }">
:style="{ width: '70vw', height: '70vh' }"></div> <div @dragenter.prevent="onDragEnter" @dragover.prevent="onDragOver" @dragleave="onDragLeave" @drop="drop"
id="map" :style="{ width: '100%', height: 'calc(100vh - 120px)' }">
</div>
</j-card>
</template> </template>
<script setup lang="ts" name="Role"> <script setup lang="ts" name="Role">
import "leaflet/dist/leaflet.css"; import "leaflet/dist/leaflet.css";
import { LatLngBoundsExpression, Layer, LayerGroup, Map } from 'leaflet'; import { LatLngBoundsExpression, Layer, LayerGroup, Map } from 'leaflet';
import { addMonitor, editMonitor, deleteMonitor } from '@/api/monitor';
import { monitorType } from '../type' import { monitorType } from '../type'
import * as L from 'leaflet' import * as L from 'leaflet'
import { filterTreeItem } from '@/utils/comm' import { filterTreeItem, onlyMessage } from '@/utils/comm'
import bg from '/images/bind/bdt.png' import bg from '/images/bind/bdt.png'
import { deviceIcons, stateIcons } from '@/assets/diviceIcon' import { deviceIcons, stateIcons } from '@/assets/diviceIcon'
import { pad } from "lodash-es";
interface MarkerType extends Layer { interface MarkerType extends Layer {
markerId?: string | number markerId?: string | number
} }
@ -49,15 +55,38 @@ const createMarkers = (info: monitorType): MarkerType => {
} }
// //
const loadMap = () => { const loadMap = () => {
const imageBounds: LatLngBoundsExpression = [[0, 0], [1000, 1980]]; const imageBounds: LatLngBoundsExpression = [[0, 0], [1080, 1980]];
if (map.value) { if (map.value) {
//114.34,30.58
} else { } else {
map.value = L.map('map', { //, {
//crs: L.CRS.Simple,
// minZoom: -1,
// maxZoom: 16,
// center: [1, 1],
// zoom: -1,
// //maxBounds: imageBounds,
// attributionControl: false,// attribution
// zoomControl: false,// zoom
//})
map.value = L.map('map')
map.value.setView([30.58, 114.34,], 10);
const stamenLayer = L.tileLayer('/static/map/{z}/{x}/{y}/tile.png', {
attribution: '垃圾程序员', //
minZoom: 10, //
maxZoom: 15 //
}).addTo(map.value);
//map.value.setMaxBounds(imageBounds);
markers.value = L.layerGroup()
map.value.addLayer(markers.value);
map.value.on('dblclick', () => {
map.value?.setZoom(-1)
})
/* map.value = L.map('map', {
crs: L.CRS.Simple, crs: L.CRS.Simple,
minZoom: -1, minZoom: -1,
maxZoom: 16, maxZoom: 16,
center: [0, 1], center: [1, 1],
zoom: -1, zoom: -1,
maxBounds: imageBounds, maxBounds: imageBounds,
attributionControl: false,// attribution attributionControl: false,// attribution
@ -70,24 +99,25 @@ const loadMap = () => {
map.value.addLayer(markers.value); map.value.addLayer(markers.value);
map.value.on('dblclick', () => { map.value.on('dblclick', () => {
map.value?.setZoom(-1) map.value?.setZoom(-1)
}) }) */
} }
} }
const drop = (event: DragEvent) => { const drop = async (event: DragEvent) => {
//event.preventDefault() //event.preventDefault()
const mouseEventLatLng = map.value?.mouseEventToLatLng(event); const mouseEventLatLng = map.value?.mouseEventToLatLng(event);
if (mouseEventLatLng) { if (mouseEventLatLng) {
const { lat, lng } = mouseEventLatLng; const { lat, lng } = mouseEventLatLng;
//const dragEvent = event as DragEvent; //const dragEvent = event as DragEvent;
let monitorData = JSON.parse(event.dataTransfer?.getData('monitorData') || ''); let monitorData = JSON.parse(event.dataTransfer?.getData('monitorData') || '');
console.log("🚀 monitorData:", monitorData, lat, lng)
// //
if (monitorData.positionX) { const res = await editMonitor({ ...monitorData, positionX: lng, positionY: lat });
if (res.result) {
//marker onlyMessage('保存成功');
} else { if (!monitorData.positionX) {
markers.value?.addLayer(createMarkers({ ...monitorData, positionX: lng, positionY: lat })) markers.value?.addLayer(createMarkers({ ...monitorData, positionX: lng, positionY: lat }))
} }
}
} }
} }
@ -101,9 +131,10 @@ const onDragOver = (event: MouseEvent) => {
const onDragLeave = (event: MouseEvent) => { const onDragLeave = (event: MouseEvent) => {
console.log('Drag leave'); console.log('Drag leave');
}; };
onMounted(() => { onMounted(() => {
loadMap() loadMap()
mapMonitorList.value = filterTreeItem(props.listData, 'children', (i) => i.level == 2 && i.positionX) mapMonitorList.value = filterTreeItem(props.listData, 'children', (i) => i.positionX)
mapMonitorList.value.forEach((i: monitorType) => { mapMonitorList.value.forEach((i: monitorType) => {
markers.value?.addLayer(createMarkers(i)) markers.value?.addLayer(createMarkers(i))
}) })
@ -116,4 +147,8 @@ onMounted(() => {
.leaflet-container { .leaflet-container {
background-color: #fff; background-color: #fff;
} }
:deep(.ant-card-body) {
padding: 0;
}
</style> </style>

@ -1,27 +1,37 @@
<template> <template>
<page-container> <page-container>
<FullPage> <FullPage>
<div class="dictionary_contain"> <Splitpanes ref="split" class="default-theme"
<div class="dictionary_left"> @splitter-click="treeShow = !treeShow; treeMinSize = treeMinSize == 0 ? 20 : 0;"
:style="{ height: bodyHeight + 'px', overflow: true, minHeight: '720px', width: '100%' }">
<Pane :style="{backgroudColor:'#fff'}" ref="paneLeft" :size="treeMinSize" :min-size="treeMinSize" v-show="treeShow">
<j-card :style="{height: '100%'}">
<Left :listData="listData" :logicId="logicId" @getMonitorList="getMonitorList" <Left :listData="listData" :logicId="logicId" @getMonitorList="getMonitorList"
@select-data="selectData" /> @select-data="selectData" />
</div> </j-card>
<div class="dictionary_right">
</Pane>
<pane min-size="50" class="realTime" ref="paneRight" :size="100 - treeMinSize"
:style="{ minWidth: '500px' }">
<Right :listData="listData" :groupId="groupId" /> <Right :listData="listData" :groupId="groupId" />
</div> </pane>
</div> </Splitpanes>
</FullPage> </FullPage>
</page-container> </page-container>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Splitpanes, Pane } from 'splitpanes';
import 'splitpanes/dist/splitpanes.css'
import Left from './RoleLeft/index.vue' import Left from './RoleLeft/index.vue'
import Right from './RoleRight/index.vue' import Right from './RoleRight/index.vue'
import { TreeNode } from './type'; import { TreeNode } from './type';
import { treeList } from '@/views/gis/data' import { treeList } from '@/views/gis/data'
import { Ref } from 'vue'; import { Ref } from 'vue';
import { findDefaultTree } from '@/api/monitor' import { findDefaultTree } from '@/api/monitor'
const treeShow = ref<boolean>(true);
const treeMinSize = ref<number>(20);
const bodyHeight = ref<number>(document.body.clientHeight - 120);
const listData: Ref<TreeNode[]> = ref([]); const listData: Ref<TreeNode[]> = ref([]);
const groupId = ref() const groupId = ref()
// //
@ -53,10 +63,15 @@ const selectData = (data: any) => {
border-right: 1px solid #f0f0f0; border-right: 1px solid #f0f0f0;
padding-right: 24px; padding-right: 24px;
flex: 1; flex: 1;
height: 100% height: 100%;
min-width: 300px;
overflow-x: auto;
/* 当内容超出容器宽度时显示滚动条 */
} }
.dictionary_right { .dictionary_right {
flex: 4 flex: 4
} }
</style> </style>
Loading…
Cancel
Save