forked from dyf/dyf-vue-ui
电子围栏完成
This commit is contained in:
@ -6,8 +6,10 @@ VITE_APP_ENV = 'development'
|
|||||||
|
|
||||||
# 开发环境
|
# 开发环境
|
||||||
# VITE_APP_BASE_API = 'http://47.120.79.150/backend'
|
# VITE_APP_BASE_API = 'http://47.120.79.150/backend'
|
||||||
VITE_APP_BASE_API = 'http://192.168.2.23:8000'
|
# VITE_APP_BASE_API = 'http://192.168.110.54:8000'
|
||||||
# VITE_APP_BASE_API = 'http://localhost:8000'
|
|
||||||
|
#代永飞接口
|
||||||
|
VITE_APP_BASE_API = 'http://457102h2d6.qicp.vip:24689'
|
||||||
|
|
||||||
|
|
||||||
# 应用访问路径 例如使用前缀 /admin/
|
# 应用访问路径 例如使用前缀 /admin/
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<meta name="renderer" content="webkit" />
|
<meta name="renderer" content="webkit" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<script src="https://webapi.amap.com/maps?v=2.0&key=90bc158992feb8ccd0145e168cab1307"></script>
|
<script src="https://webapi.amap.com/maps?v=2.0&key=90bc158992feb8ccd0145e168cab1307&plugin=AMap.CircleEditor"></script>
|
||||||
<title>物联网管理平台</title>
|
<title>物联网管理平台</title>
|
||||||
<!--[if lt IE 11
|
<!--[if lt IE 11
|
||||||
]><script>
|
]><script>
|
||||||
|
|||||||
77
src/api/FenceManager/fence.ts
Normal file
77
src/api/FenceManager/fence.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
//修改电子围栏
|
||||||
|
function updateFence(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/geoFence',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//新增电子围栏
|
||||||
|
function AddFence(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/geoFence',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//导出电子围栏列表
|
||||||
|
function exportFence (data){
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/geoFence/export',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//位置检查
|
||||||
|
function check(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/geoFence/check',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取电子围栏详细信息
|
||||||
|
function geoFenceById(id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/geoFence/'+id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询电子围栏列表
|
||||||
|
function getList(data) {
|
||||||
|
if(!data){
|
||||||
|
data={pageNum:1,pageSize:9999};
|
||||||
|
}
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/geoFence/list',
|
||||||
|
method: 'get',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除电子围栏
|
||||||
|
function DelFence(ids) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/geoFence/' + ids,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default{
|
||||||
|
updateFence:updateFence,
|
||||||
|
AddFence:AddFence,
|
||||||
|
exportFence:exportFence,
|
||||||
|
check:check,
|
||||||
|
geoFenceById:geoFenceById,
|
||||||
|
getList:getList,
|
||||||
|
DelFence:DelFence
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
240
src/api/FenceManager/mapOpt.ts
Normal file
240
src/api/FenceManager/mapOpt.ts
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
var map = null;
|
||||||
|
var circle = null;
|
||||||
|
var polygon = null;
|
||||||
|
|
||||||
|
|
||||||
|
function initMap() {
|
||||||
|
// let key = '90bc158992feb8ccd0145e168cab1307';
|
||||||
|
let init = function () {
|
||||||
|
map = new AMap.Map("map", {
|
||||||
|
viewMode: '2D', //默认使用 2D 模式
|
||||||
|
zoom: 11, //地图级别
|
||||||
|
center: [114.420739, 30.487514], //地图中心点
|
||||||
|
});
|
||||||
|
|
||||||
|
map.on('click',function(evt){
|
||||||
|
alert('您点击的位置:'+evt.lnglat.lng+' , '+ evt.lnglat.lat);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if(map){
|
||||||
|
resolve(200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (window.AMap) {
|
||||||
|
init();
|
||||||
|
resolve(200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject({code:500,msg:'高德地图未能初始化成功'});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//添加一个点
|
||||||
|
function AddPoint(point, index, dragEnd, click) {
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
let center = point ? new AMap.LngLat(point.lng, point.lat) : map.getCenter();
|
||||||
|
|
||||||
|
let marker = new AMap.Text({
|
||||||
|
icon: "http://wdxm.ztzhtech.com:8111/Script/Home/img/welComeImg/mapLocation.png",
|
||||||
|
position: center,
|
||||||
|
offset: new AMap.Pixel(-15, -24),
|
||||||
|
draggable: true,
|
||||||
|
cursor: 'point',
|
||||||
|
title: '点击删除',
|
||||||
|
text: index,
|
||||||
|
class: 'point',
|
||||||
|
extData: { type: 'point', txt: index }
|
||||||
|
});
|
||||||
|
marker.setMap(map);
|
||||||
|
|
||||||
|
let lays = map.getAllOverlays('text');
|
||||||
|
for (let i = 0; i < lays.length; i++) {
|
||||||
|
const element = lays[i];
|
||||||
|
let cls = element.getOptions();
|
||||||
|
if (cls.class) {
|
||||||
|
element.dom.classList.add(cls.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
marker.on('dragend', dragEnd);
|
||||||
|
marker.on('mouseover', function (evt) {
|
||||||
|
marker.setText('X');
|
||||||
|
|
||||||
|
});
|
||||||
|
marker.on('mouseout', function (evt) {
|
||||||
|
marker.setText(marker.getExtData().txt);
|
||||||
|
|
||||||
|
});
|
||||||
|
marker.on('click', function (evt) {
|
||||||
|
|
||||||
|
click(evt, marker);
|
||||||
|
});
|
||||||
|
resolve(center);
|
||||||
|
} catch (ex) {
|
||||||
|
reject(ex)
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCenter() {
|
||||||
|
var center = map.getCenter().toJSON();
|
||||||
|
return center;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCenter(lon, lat) {
|
||||||
|
var position = new AMap.LngLat(lon, lat); //传入经纬度
|
||||||
|
map.setCenter(position); //简写 设置地图中心点
|
||||||
|
|
||||||
|
}
|
||||||
|
//画多边形
|
||||||
|
function DrawPoy(points) {
|
||||||
|
if(!map){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!points) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let path = [];
|
||||||
|
if (polygon) {
|
||||||
|
map.remove(polygon);
|
||||||
|
polygon = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
points.filter(v => {
|
||||||
|
path.push(new AMap.LngLat(v.lng, v.lat));
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
polygon = new AMap.Polygon({
|
||||||
|
path: path,
|
||||||
|
fillColor: '#ccebc5',
|
||||||
|
strokeOpacity: 1,
|
||||||
|
fillOpacity: 0.5,
|
||||||
|
strokeColor: '#FF0000',
|
||||||
|
strokeWeight: 5,
|
||||||
|
strokeStyle: 'solid',
|
||||||
|
strokeDasharray: [5, 5],
|
||||||
|
});
|
||||||
|
|
||||||
|
map.add(polygon);
|
||||||
|
|
||||||
|
// map.setFitView();
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
//画圆形
|
||||||
|
function DrawCicle(points, raduis, dragEnd) {
|
||||||
|
if(!map){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (circle) {
|
||||||
|
map.remove(circle);
|
||||||
|
}
|
||||||
|
|
||||||
|
circle = new AMap.Circle({
|
||||||
|
center: [points[0].lng, points[0].lat],
|
||||||
|
radius: raduis ? raduis : 1000, //半径
|
||||||
|
borderWeight: 3,
|
||||||
|
strokeColor: "#FF33FF",
|
||||||
|
strokeOpacity: 1,
|
||||||
|
strokeWeight: 6,
|
||||||
|
strokeOpacity: 0.2,
|
||||||
|
fillOpacity: 0.4,
|
||||||
|
strokeStyle: 'solid',
|
||||||
|
strokeDasharray: [10, 10],
|
||||||
|
// 线样式还支持 'dashed'
|
||||||
|
fillColor: '#1791fc',
|
||||||
|
zIndex: 50,
|
||||||
|
})
|
||||||
|
|
||||||
|
// var circleEditor = new AMap.CircleEditor(map, circle,{
|
||||||
|
// editOptions: {
|
||||||
|
// moveable: false, // 禁止拖拽圆心
|
||||||
|
// // 可以同时配置其他编辑选项
|
||||||
|
// // scalable: true // 允许缩放(默认开启)
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// circleEditor.open();
|
||||||
|
|
||||||
|
// circleEditor.on('move', function (event) {
|
||||||
|
|
||||||
|
// console.log('触发事件:move')
|
||||||
|
// })
|
||||||
|
|
||||||
|
// circleEditor.on('adjust', function (event) {
|
||||||
|
// console.log('触发事件:adjust');
|
||||||
|
|
||||||
|
// dragEnd(event.radius);
|
||||||
|
// })
|
||||||
|
|
||||||
|
// circleEditor.on('end', function (event) {
|
||||||
|
|
||||||
|
// console.log('触发事件: end')
|
||||||
|
// // event.target 即为编辑后的圆形对象
|
||||||
|
// })
|
||||||
|
|
||||||
|
map.add(circle);
|
||||||
|
// 缩放地图到合适的视野级别
|
||||||
|
map.setFitView([circle])
|
||||||
|
}
|
||||||
|
|
||||||
|
//清除所有
|
||||||
|
function clearOverLays() {
|
||||||
|
map && map.clearMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function removeOverLay(lay) {
|
||||||
|
map && map.remove(lay);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removePoy() {
|
||||||
|
if(!map){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (polygon) {
|
||||||
|
map.remove(polygon);
|
||||||
|
polygon = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function removeCircle() {
|
||||||
|
if(!map){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (circle) {
|
||||||
|
map.remove(circle);
|
||||||
|
circle = null;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFitView() {
|
||||||
|
if(map){map.setFitView();}
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
gdMap: map,
|
||||||
|
initMap: initMap,
|
||||||
|
AddPoint: AddPoint,
|
||||||
|
getCenter: getCenter,
|
||||||
|
DrawPoy: DrawPoy,
|
||||||
|
DrawCicle: DrawCicle,
|
||||||
|
clearOverLays: clearOverLays,
|
||||||
|
removeOverLay: removeOverLay,
|
||||||
|
removePoy: removePoy,
|
||||||
|
removeCircle: removeCircle,
|
||||||
|
setFitView: setFitView
|
||||||
|
}
|
||||||
55
src/api/FenceManager/record.ts
Normal file
55
src/api/FenceManager/record.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
//修改围栏进出记录
|
||||||
|
function updateRecord(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/fenceAccessRecord',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//新增围栏进出记录
|
||||||
|
function addRecord(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/fenceAccessRecord',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//获取围栏进出记录详细信息
|
||||||
|
function getRecordById(id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/fenceAccessRecord/' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询围栏进出记录列表
|
||||||
|
function RecordList(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/fenceAccessRecord/list',
|
||||||
|
method: 'get',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除围栏进出记录
|
||||||
|
function DropRecord(ids) {
|
||||||
|
return request({
|
||||||
|
url: '/api/equipment/fenceAccessRecord/' + ids,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
updateRecord: updateRecord,
|
||||||
|
addRecord: addRecord,
|
||||||
|
getRecordById: getRecordById,
|
||||||
|
RecordList: RecordList,
|
||||||
|
DropRecord: DropRecord
|
||||||
|
}
|
||||||
BIN
src/assets/images/mapLocation.png
Normal file
BIN
src/assets/images/mapLocation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
593
src/views/fys-equipment/fenceAccessRecord/index.vue
Normal file
593
src/views/fys-equipment/fenceAccessRecord/index.vue
Normal file
@ -0,0 +1,593 @@
|
|||||||
|
<template>
|
||||||
|
<div class="content" v-loading="Status.fullLoading">
|
||||||
|
<div class="percent100">
|
||||||
|
<div class="topTool">
|
||||||
|
<div class="button-row">
|
||||||
|
<el-button type="primary" @click.stop="ShowEdit(null)"
|
||||||
|
><el-icon><Plus /></el-icon>新增</el-button
|
||||||
|
>
|
||||||
|
<el-button type="primary" @click.stop="Export()" plain
|
||||||
|
><el-icon><Download /></el-icon>导出</el-button
|
||||||
|
>
|
||||||
|
<el-button type="danger" plain @click.stop="DropFence(null)"
|
||||||
|
><el-icon><Delete /></el-icon>删除</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form :inline="true" :model="queryParams" class="demo-form-inline" @submit.native.prevent>
|
||||||
|
<el-form-item label="" style="margin-right: 15px">
|
||||||
|
<el-input :suffix-icon="'Search'" v-model="queryParams.fenceName" placeholder="名称" clearable @keyup.enter.stop="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item style="margin-right: 0px">
|
||||||
|
<el-button type="primary" @click.stop="showSearch">高级筛选</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="demo-collapse" v-show="Status.showSearch.length > 0">
|
||||||
|
<el-collapse accordion v-model="Status.showSearch">
|
||||||
|
<el-collapse-item name="1">
|
||||||
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true" class="queryFormRef">
|
||||||
|
<el-form-item label="事件类型" prop="eventType">
|
||||||
|
<el-select v-model="queryParams.eventType" placeholder="请选择" clearable>
|
||||||
|
<el-option :key="1" :label="'闯入'" :value="1" />
|
||||||
|
<el-option :key="2" :label="'离开'" :value="2" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="事件时间" prop="Date">
|
||||||
|
<el-date-picker
|
||||||
|
style="width: 240px"
|
||||||
|
v-model="queryParams.Date"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="围栏名称" prop="fenceId">
|
||||||
|
<el-select v-model="queryParams.fenceId" placeholder="请选择" clearable filterable>
|
||||||
|
<el-option v-for="item in dic.fence" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备名称" prop="deviceId">
|
||||||
|
<el-select v-model="queryParams.deviceId" placeholder="请选择" clearable filterable>
|
||||||
|
<el-option v-for="item in dic.device" :key="item.deviceId" :label="item.deviceName" :value="item.deviceId" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-collapse-item>
|
||||||
|
</el-collapse>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
ref="grid"
|
||||||
|
v-loading="Status.loading"
|
||||||
|
border
|
||||||
|
:data="List"
|
||||||
|
:height="Status.showSearch.length > 0 ? 'calc(100vh - 355px)' : 'calc(100vh - 255px)'"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
|
|
||||||
|
<el-table-column label="围栏名称" align="center" prop="fenceName"> </el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="设备名称" align="center" prop="deviceName"> </el-table-column>
|
||||||
|
<!-- <el-table-column label="人员名称" align="center" prop="userName"> </el-table-column> -->
|
||||||
|
<el-table-column label="事件类型" align="center" prop="eventType">
|
||||||
|
<template #default="scope">
|
||||||
|
<div>{{ scope.row.eventType == '1' ? '闯入' : '离开' }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="经纬度" align="center" prop="id">
|
||||||
|
<template #default="scope">
|
||||||
|
<span style="margin-right: 15px">{{ scope.row.longitude }}</span
|
||||||
|
><span>{{ scope.row.latitude }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="精度" align="userName" prop="accuracy"> </el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="操作" fixed="right" width="180" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" @click="ShowEdit(scope.row)">编辑</el-button>
|
||||||
|
<el-button link type="danger" @click="DropFence(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="pagin.total > 0"
|
||||||
|
v-model:page="queryParams.pageNum"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
:total="pagin.total"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 编辑弹出层 -->
|
||||||
|
<el-dialog width="760px" v-model="Status.showEdit" :title="'编辑记录'" :draggable="true">
|
||||||
|
<div>
|
||||||
|
<el-form :inline="true" :model="cEdit" label-width="auto">
|
||||||
|
<el-form-item label="围栏名称">
|
||||||
|
<el-select v-model="cEdit.fenceId" placeholder="请选择" clearable filterable>
|
||||||
|
<el-option v-for="item in dic.fence" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="设备名称">
|
||||||
|
<el-select v-model="cEdit.deviceId" placeholder="请选择" clearable filterable>
|
||||||
|
<el-option v-for="item in dic.device" :key="item.deviceId" :label="item.deviceName" :value="item.deviceId" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- <el-form-item label="人员名称">
|
||||||
|
<el-select v-model="cEdit.userId" placeholder="请选择">
|
||||||
|
<el-option :key="0" :label="'多边形'" :value="0" />
|
||||||
|
<el-option :key="1" :label="'圆形'" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item> -->
|
||||||
|
<el-form-item label="事件时间">
|
||||||
|
<el-date-picker v-model="cEdit.eventTime" type="datetime" placeholder="选择时间" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="事件类型">
|
||||||
|
<el-select v-model="cEdit.eventType" placeholder="请选择" clearable>
|
||||||
|
<el-option :key="1" :label="'闯入'" :value="1" />
|
||||||
|
<el-option :key="2" :label="'离开'" :value="2" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="经度">
|
||||||
|
<el-input v-model="cEdit.longitude" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="纬度">
|
||||||
|
<el-input v-model="cEdit.latitude" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="精度">
|
||||||
|
<el-input v-model="cEdit.accuracy" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="center" style="margin-top: 20px">
|
||||||
|
<el-button type="primary" @click="SaveFormData"> 确定 </el-button>
|
||||||
|
<el-button type="primary" plain @click="CloseEdit"> 取消 </el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 提示框 -->
|
||||||
|
<el-dialog :width="300" :draggable="true" v-model="Status.confirm.Visible" :title="Status.confirm.title" center>
|
||||||
|
<span :class="Status.confirm.isWarn">
|
||||||
|
{{ Status.confirm.text }}
|
||||||
|
</span>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="Status.confirm.OkCallback"> 确定 </el-button>
|
||||||
|
<el-button v-show="Status.confirm.showCancel" @click="Status.confirm.cancelCallback">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import api from '@/api/FenceManager/record';
|
||||||
|
import fenceApi from '@/api/FenceManager/fence';
|
||||||
|
import common from '@/utils/common';
|
||||||
|
import deviceapi from '@/api/equipmentManagement/device/index';
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
|
var grid = ref(null);
|
||||||
|
|
||||||
|
//全局状态控制
|
||||||
|
var Status = reactive({
|
||||||
|
fullLoading: false, //是否显示全屏loading
|
||||||
|
loading: false, //是否显示表格区域loading
|
||||||
|
confirm: {
|
||||||
|
//弹出框的配置
|
||||||
|
Visible: false,
|
||||||
|
title: '',
|
||||||
|
text: '',
|
||||||
|
cancelCallback: null,
|
||||||
|
OkCallback: null,
|
||||||
|
showCancel: true,
|
||||||
|
isWarn: false //是否警告色
|
||||||
|
},
|
||||||
|
showSearch: [], //是否显示高级查询
|
||||||
|
showEdit: false //是否显示编辑弹窗
|
||||||
|
});
|
||||||
|
//查询的条件
|
||||||
|
var queryParams = reactive({
|
||||||
|
fenceName: '',
|
||||||
|
fenceId: '',
|
||||||
|
deviceId: '',
|
||||||
|
eventType: '',
|
||||||
|
latitude: '',
|
||||||
|
longitude: '',
|
||||||
|
accuracy: '',
|
||||||
|
Date: [],
|
||||||
|
startEventTime: '',
|
||||||
|
endEventTime: '',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
var dic = reactive({
|
||||||
|
fence: [],
|
||||||
|
device: [],
|
||||||
|
users: []
|
||||||
|
});
|
||||||
|
var cEdit = reactive({
|
||||||
|
'id': null,
|
||||||
|
'fenceId': null,
|
||||||
|
'deviceId': null,
|
||||||
|
'userId': null,
|
||||||
|
'eventType': null,
|
||||||
|
'latitude': null,
|
||||||
|
'longitude': null,
|
||||||
|
'accuracy': null,
|
||||||
|
'eventTime': null
|
||||||
|
});
|
||||||
|
|
||||||
|
//页码控件数据
|
||||||
|
var pagin = reactive({
|
||||||
|
total: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
//列表数据
|
||||||
|
var List = ref<any[]>(null);
|
||||||
|
|
||||||
|
//显示隐藏高级查询
|
||||||
|
function showSearch() {
|
||||||
|
if (Status.showSearch.length > 0) {
|
||||||
|
Status.showSearch = [];
|
||||||
|
} else {
|
||||||
|
Status.showSearch = ['1'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function ShowEdit(item) {
|
||||||
|
Status.showEdit = true;
|
||||||
|
if (item) {
|
||||||
|
let keys = Object.keys(item);
|
||||||
|
keys.forEach((key) => {
|
||||||
|
cEdit[key] = item[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function CloseEdit() {
|
||||||
|
Status.showEdit = false;
|
||||||
|
let defCfg = {
|
||||||
|
'id': null,
|
||||||
|
'fenceId': null,
|
||||||
|
'deviceId': null,
|
||||||
|
'userId': null,
|
||||||
|
'eventType': null,
|
||||||
|
'latitude': null,
|
||||||
|
'longitude': null,
|
||||||
|
'accuracy': null,
|
||||||
|
'eventTime': null
|
||||||
|
};
|
||||||
|
let keys = Object.keys(defCfg);
|
||||||
|
keys.forEach((key) => {
|
||||||
|
cEdit[key] = defCfg[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//响应查询
|
||||||
|
var queryTime = null;
|
||||||
|
function handleQuery() {
|
||||||
|
clearTimeout(queryTime);
|
||||||
|
queryTime = setTimeout(getList, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
//重置查询条件
|
||||||
|
function resetQuery() {
|
||||||
|
let cfg = {
|
||||||
|
fenceName: '',
|
||||||
|
fenceId: '',
|
||||||
|
deviceId: '',
|
||||||
|
eventType: '',
|
||||||
|
latitude: '',
|
||||||
|
longitude: '',
|
||||||
|
accuracy: '',
|
||||||
|
Date: [],
|
||||||
|
startEventTime: '',
|
||||||
|
endEventTime: ''
|
||||||
|
};
|
||||||
|
let keys = Object.keys(cfg);
|
||||||
|
keys.forEach((k) => {
|
||||||
|
queryParams[k] = cfg[k];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------
|
||||||
|
|
||||||
|
//保存数据
|
||||||
|
function SaveFormData() {
|
||||||
|
let promise = Promise.resolve({ code: 200, msg: '操作成功' });
|
||||||
|
Status.fullLoading = true;
|
||||||
|
|
||||||
|
if (cEdit.id !== null) {
|
||||||
|
//编辑
|
||||||
|
promise = api.updateRecord(cEdit);
|
||||||
|
} else {
|
||||||
|
//新增
|
||||||
|
promise = api.addRecord(cEdit);
|
||||||
|
}
|
||||||
|
|
||||||
|
promise
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
CloseEdit();
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
alert(res.msg);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
Status.fullLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//删除围栏
|
||||||
|
function DropFence(item) {
|
||||||
|
let arr = [];
|
||||||
|
if (item) {
|
||||||
|
arr = [item];
|
||||||
|
} else {
|
||||||
|
arr = getSelectionRows(grid);
|
||||||
|
}
|
||||||
|
if (arr.length == 0) {
|
||||||
|
alert('请选择要删除的数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
confirm(
|
||||||
|
'删除后不可恢复,您确认?',
|
||||||
|
() => {
|
||||||
|
arr = arr.map((v) => {
|
||||||
|
return v.id;
|
||||||
|
});
|
||||||
|
api.DropRecord(arr).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
alert(res.msg);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
'提示'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getList() {
|
||||||
|
Status.loading = true;
|
||||||
|
api
|
||||||
|
.RecordList(queryParams)
|
||||||
|
.then((res) => {
|
||||||
|
List.value = res.rows;
|
||||||
|
pagin.total = res.total;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
Status.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function Export() {
|
||||||
|
|
||||||
|
let json = {};
|
||||||
|
proxy?.download('/api/equipment/fenceAccessRecord/export', json, `围栏进出记录_${new Date().getTime()}.xlsx`, 'post').finally(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取已选中的行
|
||||||
|
var getSelectionRows = (gridInstance) => {
|
||||||
|
if (gridInstance.value) {
|
||||||
|
// 检查ref是否已正确引用组件实例
|
||||||
|
var selectedRows = gridInstance.value.getSelectionRows(); // 获取选中行数据数组
|
||||||
|
return selectedRows;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
//字典初始化
|
||||||
|
function initDic() {
|
||||||
|
let getFence = () => {
|
||||||
|
fenceApi.getList(null).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
dic.fence = res.rows;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let getDevice = () => {
|
||||||
|
request({
|
||||||
|
url: '/api/device',
|
||||||
|
method: 'get',
|
||||||
|
params: { pageNum: 1, pageSize: 9999 }
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
dic.device = res.rows;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let getUsers = () => {
|
||||||
|
// request({
|
||||||
|
// url: '/system/user/list',
|
||||||
|
// method: 'get',
|
||||||
|
// params: { pageNum: 1, pageSize: 9999 }
|
||||||
|
// }).then((res) => {
|
||||||
|
// if (res.code == 200) {
|
||||||
|
// dic.users = res.rows;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
getFence();
|
||||||
|
getDevice();
|
||||||
|
getUsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.confirm = function (text, OK, cancel, title, isWarn = false) {
|
||||||
|
let Cfg = {
|
||||||
|
Visible: true,
|
||||||
|
title: title ? title : '提示',
|
||||||
|
text: text ? text : '此操作不可逆,您确定这样做吗?',
|
||||||
|
OkCallback: () => {
|
||||||
|
Status.confirm.Visible = false;
|
||||||
|
if (OK) {
|
||||||
|
OK();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showCancel: true,
|
||||||
|
cancelCallback: () => {
|
||||||
|
Status.confirm.Visible = false;
|
||||||
|
if (cancel) {
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isWarn: isWarn
|
||||||
|
};
|
||||||
|
|
||||||
|
Status.confirm = Cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.alert = function (text, OK, title) {
|
||||||
|
let Cfg = {
|
||||||
|
Visible: true,
|
||||||
|
title: title ? title : '提示',
|
||||||
|
text: text ? text : '不符合规则',
|
||||||
|
OkCallback: () => {
|
||||||
|
Status.confirm.Visible = false;
|
||||||
|
if (OK) {
|
||||||
|
OK();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showCancel: false,
|
||||||
|
cancelCallback: null,
|
||||||
|
isWarn: false
|
||||||
|
};
|
||||||
|
|
||||||
|
Status.confirm = Cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
var hideConfirm = function () {
|
||||||
|
let Cfg = {
|
||||||
|
Visible: false,
|
||||||
|
title: '提示',
|
||||||
|
text: '',
|
||||||
|
cancelCallback: null,
|
||||||
|
OkCallback: null,
|
||||||
|
showCancel: false,
|
||||||
|
isWarn: false
|
||||||
|
};
|
||||||
|
|
||||||
|
Status.confirm = Cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getList();
|
||||||
|
initDic();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.fleft {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fright {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.displayNone {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
min-height: calc(100vh - 84px);
|
||||||
|
height: calc(100vh - 84px);
|
||||||
|
background: rgba(247, 248, 252, 1);
|
||||||
|
font-size: 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 8px 20px;
|
||||||
|
font-family: 'Microsoft YaHei';
|
||||||
|
}
|
||||||
|
|
||||||
|
.topTool {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid #e1e2e5f2;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.percent100 {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0px 0px 6px 0px rgba(0, 34, 96, 0.1);
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep .el-collapse-item__header {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
:deep .el-collapse,
|
||||||
|
:deep .el-collapse-item__wrap {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map {
|
||||||
|
width: 100%;
|
||||||
|
height: 58vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px dashed red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point,
|
||||||
|
:deep .point {
|
||||||
|
background-image: url(@/assets/images/mapLocation.png);
|
||||||
|
width: 30px;
|
||||||
|
height: 48px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-color: #00000000;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point amap-overlay-text-container,
|
||||||
|
:deep .point .amap-overlay-text-container {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 17px;
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
background: #00000000;
|
||||||
|
}
|
||||||
|
.el-date-editor,
|
||||||
|
:deep .el-date-editor {
|
||||||
|
width: 240px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
624
src/views/fys-equipment/geoFence/index.vue
Normal file
624
src/views/fys-equipment/geoFence/index.vue
Normal file
@ -0,0 +1,624 @@
|
|||||||
|
<template>
|
||||||
|
<div class="content" v-loading="Status.fullLoading">
|
||||||
|
<div class="percent100">
|
||||||
|
<div class="topTool">
|
||||||
|
<div class="button-row">
|
||||||
|
<el-button type="primary" @click.stop="ShowEdit(null)"
|
||||||
|
><el-icon><Plus /></el-icon>新增</el-button
|
||||||
|
>
|
||||||
|
<el-button type="primary" @click.stop="Export()" plain
|
||||||
|
><el-icon><Download /></el-icon>导出</el-button
|
||||||
|
>
|
||||||
|
<el-button type="danger" plain @click.stop="DropFence(null)"
|
||||||
|
><el-icon><Delete /></el-icon>删除</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form :inline="true" :model="queryParams" class="demo-form-inline" @submit.native.prevent>
|
||||||
|
<el-form-item label="" style="margin-right: 15px">
|
||||||
|
<el-input :suffix-icon="'Search'" v-model="queryParams.name" placeholder="名称" clearable @keyup.enter.stop="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item style="margin-right: 0px">
|
||||||
|
<el-button type="primary" @click.stop="showSearch">高级筛选</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="demo-collapse" v-show="Status.showSearch.length > 0">
|
||||||
|
<el-collapse accordion v-model="Status.showSearch">
|
||||||
|
<el-collapse-item name="1">
|
||||||
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true" class="queryFormRef">
|
||||||
|
<el-form-item label="围栏类型" prop="areaType">
|
||||||
|
<el-select v-model="queryParams.areaType" placeholder="请选择" clearable>
|
||||||
|
<el-option :key="0" :label="'多边形'" :value="0" />
|
||||||
|
<el-option :key="1" :label="'圆形'" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否激活" prop="isActive" >
|
||||||
|
<el-select v-model="queryParams.isActive" clearable placeholder="请选择">
|
||||||
|
<el-option :key="1" :label="'是'" :value="1" />
|
||||||
|
<el-option :key="0" :label="'否'" :value="0" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="描述" prop="description">
|
||||||
|
<el-input v-model="queryParams.description" placeholder="请输入设备名称" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-collapse-item>
|
||||||
|
</el-collapse>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
ref="grid"
|
||||||
|
v-loading="Status.loading"
|
||||||
|
border
|
||||||
|
:data="List"
|
||||||
|
:height="Status.showSearch.length > 0 ? 'calc(100vh - 355px)' : 'calc(100vh - 255px)'"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
|
<el-table-column label="围栏名称" align="center" prop="name" />
|
||||||
|
|
||||||
|
<el-table-column label="围栏类型" align="center" prop="areaType">
|
||||||
|
<template #default="scope">
|
||||||
|
<div>{{ scope.row.areaType == '1' ? '圆形' : '多边形' }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="半径(米)" align="center" prop="radius"> </el-table-column>
|
||||||
|
<el-table-column label="是否激活" align="center" prop="isActive">
|
||||||
|
<template #default="scope">
|
||||||
|
<div>{{ scope.row.isActive == '1' ? '是' : '否' }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="描述" align="center" prop="description"> </el-table-column>
|
||||||
|
|
||||||
|
|
||||||
|
<el-table-column label="操作" fixed="right" width="180" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" @click="ShowEdit(scope.row)">编辑</el-button>
|
||||||
|
<el-button link type="danger" @click="DropFence(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="pagin.total > 0"
|
||||||
|
v-model:page="queryParams.pageNum"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
:total="pagin.total"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 围栏编辑弹出层 -->
|
||||||
|
<el-dialog width="calc(calc(100% - 250px) * 0.9)" v-model="Status.showEdit" :title="'编辑围栏'" :draggable="true">
|
||||||
|
<div>
|
||||||
|
<el-form :inline="true" :model="cEdit" label-width="auto">
|
||||||
|
<el-form-item label="围栏名称">
|
||||||
|
<el-input v-model="cEdit.name" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="围栏类型">
|
||||||
|
<el-select v-model="cEdit.areaType" placeholder="请选择" @change="areaTypeChange()">
|
||||||
|
<el-option :key="0" :label="'多边形'" :value="0" />
|
||||||
|
<el-option :key="1" :label="'圆形'" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="半径(米)" :class="cEdit.areaType == 1 ? '' : 'displayNone'">
|
||||||
|
<el-input v-model="cEdit.radius" @keydown="refreshOverLayer" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="是否激活">
|
||||||
|
<el-select v-model="cEdit.isActive" placeholder="请选择">
|
||||||
|
<el-option :key="1" :label="'是'" :value="1" />
|
||||||
|
<el-option :key="0" :label="'否'" :value="0" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="备注" style="width: 350px">
|
||||||
|
<el-input v-model="cEdit.description" type="textarea" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" @click.stop="AddPoint()"
|
||||||
|
><el-icon><Plus /></el-icon>添加坐标</el-button
|
||||||
|
>
|
||||||
|
|
||||||
|
<el-button type="primary" @click.stop="ClearPoint()">
|
||||||
|
<el-icon><Delete /></el-icon>清空</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="map" id="map"></div>
|
||||||
|
<div class="center" style="margin-top: 20px">
|
||||||
|
<el-button type="primary" @click="SaveFormData"> 确定 </el-button>
|
||||||
|
<el-button type="primary" plain @click="CloseEdit"> 取消 </el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 提示框 -->
|
||||||
|
<el-dialog :width="300" :draggable="true" v-model="Status.confirm.Visible" :title="Status.confirm.title" center>
|
||||||
|
<span :class="Status.confirm.isWarn">
|
||||||
|
{{ Status.confirm.text }}
|
||||||
|
</span>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="Status.confirm.OkCallback"> 确定 </el-button>
|
||||||
|
<el-button v-show="Status.confirm.showCancel" @click="Status.confirm.cancelCallback">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import api from '@/api/FenceManager/fence';
|
||||||
|
import common from '@/utils/common';
|
||||||
|
import map from '@/api/FenceManager/mapOpt';
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
|
var grid = ref(null);
|
||||||
|
|
||||||
|
//全局状态控制
|
||||||
|
var Status = reactive({
|
||||||
|
fullLoading: false, //是否显示全屏loading
|
||||||
|
loading: false, //是否显示表格区域loading
|
||||||
|
confirm: {
|
||||||
|
//弹出框的配置
|
||||||
|
Visible: false,
|
||||||
|
title: '',
|
||||||
|
text: '',
|
||||||
|
cancelCallback: null,
|
||||||
|
OkCallback: null,
|
||||||
|
showCancel: true,
|
||||||
|
isWarn: false //是否警告色
|
||||||
|
},
|
||||||
|
showSearch: [], //是否显示高级查询
|
||||||
|
showEdit: false //是否显示编辑弹窗
|
||||||
|
});
|
||||||
|
//查询的条件
|
||||||
|
var queryParams = reactive({
|
||||||
|
name: '',
|
||||||
|
areaType: null,
|
||||||
|
isActive: null,
|
||||||
|
description: '',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
});
|
||||||
|
var cEdit = reactive({
|
||||||
|
id: null,
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
areaType: null,
|
||||||
|
coordinates: [],
|
||||||
|
radius: null,
|
||||||
|
isActive: null
|
||||||
|
});
|
||||||
|
|
||||||
|
//页码控件数据
|
||||||
|
var pagin = reactive({
|
||||||
|
total: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
//列表数据
|
||||||
|
var List = ref<any[]>(null);
|
||||||
|
|
||||||
|
//显示隐藏高级查询
|
||||||
|
function showSearch() {
|
||||||
|
if (Status.showSearch.length > 0) {
|
||||||
|
Status.showSearch = [];
|
||||||
|
} else {
|
||||||
|
Status.showSearch = ['1'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function ShowEdit(item) {
|
||||||
|
|
||||||
|
Status.showEdit = true;
|
||||||
|
if (item) {
|
||||||
|
let keys = Object.keys(item);
|
||||||
|
keys.forEach((key) => {
|
||||||
|
if (key !== 'coordinates') {
|
||||||
|
cEdit[key] = item[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (item.coordinates) {
|
||||||
|
cEdit.coordinates = JSON.parse(item.coordinates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.clearOverLays();
|
||||||
|
setTimeout(() => {
|
||||||
|
map
|
||||||
|
.initMap()
|
||||||
|
.then((res) => {
|
||||||
|
console.log('地图初始化成功', res);
|
||||||
|
if (cEdit.coordinates.length > 0) {
|
||||||
|
refreshOverLayer();
|
||||||
|
for (let i = 0; i < cEdit.coordinates.length; i++) {
|
||||||
|
let point = cEdit.coordinates[i];
|
||||||
|
AddPoint(point, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
map.setFitView();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert('地图初始化没有成功');
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
function CloseEdit() {
|
||||||
|
Status.showEdit = false;
|
||||||
|
let defCfg = {
|
||||||
|
id: null,
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
areaType: null,
|
||||||
|
coordinates: [],
|
||||||
|
radius: null,
|
||||||
|
isActive: null
|
||||||
|
};
|
||||||
|
let keys = Object.keys(defCfg);
|
||||||
|
keys.forEach((key) => {
|
||||||
|
cEdit[key] = defCfg[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//响应查询
|
||||||
|
var queryTime = null;
|
||||||
|
function handleQuery() {
|
||||||
|
clearTimeout(queryTime);
|
||||||
|
queryTime = setTimeout(getList, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
//重置查询条件
|
||||||
|
function resetQuery() {
|
||||||
|
let cfg = {
|
||||||
|
name: '',
|
||||||
|
areaType: null,
|
||||||
|
isActive: null,
|
||||||
|
description: ''
|
||||||
|
};
|
||||||
|
let keys = Object.keys(cfg);
|
||||||
|
keys.forEach((k) => {
|
||||||
|
queryParams[k] = cfg[k];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------
|
||||||
|
//修改围栏类型时,清空所有坐标
|
||||||
|
function areaTypeChange() {
|
||||||
|
cEdit.coordinates = [];
|
||||||
|
map.clearOverLays();
|
||||||
|
}
|
||||||
|
//圆大小改变时,更新半径字段
|
||||||
|
function circleDragEnd(radius) {
|
||||||
|
cEdit.radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改半径后主动更新图形
|
||||||
|
let time = null;
|
||||||
|
function refreshOverLayer() {
|
||||||
|
clearTimeout(time);
|
||||||
|
time = setTimeout(() => {
|
||||||
|
|
||||||
|
if (cEdit.areaType == 1) {
|
||||||
|
map.DrawCicle(cEdit.coordinates, cEdit.radius, circleDragEnd);
|
||||||
|
} else {
|
||||||
|
map.DrawPoy(cEdit.coordinates);
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
//清空所有点
|
||||||
|
function ClearPoint() {
|
||||||
|
confirm(
|
||||||
|
'您确认清除所有标记吗?',
|
||||||
|
() => {
|
||||||
|
cEdit.coordinates = [];
|
||||||
|
map.clearOverLays();
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
'提示'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//添加一个点
|
||||||
|
function AddPoint(point, i) {
|
||||||
|
|
||||||
|
if (cEdit.areaType == null && !point) {
|
||||||
|
alert('请选择围栏类型');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!point && cEdit.areaType == 1 && cEdit.coordinates.length > 0) {
|
||||||
|
alert('圆形围栏只有一个中心坐标点');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = i !== undefined ? i : cEdit.coordinates.length;
|
||||||
|
let dragEnd = (evt, lay) => {
|
||||||
|
|
||||||
|
map.removePoy();
|
||||||
|
|
||||||
|
cEdit.coordinates[index].lng = evt.lnglat.lng;
|
||||||
|
cEdit.coordinates[index].lat = evt.lnglat.lat;
|
||||||
|
refreshOverLayer();
|
||||||
|
|
||||||
|
};
|
||||||
|
let pointClick = (evt, lay) => {
|
||||||
|
|
||||||
|
confirm(
|
||||||
|
'您确认删除该点吗?',
|
||||||
|
() => {
|
||||||
|
cEdit.coordinates.splice(index, 1);
|
||||||
|
map.removeOverLay(lay);
|
||||||
|
refreshOverLayer();
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
map.AddPoint(point, index + 1, dragEnd, pointClick).then((res) => {
|
||||||
|
let lon = res.lng;
|
||||||
|
let lat = res.lat;
|
||||||
|
|
||||||
|
if(!point){cEdit.coordinates.push({ lng: lon, lat: lat });}
|
||||||
|
refreshOverLayer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//保存数据
|
||||||
|
function SaveFormData() {
|
||||||
|
if (cEdit.areaType == 0 && cEdit.coordinates.length < 3) {
|
||||||
|
alert('多边形的围栏至少需要3个点');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cEdit.areaType == 0 && cEdit.coordinates.length == 0) {
|
||||||
|
alert('圆形的围栏至少需要1个点');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let promise = Promise.resolve({ code: 200, msg: '操作成功' });
|
||||||
|
Status.fullLoading = true;
|
||||||
|
let json = Object.assign({}, cEdit);
|
||||||
|
json.coordinates = JSON.stringify(json.coordinates);
|
||||||
|
if (cEdit.id !== null) {
|
||||||
|
//编辑
|
||||||
|
promise = api.updateFence(json);
|
||||||
|
} else {
|
||||||
|
//新增
|
||||||
|
promise = api.AddFence(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
promise
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
getList();
|
||||||
|
CloseEdit();
|
||||||
|
}
|
||||||
|
alert(res.msg);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
Status.fullLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//删除围栏
|
||||||
|
function DropFence(item) {
|
||||||
|
let arr = [];
|
||||||
|
if (item) {
|
||||||
|
arr = [item];
|
||||||
|
} else {
|
||||||
|
arr = getSelectionRows(grid);
|
||||||
|
}
|
||||||
|
if (arr.length == 0) {
|
||||||
|
alert('请选择要删除的数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arr = arr
|
||||||
|
.map((v) => {
|
||||||
|
return v.id;
|
||||||
|
})
|
||||||
|
.join(',');
|
||||||
|
api.DelFence(arr).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
alert(res.msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getList() {
|
||||||
|
Status.loading = true;
|
||||||
|
api
|
||||||
|
.getList(queryParams)
|
||||||
|
.then((res) => {
|
||||||
|
List.value = res.rows;
|
||||||
|
pagin.total = res.total;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
Status.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function Export() {
|
||||||
|
|
||||||
|
let json = {};
|
||||||
|
proxy?.download('/api/equipment/geoFence/export', json, `电子围栏列表_${new Date().getTime()}.xlsx`, 'post').finally(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取已选中的行
|
||||||
|
var getSelectionRows = (gridInstance) => {
|
||||||
|
if (gridInstance.value) {
|
||||||
|
// 检查ref是否已正确引用组件实例
|
||||||
|
var selectedRows = gridInstance.value.getSelectionRows(); // 获取选中行数据数组
|
||||||
|
return selectedRows;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
window.confirm = function (text, OK, cancel, title, isWarn = false) {
|
||||||
|
let Cfg = {
|
||||||
|
Visible: true,
|
||||||
|
title: title ? title : '提示',
|
||||||
|
text: text ? text : '此操作不可逆,您确定这样做吗?',
|
||||||
|
OkCallback: () => {
|
||||||
|
Status.confirm.Visible = false;
|
||||||
|
if (OK) {
|
||||||
|
OK();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showCancel: true,
|
||||||
|
cancelCallback: () => {
|
||||||
|
Status.confirm.Visible = false;
|
||||||
|
if (cancel) {
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isWarn: isWarn
|
||||||
|
};
|
||||||
|
|
||||||
|
Status.confirm = Cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.alert = function (text, OK, title) {
|
||||||
|
let Cfg = {
|
||||||
|
Visible: true,
|
||||||
|
title: title ? title : '提示',
|
||||||
|
text: text ? text : '不符合规则',
|
||||||
|
OkCallback: () => {
|
||||||
|
Status.confirm.Visible = false;
|
||||||
|
if (OK) {
|
||||||
|
OK();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showCancel: false,
|
||||||
|
cancelCallback: null,
|
||||||
|
isWarn: false
|
||||||
|
};
|
||||||
|
|
||||||
|
Status.confirm = Cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
var hideConfirm = function () {
|
||||||
|
let Cfg = {
|
||||||
|
Visible: false,
|
||||||
|
title: '提示',
|
||||||
|
text: '',
|
||||||
|
cancelCallback: null,
|
||||||
|
OkCallback: null,
|
||||||
|
showCancel: false,
|
||||||
|
isWarn: false
|
||||||
|
};
|
||||||
|
|
||||||
|
Status.confirm = Cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.fleft {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fright {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.displayNone {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
min-height: calc(100vh - 84px);
|
||||||
|
height: calc(100vh - 84px);
|
||||||
|
background: rgba(247, 248, 252, 1);
|
||||||
|
font-size: 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 8px 20px;
|
||||||
|
font-family: 'Microsoft YaHei';
|
||||||
|
}
|
||||||
|
|
||||||
|
.topTool {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid #e1e2e5f2;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.percent100 {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0px 0px 6px 0px rgba(0, 34, 96, 0.1);
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep .el-collapse-item__header {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
:deep .el-collapse,
|
||||||
|
:deep .el-collapse-item__wrap {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map {
|
||||||
|
width: 100%;
|
||||||
|
height: 58vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid #7371719e;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point,
|
||||||
|
:deep .point {
|
||||||
|
background-image: url(http://wdxm.ztzhtech.com:8111/Script/Home/img/welComeImg/mapLocation.png);
|
||||||
|
width: 30px;
|
||||||
|
height: 48px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-color: #00000000;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point amap-overlay-text-container,
|
||||||
|
:deep .point .amap-overlay-text-container {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 17px;
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
background: #00000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point:hover,
|
||||||
|
:deep .point:hover {
|
||||||
|
filter: hue-rotate(169deg);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user