Files
Lydc_frontend/src/components/DataManagement/DataManagement.vue

1938 lines
58 KiB
Vue
Raw Normal View History

2025-11-26 16:28:14 +08:00
<template>
<div id="mapDiv">
<Map @mapView="getMap"></Map>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
>
<div v-show="collapsed" id="leftPanel">
<div>
<!--展开折叠开关-->
<div @click.prevent="collapse" id="toLeft">
<i
v-if="collapsed"
class="el-icon-arrow-left"
title="收起"
style="margin-top: 13px; color: #264672"
></i>
<i
v-else
class="el-icon-arrow-right"
title="展开"
style="margin-top: 13px; color: #264672"
></i>
</div>
</div>
<div id="leftPanelScroll">
2025-11-28 12:58:45 +08:00
<el-tabs v-model="activeName">
2025-11-26 16:28:14 +08:00
<el-tab-pane label="数据查看" name="second">
<div>
2025-11-28 12:58:45 +08:00
<p class="mylabel">
<span class="label-text">任务</span>
2025-11-26 16:28:14 +08:00
<el-select
v-model="task"
size="small"
style="width: 60%"
placeholder="请选择任务"
filterable
clearable
@focus="getTasks()"
@change="table = ''; userId = ''"
>
<el-option
v-for="item in taskoptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</p>
2025-11-28 12:58:45 +08:00
<p class="mylabel">
<span class="label-text"></span>
2025-11-26 16:28:14 +08:00
<el-select
id="sTable"
v-model="table"
size="small"
style="width: 60%"
placeholder="请选择表"
filterable
clearable
@focus="getTables()"
>
<el-option
v-for="item in tableoptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</p>
2025-11-28 12:58:45 +08:00
<p class="mylabel">
<span class="label-text">人员</span>
2025-11-26 16:28:14 +08:00
<el-select
id="sUser"
v-model="userId"
size="small"
style="width: 60%"
placeholder="请选择人员"
filterable
clearable
@focus="getUser()"
@blur="handleUserSelectBlur"
>
<el-option
v-for="item in useroptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</p>
<el-button
size="small"
icon="el-icon-search"
class="dateBtn"
style="background-color: #304156; color: #fff"
@click="handleConfirmClick()"
>确定
</el-button
>
2025-11-28 12:58:45 +08:00
<!-- 显示要素信息属性照片和视频
<div v-if="Info && Object.keys(Info).length > 0" style="margin-top: 20px">
<featureInfo :data="Info" style="margin: 0 auto"/>
</div>-->
2025-11-26 16:28:14 +08:00
</div>
</el-tab-pane>
</el-tabs>
<div id="editionContainer">
<el-tabs v-model="activeName1">
<el-tab-pane label="版本回退" name="first1">
<p>
重叠数据查看
<el-tooltip
class="item"
effect="dark"
content="在地图上选择要素后,切换查看与已选要素重叠的要素"
placement="top-end"
><i class="el-icon-info"></i></el-tooltip
>
<el-select
v-model="currentFeatureId"
style="width: 55%; margin-bottom: 10px"
placeholder="请选择数据id"
filterable
clearable
>
<el-option
v-for="item in FeaturesId"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</p>
<featureInfo :data="Info" style="margin: 0 auto"/>
<div class="button-group">
<el-button
size="small"
class="dateBtn"
@click="getGeoJson()"
>返回父表
</el-button>
<el-button
size="small"
class="dateBtn"
@click="getSubGeoJson()"
>进入子表
</el-button>
<el-button
size="small"
class="dateBtn"
@click="clearAll()"
>清除
</el-button>
<el-button
size="small"
class="dateBtn"
icon="el-icon-info"
@click="getEdition()"
>查看历史版本
</el-button>
</div>
</el-tab-pane>
<el-tab-pane label="数据审核" name="second1">
<el-radio-group v-model="datastatus">
<el-radio :label="0">未审核</el-radio>
<el-radio :label="2">审核已通过</el-radio>
<el-radio :label="-1">审核未通过</el-radio>
</el-radio-group>
<div v-show="getList === true">
<div
:key="i"
v-for="(item, i) in examData"
style="border: 1px solid #cfcece; text-align: left"
>
{{ i + 1 + (pageNumber - 1) * pageSize }}.
<el-row
v-for="(val, key) in examData[i]"
:key="key"
@click.native="getExamInfo(i)"
>
<el-col>
{{ key }}:
<span style="color: #409eff">{{ val }}</span>
</el-col>
</el-row>
</div>
<el-pagination
small
layout="prev, pager, next, jumper,sizes"
:page-count="dataPageNum"
@current-change="pageChange"
@size-change="pageSizeChange"
style="height: 80px; white-space: break-spaces;"
></el-pagination>
</div>
<div v-show="getList === false">
<el-button
type="text"
@click="getList = true"
style="color: #409eff !important; margin-left: -250px"
>返回列表
</el-button
>
<featureInfo :data="examInfo" style="margin: 0 auto"/>
<el-button
v-show="datastatus === 0"
size="small"
icon="el-icon-success"
style="
background-color: #304156;
color: #fff;
margin-top: 20px;
margin-bottom: 20px;
"
@click="passData()"
>审核通过
</el-button
>
<el-button
v-show="datastatus === 0"
size="small"
icon="el-icon-error"
style="
background-color: #304156;
color: #fff;
margin-top: 20px;
margin-bottom: 20px;
"
@click="deleteData()"
>审核未通过
</el-button
>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
</transition>
<div style="height: 100%">
<el-dialog
v-dialogDrag
class="infoDialog1"
title="历史版本信息"
:visible.sync="dialogVisible"
>
<p>
数据历史版本
<el-select
size="small"
v-model="edition"
style="width: 71%"
placeholder="请选择历史版本"
filterable
clearable
@change="getEditionData()"
>
<el-option
v-for="item in editionoptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</p>
<featureInfo :data="EditionInfo" style="margin: 0 auto"/>
<el-button
size="small"
icon="el-icon-sort"
style="background-color: #304156; color: #fff; margin-top: 10px"
@click="Rollback()"
>回退到当前历史版本
</el-button
>
</el-dialog>
</div>
</div>
</template>
<script>
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import GeoJSON from 'ol/format/GeoJSON'
import Select from 'ol/interaction/Select'
import {ajax as request} from '@/request.js'
import 'ol/ol.css'
import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import {Cluster} from 'ol/source'
import {Circle as CircleStyle, Fill, Stroke, Style, Text} from 'ol/style'
const Map = () => import('../Mapview/Map')
const featureInfo = () => import('../DataManagement/featureInfo')
export default {
name: 'ViewTask',
data () {
return {
isExtend: false,
datastatus: 0,
dataPageNum: 1,
pageNumber: 1,
pageSize: 10,
dataInfo: [],
dataCoordinates: [],
getList: true,
examData: [],
FeaturesId: [],
clusters: null,
isClusters: false,
vectorLayer: null,
isVectorLayer: false,
distribute: false,
minSize: '',
maxSize: '',
cellLayer: null,
dialogVisible: false,
selectclick: null,
activeName: 'second',
activeName1: 'first1',
collapsed: true,
drawer: false,
task: '',
table: '',
userId: '',
edition: '',
Info: {},
examInfo: {},
EditionInfo: {},
taskoptions: [],
tableoptions: [],
useroptions: [],
editionoptions: [],
currentFeatureId: '',
feature: null,
vectorSource: null,
pageLayer: null,
pageSource: null,
selectclick1: null,
sontablename: '',
fathertablename: '',
ifsub: false,
iffather: false,
fathergeom: null,
fatherFeatureLayer: null,
isFatherFeatureLayer: false,
isSwitchingToSubTable: false,
selectId: null
}
},
components: {
Map,
featureInfo
},
created () {
},
mounted () {
},
methods: {
getTasks () {
this.taskoptions = []
let that = this
request({
url: '/task/selectTaskHasCreated',
method: 'get'
}).then(function (response) {
if (response.data.success === true) {
var jsondata = JSON.parse(response.data.data)
var options = jsondata.data
for (var i = 0; i < options.length; i++) {
that.taskoptions.push({
value: options[i].id,
label: options[i].taskName
})
}
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
}
})
},
getTables () {
if (this.task === '') {
this.$alert('请先选择任务!', '提示', {
confirmButtonText: '确定'
})
document.getElementById('sTable').blur()
} else {
var taskname = ''
for (var i = 0; i < this.taskoptions.length; i++) {
if (this.task === this.taskoptions[i].value) {
taskname = this.taskoptions[i].label
break
}
}
this.tableoptions = []
let that = this
request({
url: '/statistic/getTables',
method: 'post',
params: {
tskName: taskname
}
}).then(function (response) {
// 获取数据存入config
if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
} else if (response.status === 200) {
var json = response.data
for (var key in json) {
that.tableoptions.push({
value: key,
label: json[key]
})
}
}
})
}
},
getUser () {
if (this.task === '') {
this.$alert('请先选择任务!', '提示', {
confirmButtonText: '确定'
})
document.getElementById('sUser').blur()
} else {
this.useroptions = []
let that = this
request({
// url: '/report/workloadByUser',
url: 'statistic/getWorkers',
method: 'get',
params: {
taskId: that.task
}
}).then(function (response) {
// 登录成功获取数据存入usersData
if (response.data.success) {
response.data.data.forEach(user => {
that.useroptions.push({
value: user.id,
label: user.realName
})
})
}
})
}
},
getMap (val) {
this.map = val
let that = this
this.map.on('moveend', function (e) {
// 20250729
if (that.ifsub) {
return
}
// ---------------
// 移除所有
if (that.clusters) {
if (that.isClusters) {
that.map.removeLayer(that.clusters)
}
that.clusters = null
}
if (that.vectorLayer) {
if (that.isVectorLayer) {
that.map.removeLayer(that.vectorLayer)
that.map.removeInteraction(that.selectclick)
}
that.vectorLayer = null
that.selectclick = null
}
if (that.distribute && that.activeName1 === 'first1' && that.cellLayer) {
that.debounce(that.getClusters(), 500)
}
})
},
debounce (fn, delay) {
let timer = null // 借助闭包
return function () {
if (timer) {
clearTimeout(timer)
timer = setTimeout(fn, delay)
} else {
timer = setTimeout(fn, delay)
}
}
},
// 左侧面板收缩动画
collapse () {
this.collapsed = !this.collapsed
},
beforeEnter: function (el) {
el.style.transform = 'translate(410px,0px)'
},
enter: function (el, done) {
el.style.transform = 'translate(0px,0px)'
el.style.transition = 'all 0.6s ease'
done()
},
beforeLeave: function (el) {
el.style.transform = 'translate(0px,0px)'
},
leave: function (el, done) {
el.style.transform = 'translate(-425px,0px)'
el.style.transition = 'all 0.6s ease'
// done();
},
getRange (addToMap) {
let that = this
request({
url: '/allocation/info/cell/all',
method: 'post',
params: {
taskId: that.task
}
}).then(function (response) {
// 获取数据存入config
if (response.data.status === 200) {
var result = response.data.data
if (result.features.length !== 0) {
that.drawCellLayer(result)
that.map.getView().fit(that.cellLayer.getSource().getExtent())
// if (that.ifsub === false && that.iffather === false) {
// that.map.getView().fit(that.cellLayer.getSource().getExtent())
// }
that.getClusters()
} else {
that.$message.info('获取任务范围失败,未上传数据!')
}
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
}
})
},
getClusters () {
var zoom = 0
zoom = this.map.getView().getZoom()
// 获取地图范围
var coordinates = this.map.getView().calculateExtent(this.map.getSize())
var geoHashLength = ''
switch (zoom) {
case 8:
case 9:
geoHashLength = 4
break
case 10:
case 11:
case 12:
geoHashLength = 5
break
case 13:
case 14:
case 15:
case 16:
geoHashLength = 6
break
case 17:
case 18:
case 19:
case 20:
geoHashLength = 7
break
default:
geoHashLength = 3
}
if (this.distribute) {
if (this.ifsub) {
let that = this
request({
url: '/get/getSubDataByRangeIntersection',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
parentId: that.selectId,
longitudeMin: coordinates[0],
latitudeMin: coordinates[1],
longitudeMax: coordinates[2],
latitudeMax: coordinates[3]
}
}).then(function (response) {
if (response.data.success) {
if (response.data.data) {
var geojson = response.data.data
var geojsonObject = {
type: 'FeatureCollection',
features: geojson,
crs: {type: 'EPSG', properties: {code: '4326'}}
}
that.drawVectorLayer(geojsonObject)
} else {
that.$message.info('获取范围内数据为空!')
}
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
}
})
} else {
if (zoom < 15) {
// 请求聚类图层
let that = this
that.minSize = 0
that.maxSize = 0
request({
url: '/base/getCountByGeoHash',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
accuracy: geoHashLength,
longitudeMin: coordinates[0],
latitudeMin: coordinates[1],
longitudeMax: coordinates[2],
latitudeMax: coordinates[3]
}
}).then(function (response) {
if (response.data.success) {
if (response.data.data) {
var result = response.data.data
var geojson = []
for (var i = 0; i < result.length; i++) {
var count = result[i].count
if (i === 0) {
that.minSize = count
that.maxSize = count
} else {
if (count < that.minSize) {
that.minSize = count
}
if (count > that.maxSize) {
that.maxSize = count
}
}
// 存入count
var geojson1 = result[i].feature
geojson1.properties = {}
geojson1.properties.count = count
geojson.push(result[i].feature)
}
var geojsonObject = {
type: 'FeatureCollection',
features: geojson,
crs: {type: 'EPSG', properties: {code: '4326'}}
}
that.drawClusterLayer(geojsonObject)
} else {
that.$message.info('获取范围内数据为空!')
}
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
}
})
} else {
let that = this
request({
url: '/get/getDataByRangeIntersection',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
longitudeMin: coordinates[0],
latitudeMin: coordinates[1],
longitudeMax: coordinates[2],
latitudeMax: coordinates[3]
}
}).then(function (response) {
if (response.data.success) {
if (response.data.data) {
var geojson = response.data.data
var geojsonObject = {
type: 'FeatureCollection',
features: geojson,
crs: {type: 'EPSG', properties: {code: '4326'}}
}
that.drawVectorLayer(geojsonObject)
} else {
that.$message.info('获取范围内数据为空!')
}
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
}
})
}
}
}
},
drawCellLayer (geojsonObject) {
if (this.cellLayer) {
this.map.removeLayer(this.cellLayer)
}
var vectorSource = new VectorSource({
features: new GeoJSON().readFeatures(geojsonObject)
})
this.cellLayer = new VectorLayer({
source: vectorSource
})
this.cellLayer.setZIndex(5)
},
drawClusterLayer (geojsonObject) {
if (this.clusters) {
if (this.isClusters) {
this.map.removeLayer(this.clusters)
this.isClusters = false
}
this.clusters = null
}
if (this.vectorLayer) {
if (this.isVectorLayer) {
this.map.removeLayer(this.vectorLayer)
this.map.removeInteraction(this.selectclick)
}
this.vectorLayer = null
this.selectclick = null
}
var vectorSource = new VectorSource({
features: new GeoJSON().readFeatures(geojsonObject)
})
// let that = this
this.clusters = new VectorLayer({
source: vectorSource,
style: function (feature) {
// let count = feature.get('count').toString()
let style = new Style({
stroke: new Stroke({
lineDash: [1, 2, 3, 4, 5, 6],
color: 'rgba(70,130,180, 0.9)',
width: 2
}),
fill: new Fill({
color: [255, 153, 0, 0.8]
}),
text: new Text({
text: feature.get('count').toString(),
font: '16px Microsoft YaHei',
fill: new Fill({
color: '#fff'
}),
stroke: new Stroke({
color: 'rgba(0, 0, 0, 0.6)',
width: 3
})
})
})
return [style]
}
})
this.clusters.setZIndex(4)
this.map.addLayer(this.clusters)
this.isClusters = true
},
drawVectorLayer (geojsonObject) {
this.drawFatherFeature()
if (this.clusters) {
if (this.isClusters) {
this.map.removeLayer(this.clusters)
}
this.clusters = null
}
if (this.vectorLayer) {
if (this.isVectorLayer) {
this.map.removeLayer(this.vectorLayer)
this.map.removeInteraction(this.selectclick)
}
this.vectorLayer = null
this.selectclick = null
}
this.vectorSource = new VectorSource({
features: new GeoJSON().readFeatures(geojsonObject)
})
var styles = {
Point: new Style({
image: new CircleStyle({
radius: 7,
fill: new Fill({
color: 'rgba(173,216,230)'
}),
stroke: new Stroke({
lineDash: [1, 2, 3, 4, 5, 6],
color: 'rgba(70,130,180)',
width: 2
})
}),
stroke: new Stroke({
lineDash: [1, 2, 3, 4, 5, 6],
color: 'rgba(70,130,180)',
width: 2
}),
fill: new Fill({
color: 'rgba(173,216,230)'
})
}),
LineString: new Style({
stroke: new Stroke({
color: 'green',
width: 3
})
}),
Polygon: new Style({
stroke: new Stroke({
color: 'blue',
lineDash: [4],
width: 3
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)'
})
})
}
var styleFunction = function (feature) {
return styles[feature.getGeometry().getType()]
}
var allfearures = this.vectorSource.getFeatures()
for (var i = 0; i < allfearures.length; i++) {
allfearures[i].setId(allfearures[i].get('id'))
}
this.vectorLayer = new VectorLayer({
id: 'vectorlayer',
source: this.vectorSource,
style: styleFunction
})
this.vectorLayer.setZIndex(4)
this.map.addLayer(this.vectorLayer)
this.isVectorLayer = true
let this1 = this
this.selectclick = new Select({
layers: [this.vectorLayer]
})
this.selectclick.on('select', function (e) {
this1.edition = ''
this1.editionoptions = []
this1.EditionInfo = {}
this1.FeaturesId = []
var features = e.selected
if (features.length > 0) {
let that = this1
var feature = features[0]
var type = feature.getGeometry().getType()
if (that.ifsub === false) {
that.fathergeom = feature.getGeometry()
}
console.log(that.fathergeom)
var tmp = 1
if (type === 'LineString' || type === 'Point') {
that.FeaturesId.push({
value: feature.get('id'),
label: feature.get('id')
})
that.currentFeatureId = feature.get('id')
tmp = 0
}
this.getFeatures().clear()
var coordinate = e.mapBrowserEvent.coordinate
var Features = that.vectorSource.getFeaturesAtCoordinate(coordinate)
for (var i = 0; i < Features.length; i++) {
that.FeaturesId.push({
value: Features[i].get('id'),
label: Features[i].get('id')
})
if (i === 0 && tmp === 1) {
that.currentFeatureId = Features[i].get('id')
}
}
2025-11-28 12:58:45 +08:00
// 获取并显示要素属性(无论哪个标签页都获取)
that.getFeatureData()
2025-11-26 16:28:14 +08:00
}
})
this.map.addInteraction(this.selectclick)
},
drawFatherFeature () {
// 如果已存在父几何图层,先移除它
if (this.fatherFeatureLayer) {
if (this.isFatherFeatureLayer) {
this.map.removeLayer(this.fatherFeatureLayer)
}
this.fatherFeatureLayer = null
}
// 如果 fathergeom 存在,则绘制它
if (this.fathergeom) {
// 创建一个 feature 来容纳 fathergeom
const fatherFeature = new Feature({
geometry: this.fathergeom
})
// 为父几何图形创建特殊样式(红色高亮)
const fatherStyle = new Style({
image: new CircleStyle({
radius: 8,
fill: new Fill({
color: 'rgba(255, 0, 0, 0.7)'
}),
stroke: new Stroke({
color: 'rgba(255, 0, 0, 1)',
width: 3
})
}),
stroke: new Stroke({
color: 'rgba(255, 0, 0, 1)',
width: 4
}),
fill: new Fill({
color: 'rgba(255, 0, 0, 0.3)'
})
})
// 创建父几何图形的 source 和 layer
const fatherSource = new VectorSource({
features: [fatherFeature]
})
this.fatherFeatureLayer = new VectorLayer({
source: fatherSource,
style: fatherStyle
})
this.fatherFeatureLayer.setZIndex(2)
this.map.addLayer(this.fatherFeatureLayer)
this.isFatherFeatureLayer = true
}
},
handleConfirmClick () {
// 主动移除所有可能的焦点,防止下拉菜单意外弹出
if (document.activeElement) {
document.activeElement.blur()
}
// 使用 nextTick 确保 DOM 更新完成后再执行
this.$nextTick(() => {
this.getGeoJson()
})
},
handleUserSelectBlur () {
// 处理人员选择组件失焦事件,确保下拉菜单正确关闭
this.$nextTick(() => {
// 确保下拉菜单完全关闭
const userSelect = document.getElementById('sUser')
if (userSelect) {
const selectElement = userSelect.querySelector('.el-select')
if (selectElement) {
selectElement.blur()
}
}
})
},
getGeoJson () {
if (this.pageLayer) {
this.map.removeLayer(this.pageLayer)
this.map.removeInteraction(this.selectclick1)
this.pageLayer = null
this.selectclick1 = null
}
this.examInfo = {}
this.examData = []
this.dataPageNum = 1
this.activeName1 = 'first1'
this.getList = true
this.currentFeatureId = ''
this.edition = ''
this.editionoptions = []
this.EditionInfo = {}
this.fathergeom = null
if (this.task === '') {
this.$alert('请选择任务!', '提示', {
confirmButtonText: '确定'
})
return
}
if (this.table === '') {
this.$alert('请选择表!', '提示', {
confirmButtonText: '确定'
})
return
}
/*if (this.userId === '') {
this.$alert('请选择人员!', '提示', {
confirmButtonText: '确定'
})
return
}*/
if (this.ifsub === true) {
this.table = this.fathertablename
this.ifsub = false
this.iffather = true
}
this.distribute = true
this.getRange(0)
this.getList = true
this.updataList()
},
initPageLayer () {
if (this.pageLayer) {
this.map.removeLayer(this.pageLayer)
this.pageLayer = null
this.map.removeInteraction(this.selectclick1)
}
var geojsonObject = {
type: 'FeatureCollection',
features: this.dataCoordinates,
crs: {type: 'EPSG', properties: {code: '4326'}}
}
this.pageSource = new VectorSource({
features: new GeoJSON().readFeatures(geojsonObject)
})
var styles = {
Point: new Style({
image: new CircleStyle({
radius: 7,
fill: new Fill({
color: 'rgba(173,216,230)'
}),
stroke: new Stroke({
lineDash: [1, 2, 3, 4, 5, 6],
color: 'rgba(70,130,180)',
width: 2
})
}),
stroke: new Stroke({
lineDash: [1, 2, 3, 4, 5, 6],
color: 'rgba(70,130,180)',
width: 2
}),
fill: new Fill({
color: 'rgba(173,216,230)'
})
}),
LineString: new Style({
stroke: new Stroke({
color: 'green',
width: 3
})
}),
Polygon: new Style({
stroke: new Stroke({
color: 'blue',
lineDash: [4],
width: 3
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)'
})
})
}
var styleFunction = function (feature) {
return styles[feature.getGeometry().getType()]
}
var allfearures = this.pageSource.getFeatures()
for (var i = 0; i < allfearures.length; i++) {
allfearures[i].setId(allfearures[i].get('id'))
}
this.pageLayer = new VectorLayer({
source: this.pageSource,
style: styleFunction
})
this.pageLayer.setZIndex(5)
this.map.addLayer(this.pageLayer)
if (this.activeName1 === 'first1') {
this.pageLayer.setVisible(false)
}
this.selectclick1 = new Select({
layers: [this.pageLayer]
})
let that = this
this.selectclick1.on('select', function (e) {
var features = e.selected
if (features.length > 0) {
var feature = features[0]
that.isExtend = false
that.currentFeatureId = feature.get('id')
this.getFeatures().clear()
}
})
this.map.addInteraction(this.selectclick1)
},
initPage () {
this.examData = []
for (var i = 0; i < this.dataInfo.length; i++) {
// var maxcount = 0;
var dataInfo1 = {}
for (var key in this.dataInfo[i]) {
if (
key !== 'mediaFileURLs' &&
key !== 'id' &&
this.dataInfo[i][key].toString().substring(0, 15) !== '/get/getPicture'
// && maxcount < 3
) {
// maxcount = maxcount + 1;
dataInfo1[key] = this.dataInfo[i][key]
}
}
this.examData.push(dataInfo1)
}
},
getEdition () {
if (this.currentFeatureId === '') {
this.$alert('请先选择数据!', '提示', {confirmButtonText: '确定'})
} else {
let that = this
that.editionoptions = []
request({
url: '/get/getDataVersion',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
polygonId: that.currentFeatureId
}
}).then(function (response) {
// 获取数据存入config
if (response.data.success === true) {
var options = response.data.data
that.edition = options[0]
that.getEditionData()
for (var i = 0; i < options.length; i++) {
that.editionoptions.push({
value: options[i],
label: options[i]
})
}
that.dialogVisible = true
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
} else if (response.data.success === false) {
that.$alert('当前数据无历史版本!')
}
})
}
},
getFeatureData () {
if (this.currentFeatureId !== '') {
let that = this
// 获取数据
request({
url: '/get/getDataById',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
polygonId: that.currentFeatureId,
requestor: 'browser'
}
}).then(function (response) {
if (response.data.success === true) {
var jsondata = response.data.data
var imagedata = []
var videodata = []
2025-11-28 12:58:45 +08:00
// 处理媒体文件URL
if (jsondata.mediaFileURLs && Array.isArray(jsondata.mediaFileURLs)) {
for (var i = 0; i < jsondata.mediaFileURLs.length; i++) {
var url = jsondata.mediaFileURLs[i]
if (!url) continue
// 获取文件扩展名(支持多种格式)
var urlLower = url.toLowerCase()
var ext = ''
var lastDot = urlLower.lastIndexOf('.')
if (lastDot > 0) {
ext = urlLower.substring(lastDot + 1)
}
// 图片格式jpg, jpeg, png, gif, bmp, webp
if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext)) {
imagedata.push(url)
}
// 视频格式avi, mp4, mov, wmv, flv, mkv, webm
else if (['avi', 'mp4', 'mov', 'wmv', 'flv', 'mkv', 'webm'].includes(ext)) {
videodata.push(url)
}
2025-11-26 16:28:14 +08:00
}
}
jsondata.imagedata = imagedata
jsondata.videodata = videodata
that.Info = jsondata
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
}
})
}
},
getEditionData () {
if (this.edition !== '') {
let that = this
request({
url: '/get/getDataByIdAndVersion',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
polygonId: that.currentFeatureId,
version: that.edition
}
}).then(function (response) {
if (response.data.success === true) {
var jsondata = response.data.data
var imagedata = []
var videodata = []
for (var i = 0; i < jsondata.mediaFileURLs.length; i++) {
if (
jsondata.mediaFileURLs[i].substring(
jsondata.mediaFileURLs[i].length - 3
) === 'jpg'
) {
imagedata.push(jsondata.mediaFileURLs[i])
} else if (
jsondata.mediaFileURLs[i].substring(
jsondata.mediaFileURLs[i].length - 3
) === 'avi'
) {
videodata.push(jsondata.mediaFileURLs[i])
}
}
jsondata.imagedata = imagedata
jsondata.videodata = videodata
that.EditionInfo = jsondata
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
}
})
}
},
Rollback () {
if (this.edition === '') {
this.$alert('请先选择历史版本!', '提示', {
confirmButtonText: '确定'
})
} else {
let that = this
request({
url: '/base/rollBackDataForVersion',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
polygonId: that.currentFeatureId,
version: that.edition
}
}).then(function (response) {
if (response.data.success === true) {
that.$alert('版本回退成功!', '提示', {
confirmButtonText: '确定'
})
that.edition = ''
that.Info = {}
that.currentFeatureId = ''
that.editionoptions = []
that.EditionInfo = {}
that.getClusters()
that.dialogVisible = false
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
}
})
}
},
passData () {
if (this.currentFeatureId === '') {
this.$alert('请先选择数据!', '提示', {confirmButtonText: '确定'})
} else {
this.$confirm('确认该数据审核通过吗?', '提示', {}).then(() => {
let that = this
// 审核通过请求
request({
url: '/base/setDataStatus',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
polygonId: that.currentFeatureId,
pass: true
}
}).then(function (response) {
if (response.data.success === true) {
that.$alert('操作成功!', '提示', {confirmButtonText: '确定'})
that.changeCurrentInfo(that.pageNumber, that.currentFeatureId)
that.updataList()
that.getList = true
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
}
})
})
}
},
deleteData () {
if (this.currentFeatureId === '') {
this.$alert('请先选择数据!', '提示', {confirmButtonText: '确定'})
} else {
this.$prompt('请输入审核未通过原因', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /\S/,
inputErrorMessage: '输入原因不可为空'
})
.then(({value}) => {
let that = this
// 审核未通过请求
request({
url: '/base/setDataStatus',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
polygonId: that.currentFeatureId,
pass: false,
reason: value
}
}).then(function (response) {
if (response.data.success === true) {
that.$message({
type: 'success',
message: '操作成功'
})
that.changeCurrentInfo(that.pageNumber, that.currentFeatureId)
that.updataList()
that.getList = true
/* that.pageChange(that.pageNumber)
that.getExamInfoById(that.currentFeatureId); */
} else if (response.data.status === '401') {
that.$alert(response.data.message)
that.$router.push({path: '/login'})
} else {
that.$message({
type: 'error',
message: '操作失败'
})
}
})
})
.catch(() => {
this.$message({
type: 'info',
message: '取消操作'
})
})
}
},
getClusterData (geojsonObject) {
var Features = new GeoJSON().readFeatures(geojsonObject)
var features = new Array(Features.length)
for (var i = 0; i < Features.length; i++) {
var geometry = Features[i].getGeometry()
var coordinates = geometry.getCoordinates()
var coordinate = []
if (coordinates[0][0]) {
if (coordinates[0][0][0]) {
coordinate = coordinates[0][0]
} else {
coordinate = coordinates[0]
}
} else {
coordinate = coordinates
}
features[i] = new Feature(new Point(coordinate))
}
var clusterSource = new VectorSource({
features: features
})
var cluster = new Cluster({
distance: 40,
source: clusterSource
})
var styleCache = {}
this.clusters = new VectorLayer({
id: 'clusterlayer',
source: cluster,
style: function (feature) {
if (feature.get('features')) {
var size = feature.get('features').length
var style = styleCache[size]
if (!style) {
style = new Style({
image: new CircleStyle({
radius: 10,
stroke: new Stroke({
color: '#fff'
}),
fill: new Fill({
color: '#3399CC'
})
}),
text: new Text({
text: size.toString(),
fill: new Fill({
color: '#fff'
})
})
})
styleCache[size] = style
}
return style
}
}
})
// 聚类图层
this.clusters.setZIndex(4)
this.map.addLayer(this.clusters)
this.isClusters = true
},
setCurrentStyle1 () {
if (this.currentFeatureId !== '') {
this.getList = false
this.getExamInfoById(this.currentFeatureId)
// 改变样式
if (this.feature) {
this.feature.setStyle(undefined)
}
this.feature = this.pageSource.getFeatureById(this.currentFeatureId)
var type = this.feature.getGeometry().getType()
if (this.isExtend) {
if (type === 'Point') {
this.map
.getView()
.setCenter(this.feature.getGeometry().getExtent())
this.map.getView().setZoom(15)
} else {
var extent = this.feature.getGeometry().getExtent()
var center = [
(extent[0] + extent[2]) / 2,
(extent[1] + extent[3]) / 2
] // 获取边界区域的中心位置
this.map.getView().setCenter(center) // 设置当前地图的显示中心位置
this.map.getView().setZoom(14)
}
}
var style = new Style({
image: new CircleStyle({
radius: 7,
fill: new Fill({
color: 'yellow'
}),
stroke: new Stroke({
color: '#37eed0',
width: 3
})
}),
fill: new Fill({
color: 'yellow'
}),
stroke: new Stroke({
color: '#37eed0',
width: 3
})
})
this.feature.setStyle(style)
} else {
if (this.feature) {
this.feature.setStyle(undefined)
this.feature = null
}
}
},
setCurrentStyle () {
if (this.currentFeatureId !== '') {
this.getFeatureData()
// 改变样式
if (this.feature) {
this.feature.setStyle(undefined)
}
this.feature = this.vectorSource.getFeatureById(this.currentFeatureId)
if (this.feature) { // 添加检查确保要素存在
var style = new Style({
image: new CircleStyle({
radius: 7,
fill: new Fill({
color: 'yellow'
}),
stroke: new Stroke({
color: '#37eed0',
width: 3
})
}),
fill: new Fill({
color: 'yellow'
}),
stroke: new Stroke({
color: '#37eed0',
width: 3
})
})
this.feature.setStyle(style)
}
} else {
if (this.feature) {
this.feature.setStyle(undefined)
this.feature = null
}
}
},
clearAll () {
this.currentFeatureId = ''
this.Info = {}
this.edition = ''
this.editionoptions = []
this.EditionInfo = {}
this.FeaturesId = []
this.fathergeom = null
// 清除父几何图形显示
if (this.fatherFeatureLayer) {
if (this.isFatherFeatureLayer) {
this.map.removeLayer(this.fatherFeatureLayer)
}
this.fatherFeatureLayer = null
this.isFatherFeatureLayer = false
}
},
getExamInfoById (id) {
var jsondata = {}
for (var k = 0; k < this.dataInfo.length; k++) {
if (this.dataInfo[k].id.toString() === id) {
jsondata = JSON.parse(JSON.stringify(this.dataInfo[k]))
break
}
}
this.examInfo = {}
var imagedata = []
var videodata = []
for (var i = 0; i < jsondata.mediaFileURLs.length; i++) {
if (
jsondata.mediaFileURLs[i].substring(
jsondata.mediaFileURLs[i].length - 3
) === 'jpg'
) {
imagedata.push(jsondata.mediaFileURLs[i])
} else if (
jsondata.mediaFileURLs[i].substring(
jsondata.mediaFileURLs[i].length - 3
) === 'avi'
) {
videodata.push(jsondata.mediaFileURLs[i])
}
}
jsondata.imagedata = imagedata
jsondata.videodata = videodata
delete jsondata.mediaFileURLs
delete jsondata.id
this.examInfo = jsondata
},
getExamInfo (i) {
this.getList = false
var jsondata = this.dataInfo[i]
this.examInfo = {}
if (this.currentFeatureId === jsondata.id.toString()) {
this.getExamInfoById(this.currentFeatureId)
} else {
this.isExtend = true
this.currentFeatureId = jsondata.id.toString()
}
},
changeCurrentInfo (num, id) {
let that = this
if (this.table !== '') {
request({
url: '/get/getDataByPageNum',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
pageNum: num,
pageSize: that.pageSize,
status: that.datastatus,
workerId: that.userId
}
}).then(function (response) {
if (response.data.data) {
that.dataInfo = response.data.data.dataInfo
that.dataCoordinates = response.data.data.dataCoordinates
that.getExamInfoById(id)
that.initPage()
that.initPageLayer()
}
})
}
},
updataList () {
this.pageNumber = 1
if (this.table !== '') {
let that = this
request({
url: '/get/getDataByPageNum',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
pageNum: 1,
pageSize: that.pageSize,
status: that.datastatus,
workerId: that.userId
}
}).then(function (response) {
if (response.data.data) {
that.dataInfo = response.data.data.dataInfo
that.dataCoordinates = response.data.data.dataCoordinates
that.dataPageNum = response.data.data.dataPageNum
that.initPage()
that.initPageLayer()
} else {
that.examData = []
that.dataInfo = []
that.dataCoordinates = null
that.dataPageNum = 0
that.map.removeLayer(that.pageLayer)
}
})
}
},
pageChange (val) {
let that = this
this.pageNumber = val
if (this.table !== '') {
request({
url: '/get/getDataByPageNum',
method: 'post',
params: {
taskId: that.task,
tableName: that.table,
pageNum: val,
pageSize: that.pageSize,
status: that.datastatus,
workerId: that.userId
}
}).then(function (response) {
if (response.data.data) {
that.dataInfo = response.data.data.dataInfo
that.dataCoordinates = response.data.data.dataCoordinates
that.initPage()
that.initPageLayer()
}
})
}
},
pageSizeChange (pageSize) {
this.pageSize = pageSize
this.pageNumber = 1
},
getSubGeoJson () {
if (!this.currentFeatureId) {
this.$alert('请先在地图上选择一个要素!', '提示', {
confirmButtonText: '确定'
})
return
}
this.selectId = this.currentFeatureId
// 保存当前状态
this.fathertablename = this.table
// 设置新的表名
if (this.table === 'roottable1') {
this.table = 't1sub1'
} else if (this.table === 'roottable3') {
this.table = 't3sub'
} else if (this.table === 'roottable4') {
this.table = 't4sub'
}
this.ifsub = true
// 清理现有图层和交互
this.clearAllLayersAndInteractions()
// 重置相关状态
this.FeaturesId = []
this.Info = {}
this.currentFeatureId = ''
// 获取子区域范围并更新数据列表
this.distribute = true
this.getRange(0)
this.updataList()
},
clearAllLayersAndInteractions () {
// 清除聚类图层
if (this.clusters) {
if (this.isClusters) {
this.map.removeLayer(this.clusters)
}
this.clusters = null
this.isClusters = false
}
// 清除矢量图层和交互
if (this.vectorLayer) {
if (this.isVectorLayer) {
this.map.removeLayer(this.vectorLayer)
this.map.removeInteraction(this.selectclick)
}
this.vectorLayer = null
this.selectclick = null
this.isVectorLayer = false
}
// 清除分页图层和交互
if (this.pageLayer) {
this.map.removeLayer(this.pageLayer)
this.map.removeInteraction(this.selectclick1)
this.pageLayer = null
this.selectclick1 = null
}
// 清除cellLayer
this.cellLayer = null
// 清除父几何图层
if (this.fatherFeatureLayer) {
if (this.isFatherFeatureLayer) {
this.map.removeLayer(this.fatherFeatureLayer)
}
this.fatherFeatureLayer = null
this.isFatherFeatureLayer = false
}
// 重置相关数据
this.FeaturesId = []
this.Info = {}
this.EditionInfo = {}
this.editionoptions = []
this.edition = ''
}
},
watch: {
currentFeatureId: {
handler () {
if (this.vectorLayer && this.activeName1 === 'first1') {
this.setCurrentStyle()
}
if (this.pageLayer && this.activeName1 === 'second1') {
this.setCurrentStyle1(1)
}
2025-11-28 12:58:45 +08:00
// 在"数据查看"标签页中,当选择要素时获取要素数据
if (this.activeName === 'second' && this.currentFeatureId && this.task && this.table) {
this.getFeatureData()
}
2025-11-26 16:28:14 +08:00
}
},
vectorSource: {
handler () {
if (this.vectorLayer) {
this.setCurrentStyle()
}
}
},
activeName1: {
handler () {
if (this.activeName1 === 'first1') {
this.clearAll()
this.getClusters()
if (this.pageLayer) {
this.pageLayer.setVisible(false)
}
} else {
this.clearAll()
if (this.clusters) {
if (this.isClusters) {
this.map.removeLayer(this.clusters)
}
this.clusters = null
}
if (this.vectorLayer) {
if (this.isVectorLayer) {
this.map.removeLayer(this.vectorLayer)
this.map.removeInteraction(this.selectclick)
}
this.vectorLayer = null
this.selectclick = null
}
this.cellLayer = null
if (this.pageLayer) {
this.pageLayer.setVisible(true)
this.map.getView().fit(this.pageLayer.getSource().getExtent())
}
}
}
},
datastatus: {
handler () {
this.updataList()
this.getList = true
}
},
table: {
handler () {
if (this.clusters) {
if (this.isClusters) {
this.map.removeLayer(this.clusters)
}
this.clusters = null
}
if (this.vectorLayer) {
if (this.isVectorLayer) {
this.map.removeLayer(this.vectorLayer)
this.map.removeInteraction(this.selectclick)
}
this.vectorLayer = null
this.selectclick = null
}
this.cellLayer = null
if (this.pageLayer) {
this.map.removeLayer(this.pageLayer)
this.map.removeInteraction(this.selectclick1)
this.pageLayer = null
this.selectclick1 = null
}
this.currentFeatureId = ''
this.Info = {}
this.edition = ''
this.editionoptions = []
this.EditionInfo = {}
this.FeaturesId = []
this.examInfo = {}
this.examData = []
this.dataPageNum = 1
this.activeName1 = 'first1'
this.getList = true
}
}
}
}
</script>
<style scoped lang='scss'>
.el-input__inner {
&::placeholder {
font-family: PingFangSC-Regular;
font-size: 14px;
color: #c0c4cc;
}
}
.ol-popup {
position: absolute;
background-color: white;
-webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
}
.ol-popup:after,
.ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
.taskChoser {
margin: 5px 0px 5px 0px;
}
.mylabel {
2025-11-28 12:58:45 +08:00
display: flex;
align-items: center;
flex-wrap: wrap;
margin: 0 0 8px 0;
padding: 4px 14px;
font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif;
2025-11-26 16:28:14 +08:00
font-size: 14px;
2025-11-28 12:58:45 +08:00
font-weight: 600;
color: #1B5E20;
background: rgba(232, 245, 233, 0.85);
border: 1px solid rgba(129, 199, 132, 0.4);
border-radius: 12px;
letter-spacing: 0.5px;
line-height: 1.4;
}
.mylabel .label-text {
display: inline-block;
min-width: 60px;
flex-shrink: 0;
text-align: right;
}
.mylabel ::v-deep .el-select,
.mylabel ::v-deep .el-input {
flex: 1;
min-width: 220px;
2025-11-26 16:28:14 +08:00
}
.el-icon-circle-close {
color: white;
}
</style>