电子围栏完成

This commit is contained in:
liub
2025-09-12 16:50:18 +08:00
parent e5d62c84a5
commit d976443fb9
8 changed files with 1594 additions and 3 deletions

View 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>

View 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>