/> | /> | ||||
</n-form-item> | </n-form-item> | ||||
<n-form-item label="问题描述:"> | <n-form-item label="问题描述:"> | ||||
<span>{{ form.content }}</span> | |||||
<span>{{ form.questionDesc }}</span> | |||||
</n-form-item> | </n-form-item> | ||||
<n-form-item label="经纬度:"> | <n-form-item label="经纬度:"> | ||||
<span>{{ form.longitude }},{{ form.latitude }}</span> | |||||
<span>{{ form.lng }},{{ form.lat }}</span> | |||||
</n-form-item> | </n-form-item> | ||||
<n-form-item label="问题图片:"> | <n-form-item label="问题图片:"> | ||||
<img class="image_size" :src="form.fileImage" alt="" style="width: 108px; height: auto; margin: 0 5px 5px 0"> | |||||
<img class="image_size" :src="form.fileMarkerUrl" alt="" style="width: 108px; height: auto; margin: 0 5px 5px 0"> | |||||
</n-form-item> | </n-form-item> | ||||
</n-form> | </n-form> | ||||
</div> | </div> | ||||
<div class="btn_list"> | |||||
<n-button class="btn_item" type="primary" @click="makeSure">确定</n-button> | |||||
<n-button class="btn_item" @click="pass">忽略</n-button> | |||||
<div v-if="positionType === 'handle'" class="btn_list"> | |||||
<n-button v-if="form.status !== 1" class="btn_item" type="primary" @click="makeSure">确定</n-button> | |||||
<n-button v-if="form.status !== 2" class="btn_item" @click="pass">忽略</n-button> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { toRefs, reactive, watch, inject } from 'vue' | import { toRefs, reactive, watch, inject } from 'vue' | ||||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
export default { | export default { | ||||
name: 'OverLay', | name: 'OverLay', | ||||
props: { | props: { | ||||
data: { | data: { | ||||
type: Object, | type: Object, | ||||
default: () => null | default: () => null | ||||
}, | |||||
type: { | |||||
type: String, | |||||
default: '' | |||||
} | } | ||||
}, | }, | ||||
emits: { | emits: { | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const data = reactive({ | const data = reactive({ | ||||
form: {}, | form: {}, | ||||
typeList: [ | |||||
{ value: 1, label: '林斑' }, | |||||
{ value: 2, label: '病虫害' } | |||||
] | |||||
positionType: '', | |||||
typeList: [] | |||||
}) | }) | ||||
/* 引入祖先组件注册的方法 */ | /* 引入祖先组件注册的方法 */ | ||||
const confirm = inject('confirm', null) | |||||
const ignore = inject('ignore', null) | |||||
const handleRow = inject('handleRow', null) | |||||
watch(() => props.data, () => { | watch(() => props.data, () => { | ||||
data.positionType = props.type | |||||
data.typeList = QUESTION_TYPE | |||||
data.form = Object.assign({}, props.data) | data.form = Object.assign({}, props.data) | ||||
}) | }) | ||||
const updateVisible = function() { | const updateVisible = function() { | ||||
emit('close') | emit('close') | ||||
} | } | ||||
function makeSure() { | function makeSure() { | ||||
confirm(data.form) | |||||
handleRow('confirm', data.form.id, data.form.type) | |||||
updateVisible() | updateVisible() | ||||
} | } | ||||
function pass() { | function pass() { | ||||
ignore(data.form) | |||||
handleRow('ignore', data.form.id, data.form.type) | |||||
updateVisible() | updateVisible() | ||||
} | } | ||||
return { | return { |
<div class="main_container"> | <div class="main_container"> | ||||
<div id="track" ref="map" /> | <div id="track" ref="map" /> | ||||
<div id="pointOverlay" class="point_overlay"> | <div id="pointOverlay" class="point_overlay"> | ||||
<over-lay :data="problemData" @close="closeOverlay" /> | |||||
<over-lay :data="problemData" :type="positionType" @close="closeOverlay" /> | |||||
</div> | </div> | ||||
<ul class="legend_list"> | <ul class="legend_list"> | ||||
data: { | data: { | ||||
type: Array, | type: Array, | ||||
default: () => {} | default: () => {} | ||||
}, | |||||
type: { | |||||
type: String, | |||||
default: '' | |||||
} | } | ||||
}, | }, | ||||
emits: {}, | emits: {}, | ||||
const data = reactive({ | const data = reactive({ | ||||
problemList: props.data, // 问题矢量点列表 | problemList: props.data, // 问题矢量点列表 | ||||
problemData: {}, // 问题点数据 | problemData: {}, // 问题点数据 | ||||
positionType: props.type, // 组件展示类型 look 纯展示, handle 带操作 | |||||
legendList: legendList | legendList: legendList | ||||
}) | }) | ||||
if (data.length) { | if (data.length) { | ||||
data.forEach((item) => { | data.forEach((item) => { | ||||
const pointItem = [] | const pointItem = [] | ||||
pointItem.push(parseFloat(item.longitude)) | |||||
pointItem.push(parseFloat(item.latitude)) | |||||
pointItem.push(parseFloat(item.lng)) | |||||
pointItem.push(parseFloat(item.lat)) | |||||
const featureItem = new Feature(new Point(fromLonLat(pointItem))) | const featureItem = new Feature(new Point(fromLonLat(pointItem))) | ||||
points.push(fromLonLat(pointItem)) | points.push(fromLonLat(pointItem)) | ||||
featureItem.setProperties({ item: item, type: 'problem' }, false) | featureItem.setProperties({ item: item, type: 'problem' }, false) | ||||
watch(() => props.data, (value) => { | watch(() => props.data, (value) => { | ||||
if (value) { | if (value) { | ||||
if (mapdata.value) { | if (mapdata.value) { | ||||
console.log('数据变化===============================') | |||||
removeVector(problemLayer.value) | removeVector(problemLayer.value) | ||||
getLayer(props.data) | getLayer(props.data) | ||||
} | } |
import 'ol/ol.css' | import 'ol/ol.css' | ||||
import { Style, Icon } from 'ol/style' | import { Style, Icon } from 'ol/style' | ||||
import imgAwait from '../../assets/point/await.png' | |||||
import imgChecked from '../../assets/point/checked.png' | |||||
import imgIgnored from '../../assets/point/ignored.png' | |||||
import imgSelected from '../../assets/point/selected.png' | |||||
import imgAwait from '@/assets/point/await.png' | |||||
import imgChecked from '@/assets/point/checked.png' | |||||
import imgIgnored from '@/assets/point/ignored.png' | |||||
import imgSelected from '@/assets/point/selected.png' | |||||
// 矢量图标样式 | // 矢量图标样式 | ||||
export const styleList = [ | export const styleList = [ | ||||
new Style({ | new Style({ | ||||
image: new Icon({ | image: new Icon({ | ||||
anchor: [0.5, 0.5], | anchor: [0.5, 0.5], | ||||
src: imgAwait, | |||||
src: imgChecked, | |||||
crossOrigin: '', | crossOrigin: '', | ||||
scale: [1, 1], | scale: [1, 1], | ||||
rotateWithView: true | rotateWithView: true | ||||
new Style({ | new Style({ | ||||
image: new Icon({ | image: new Icon({ | ||||
anchor: [0.5, 0.5], | anchor: [0.5, 0.5], | ||||
src: imgChecked, | |||||
src: imgIgnored, | |||||
crossOrigin: '', | crossOrigin: '', | ||||
scale: [1, 1], | scale: [1, 1], | ||||
rotateWithView: true | rotateWithView: true | ||||
new Style({ | new Style({ | ||||
image: new Icon({ | image: new Icon({ | ||||
anchor: [0.5, 0.5], | anchor: [0.5, 0.5], | ||||
src: imgIgnored, | |||||
src: imgAwait, | |||||
crossOrigin: '', | crossOrigin: '', | ||||
scale: [1, 1], | scale: [1, 1], | ||||
rotateWithView: true | rotateWithView: true |
<template> | <template> | ||||
<div> | |||||
问题分布 | |||||
<div class="question-container"> | |||||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||||
<position-msg :data="dataList" :type="positionType" /> | |||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { reactive, toRefs } from '@vue/reactivity' | |||||
import search from './tools/search.js' | |||||
import HeadSearch from '@/components/Search/index.vue' | |||||
import PositionMsg from '@/components/PositionMsg/index.vue' | |||||
export default { | export default { | ||||
name: 'QuestionDistribution', | name: 'QuestionDistribution', | ||||
components: { PositionMsg, HeadSearch }, | |||||
setup() { | setup() { | ||||
const data = reactive({ | |||||
search, | |||||
dataList: [ | |||||
{ lng: '118.32002', lat: '32.345623' } | |||||
], | |||||
positionType: 'look' | |||||
}) | |||||
return { | |||||
...toRefs(data) | |||||
} | |||||
} | } | ||||
} | } | ||||
</script> | </script> | ||||
<style scoped lang='scss'> | <style scoped lang='scss'> | ||||
.question-container { | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
</style> | </style> |
import { reactive } from 'vue' | |||||
const data = reactive([ | |||||
{ | |||||
label: '选择时间', | |||||
key: 'time', | |||||
type: 'date', | |||||
value: null, | |||||
props: { | |||||
type: 'daterange', | |||||
valueFormat: 'yyyy-MM-dd HH:mm:ss', | |||||
format: 'yyyy-MM-dd HH:mm:ss' | |||||
} | |||||
}, | |||||
{ | |||||
label: '搜索任务', | |||||
key: 'name', | |||||
props: { | |||||
placeholder: '请输入任务名称' | |||||
} | |||||
} | |||||
]) | |||||
export default data | |||||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
import TableImage from '@/components/DataTable/tools/Image.vue' | |||||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||||
import { h, ref, reactive } from 'vue' | |||||
/* 注册table */ | |||||
const tableRef = ref() | |||||
const searchParams = ref() | |||||
function handleSearch(params) { | |||||
searchParams.value = { ...params } | |||||
if (params?.time?.length) { | |||||
searchParams.value = { | |||||
startTime: params.time[0], | |||||
endTime: params.time[1] | |||||
} | |||||
} | |||||
delete searchParams.value.time | |||||
tableRef.value.reFetch({ searchParams }) | |||||
} | |||||
/* 位置 */ | |||||
function handlePositionDrawer(row) { | |||||
data.rowData = row | |||||
data.positionDrawer = true | |||||
} | |||||
const data = reactive({ | |||||
tableRef, | |||||
searchParams, | |||||
rowData: {}, | |||||
positionDrawer: false, | |||||
handleSearch, | |||||
columns: [ | |||||
{ | |||||
title: '序号', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '问题类型', | |||||
key: 'type', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.type, | |||||
filters: QUESTION_TYPE | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '问题图片', | |||||
key: 'fileMarkerUrl', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableImage, { | |||||
images: { | |||||
width: 36, | |||||
height: 36, | |||||
src: row.fileMarkerUrl | |||||
// previewDisabled: true | |||||
// onClick: handleImgPreview.bind(null, row) | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '经纬度', | |||||
key: 'name', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: [{ name: row.lng }, { name: row.lat }] | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '位置', | |||||
key: 'position', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '图片位置', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handlePositionDrawer.bind(null, row) | |||||
}, | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '备注', | |||||
key: 'note', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '所属任务', | |||||
key: 'note', | |||||
align: 'center' | |||||
} | |||||
] | |||||
}) | |||||
export default data |
import { getQuestionList } from '@/api/task/index.js' | import { getQuestionList } from '@/api/task/index.js' | ||||
export default { | export default { | ||||
name: 'TaskAll', | |||||
name: 'QuestionList', | |||||
components: { HeadSearch, DataTable }, | components: { HeadSearch, DataTable }, | ||||
setup() { | setup() { | ||||
const data = reactive({ | const data = reactive({ |
<template> | <template> | ||||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | <n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | ||||
<n-drawer-content closable title="飞行直播"> | <n-drawer-content closable title="飞行直播"> | ||||
<BaseMap /> | |||||
<div class="main_container"> | |||||
<div id="live-map" /> | |||||
</div> | |||||
</n-drawer-content> | </n-drawer-content> | ||||
</n-drawer> | </n-drawer> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import BaseMap from './BaseMap.vue' | |||||
import { h, defineComponent, computed, reactive, toRefs } from 'vue' | |||||
import { defineComponent, computed, reactive, toRefs, onMounted } from 'vue' | |||||
import { Map, View, Feature } from 'ol' | |||||
import 'ol/ol.css' | |||||
import { Tile, Vector as VectorLayer } from 'ol/layer' | |||||
import LineString from 'ol/geom/LineString' | |||||
import Point from 'ol/geom/Point' | |||||
import { XYZ, Vector as VectorSource } from 'ol/source' | |||||
import { transform, fromLonLat } from 'ol/proj' | |||||
import { getVectorContext } from 'ol/render' | |||||
import VectorContext from 'ol/render/VectorContext' | |||||
import { Draw } from 'ol/interaction' | |||||
import { toRaw } from '@vue/reactivity' | |||||
import * as control from 'ol/control' | |||||
import { styleList } from '../tools/style.js' | |||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'LiveDrawer', | name: 'LiveDrawer', | ||||
components: { BaseMap }, | |||||
props: { | props: { | ||||
/* 可见 */ | /* 可见 */ | ||||
visible: { | visible: { | ||||
}, | }, | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const data = reactive({ | const data = reactive({ | ||||
mapData: null, | |||||
view: null, | |||||
liveTrackLayer: null, | |||||
lineTrackLayer: null, | |||||
trackInfo: null, | |||||
socket: null, | |||||
// 预计航线数据 | |||||
lineTrajectoryList: [ | |||||
{ lng: '118.765591', lat: '32.050993' }, | |||||
{ lng: '118.665591', lat: '32.150993' }, | |||||
{ lng: '118.565591', lat: '32.070993' }, | |||||
{ lng: '118.465591', lat: '32.020993' }, | |||||
{ lng: '118.365591', lat: '32.110993' }, | |||||
{ lng: '118.265591', lat: '32.080993' }, | |||||
{ lng: '118.165591', lat: '32.150993' }, | |||||
{ lng: '118.765591', lat: '32.150993' }, | |||||
{ lng: '118.665591', lat: '32.050993' }, | |||||
{ lng: '118.565591', lat: '32.170993' }, | |||||
{ lng: '118.465591', lat: '32.010993' }, | |||||
{ lng: '118.365591', lat: '32.060993' }, | |||||
{ lng: '118.265591', lat: '32.180993' }, | |||||
{ lng: '118.165591', lat: '32.050993' } | |||||
], | |||||
// 轨迹数据 | |||||
trackList: [ | |||||
{ lng: '118.765591', lat: '32.050993' }, | |||||
{ lng: '118.665591', lat: '32.150993' }, | |||||
{ lng: '118.565591', lat: '32.070993' }, | |||||
{ lng: '118.465591', lat: '32.020993' }, | |||||
{ lng: '118.365591', lat: '32.110993' }, | |||||
{ lng: '118.265591', lat: '32.080993' }, | |||||
{ lng: '118.165591', lat: '32.150993' } | |||||
], | |||||
trajectoryList: [], // 历史轨迹坐标数据 | |||||
disdance: null, | |||||
animating: null | |||||
}) | }) | ||||
/* 获取抽屉的信息 */ | /* 获取抽屉的信息 */ | ||||
const getDrawerOptions = computed(() => { | const getDrawerOptions = computed(() => { | ||||
return { | return { | ||||
emit('update:visible', false) | emit('update:visible', false) | ||||
} | } | ||||
onMounted(() => { | |||||
initMap() | |||||
// 加载航线 | |||||
initTrack(formatTradeList(data.lineTrajectoryList), 'lineTrackLayer', 'lineRoute') | |||||
// 加载历史轨迹和实时轨迹 | |||||
setLiveTrack(formatTradeList(data.trackList)) | |||||
}) | |||||
/* 初始化地图 */ | |||||
const initMap = function() { | |||||
const layers = [ | |||||
new Tile({ | |||||
visible: true, | |||||
source: new XYZ({ | |||||
url: 'https://tianditu.t-aaron.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=f82bb2fd8115c7fb576a8b2fcf738523' | |||||
}) | |||||
}) | |||||
] | |||||
data.view = new View({ | |||||
maxZoom: 18, | |||||
zoom: 5, | |||||
center: transform([118.837886, 32.057175], 'EPSG:4326', 'EPSG:3857') | |||||
}) | |||||
data.mapData = new Map({ | |||||
layers: layers, | |||||
target: 'live-map', | |||||
view: data.view, | |||||
controls: control.defaults({ | |||||
attribution: false, | |||||
rotate: false, | |||||
zoom: false | |||||
}) | |||||
}) | |||||
data.mapData.render() | |||||
} | |||||
/* 处理轨迹列表 */ | |||||
const formatTradeList = function(trackList) { | |||||
return trackList.map((item) => | |||||
fromLonLat([parseFloat(item.lng), parseFloat(item.lat)]) | |||||
) | |||||
} | |||||
/* 初始化轨迹 */ | |||||
const initTrack = function(coordinate, layer, routeType) { | |||||
let vectorLayer = null | |||||
const route = new LineString(coordinate) | |||||
const routeFeature = new Feature({ | |||||
type: routeType, | |||||
geometry: route | |||||
}) | |||||
const startMarker = new Feature({ | |||||
type: 'icon', | |||||
geometry: new Point(route.getFirstCoordinate()) | |||||
}) | |||||
const position = startMarker.getGeometry().clone() | |||||
const geoMarker = new Feature({ | |||||
type: 'geoMarker', | |||||
geometry: position | |||||
}) | |||||
geoMarker.setProperties({ type: 'geoMarker' }, false) | |||||
if (data.liveTrackLayer) { | |||||
data.liveTrackLayer.setSource( | |||||
new VectorSource({ | |||||
features: [geoMarker, routeFeature] | |||||
}) | |||||
) | |||||
vectorLayer = data.liveTrackLayer | |||||
} else { | |||||
vectorLayer = new VectorLayer({ | |||||
source: new VectorSource({ | |||||
features: [geoMarker, routeFeature] | |||||
}), | |||||
style: function(feature) { | |||||
return styleList[feature.get('type')] | |||||
} | |||||
}) | |||||
} | |||||
data[layer] = vectorLayer | |||||
data.mapData.addLayer(data[layer]) | |||||
data.view.fit(route, { padding: [50, 50, 50, 50] }) | |||||
return { | |||||
vectorLayer, | |||||
geoMarker, | |||||
route, | |||||
position | |||||
} | |||||
} | |||||
/* 轨迹改变 */ | |||||
const changeTrack = (event) => { | |||||
try { | |||||
const vectorContext = getVectorContext(event) | |||||
vectorContext.setStyle(styleList['geoMarker']) | |||||
VectorContext.drawGeometry(data.trackInfo.position) | |||||
vectorContext.drawGeometry(data.trackInfo.route) | |||||
data.mapData.render() | |||||
} catch { | |||||
console.log(event) | |||||
} | |||||
} | |||||
/* 加载实时轨迹 */ | |||||
const setLiveTrack = function(hisTrackList) { | |||||
data.animating = false | |||||
data.disdance = 0 | |||||
if (hisTrackList.length > 1) { | |||||
data.trackInfo = initTrack(hisTrackList, 'liveTrackLayer', 'route') | |||||
if (data.trackInfo.vectorLayer) { | |||||
data.liveTrackLayer.on('change', changeTrack) | |||||
} | |||||
} | |||||
// 两秒钟获取一次数据 | |||||
data.socket = setInterval(() => { | |||||
// getTrackdata({ inspectionId: id }).then((res) => { | |||||
// const coordinate = fromLonLat([res.data.lng, res.data.lat]) | |||||
// const unUseableCoordinate = !coordinate.every((item) => !isNaN(item)) | |||||
// if (unUseableCoordinate) return | |||||
// // 赋值动态无人机坐标 | |||||
// if (coordinate.length) { | |||||
// data.trajectoryList.lng = coordinate[0] | |||||
// data.trajectoryList.lat = coordinate[1] | |||||
// } | |||||
// data.trackList.push(coordinate) | |||||
// if (data.trackList.length > 1 && !data.trackInfo) { | |||||
// initTrack(data.trackList) | |||||
// } | |||||
// if (data.trackInfo) { | |||||
// data.trackInfo.route.appendCoordinate(coordinate) | |||||
// data.trackInfo.vectorLayer.getSource().changed() | |||||
// data.trackInfo.position.setCoordinates(coordinate) | |||||
// } | |||||
// }) | |||||
}, 2000) | |||||
// 移动要素 | |||||
const moveFeature = function(event) { | |||||
var lastTime | |||||
const speed = Number(50) | |||||
const time = event.frameState.time | |||||
const elapsedTime = time - lastTime | |||||
data.disdance = (data.disdance + (speed * elapsedTime) / 1e6) % 2 | |||||
if (data.disdance > 1) { | |||||
stopAnimation(data.trackInfo) | |||||
} | |||||
lastTime = time | |||||
const currentCoordinate = data.trackInfo.route.getCoordinateAt( | |||||
data.disdance > 1 ? 2 - data.disdance : data.disdance | |||||
) | |||||
data.trackInfo.position.setCoordinates(currentCoordinate) | |||||
const vectorContext = getVectorContext(event) | |||||
vectorContext.setStyle(styleList['geoMarker']) | |||||
vectorContext.drawGeometry(data.trackInfo.position) | |||||
data.mapData.render() | |||||
} | |||||
// 停止动画 | |||||
const stopAnimation = function(trackInfo) { | |||||
const { vectorLayer, geoMarker } = trackInfo | |||||
data.animating = false | |||||
geoMarker.setGeometry(trackInfo.position) | |||||
vectorLayer.un('postrender', moveFeature) | |||||
} | |||||
} | |||||
return { | return { | ||||
...toRefs(data), | ...toRefs(data), | ||||
getDrawerOptions, | getDrawerOptions, | ||||
.n-button+.n-button{ | .n-button+.n-button{ | ||||
margin-left: 30px; | margin-left: 30px; | ||||
} | } | ||||
.main_container { | |||||
width: 100%; | |||||
height: 100%; | |||||
position: relative; | |||||
overflow: hidden; | |||||
} | |||||
#live-map { | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
</style> | </style> |
<!-- 新增、编辑弹窗 --> | <!-- 新增、编辑弹窗 --> | ||||
<TaskModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" @reload="handleSearch" /> | <TaskModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" @reload="handleSearch" /> | ||||
<!-- 直播抽屉 --> | <!-- 直播抽屉 --> | ||||
<LiveDrawer v-model:visible="liveDrawer" :data="rowData" /> | |||||
<LiveDrawer v-if="liveDrawer" v-model:visible="liveDrawer" :data="rowData" /> | |||||
<!-- 轨迹回放 --> | <!-- 轨迹回放 --> | ||||
<DemandDrawer v-model:visible="demandDrawer" :data="rowData" /> | <DemandDrawer v-model:visible="demandDrawer" :data="rowData" /> | ||||
<!-- 问题核实 --> | <!-- 问题核实 --> |
import { Style, Icon, Stroke } from 'ol/style' | |||||
import imgGeo from '@/assets/point/geo.png' | |||||
export const styleList = { | |||||
route: new Style({ | |||||
stroke: new Stroke({ | |||||
width: 2, | |||||
color: 'red' | |||||
}) | |||||
}), | |||||
geoMarker: new Style({ | |||||
image: new Icon({ | |||||
anchor: [0.5, 0.5], | |||||
src: imgGeo, | |||||
crossOrigin: '', | |||||
scale: [1, 1], | |||||
rotateWithView: true | |||||
}) | |||||
}), | |||||
lineRoute: new Style({ | |||||
stroke: new Stroke({ | |||||
width: 2, | |||||
color: 'yellow', | |||||
lineDash: [5] | |||||
}) | |||||
}) | |||||
} | |||||
<template> | <template> | ||||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | <n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | ||||
<n-drawer-content closable title="图片位置"> | <n-drawer-content closable title="图片位置"> | ||||
<position-msg :data="problemList" /> | |||||
<position-msg :data="problemList" :type="positionType" /> | |||||
</n-drawer-content> | </n-drawer-content> | ||||
</n-drawer> | </n-drawer> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { defineComponent, computed, reactive, toRefs, provide } from 'vue' | |||||
import { defineComponent, computed, reactive, toRefs, watch } from 'vue' | |||||
import PositionMsg from '@/components/PositionMsg/index.vue' | import PositionMsg from '@/components/PositionMsg/index.vue' | ||||
export default defineComponent({ | export default defineComponent({ | ||||
}, | }, | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const data = reactive({ | const data = reactive({ | ||||
problemList: [ | |||||
{ content: '河道内存在水生植被', | |||||
fileImage: 'https://image.t-aaron.com/XJRW20220725103839/2022-07-25-10-41-46_frame-1500-1680_type-水生植被_VMgRwh05s4clHXCu_s-live-XJRW20220725103839-b73c470768f74422b287981fc75c31c3_AI.jpg', | |||||
handlerImage: 'https://image.t-aaron.com/imagedir/kw6vv4m1yw_1658717157035.png', | |||||
handlerResult: '', | |||||
handlerTime: '2022-07-25 10:45:56', | |||||
latitude: '31.829037194418085', | |||||
location: '江苏省南京市江宁区秣陵街道东吉大道', | |||||
longitude: '118.770222690945', | |||||
name: 1, | |||||
status: 1, | |||||
type: 1, | |||||
userName: '运管单位' }, | |||||
{ content: '水生植被', | |||||
fileImage: 'https://image.t-aaron.com/XJRW20220725103839/2022-07-25-10-41-46_frame-1500-1680_type-水生植被_VMgRwh05s4clHXCu_s-live-XJRW20220725103839-b73c470768f74422b287981fc75c31c3_AI.jpg', | |||||
handlerImage: 'https://image.t-aaron.com/imagedir/kw6vv4m1yw_1658717157035.png', | |||||
handlerResult: '', | |||||
handlerTime: '2022-07-25 10:45:56', | |||||
latitude: '31.129037194418085', | |||||
location: '江苏省南京市江宁区秣陵街道东吉大道', | |||||
longitude: '118.880222690945', | |||||
name: 1, | |||||
status: 2, | |||||
type: 2, | |||||
userName: '运管单位' } | |||||
] | |||||
problemList: [], | |||||
positionType: 'handle' | |||||
}) | |||||
watch(() => props.data, (value) => { | |||||
data.problemList = [value] | |||||
}) | }) | ||||
const confirm = function(params) { | |||||
console.log(params, '确认++++++++++++') | |||||
} | |||||
const ignore = function(params) { | |||||
console.log(params, '忽略------------') | |||||
} | |||||
/* 注册确认方法 */ | |||||
provide('confirm', confirm) | |||||
/* 注册忽略方法 */ | |||||
provide('ignore', ignore) | |||||
/* 获取抽屉的信息 */ | /* 获取抽屉的信息 */ | ||||
const getDrawerOptions = computed(() => { | const getDrawerOptions = computed(() => { | ||||
return { | return { |
import DataTable from '@/components/DataTable/index.vue' | import DataTable from '@/components/DataTable/index.vue' | ||||
import ConfirmModal from './components/ConfirmModal.vue' | import ConfirmModal from './components/ConfirmModal.vue' | ||||
import PositionDrawer from './components/PositionDrawer.vue' | import PositionDrawer from './components/PositionDrawer.vue' | ||||
import { getQuestionList, generateReport, questionAnalyze } from '@/api/task/index.js' | |||||
import { unref, reactive, toRefs } from 'vue' | |||||
import { getQuestionList, generateReport } from '@/api/task/index.js' | |||||
import { unref, reactive, toRefs, provide } from 'vue' | |||||
export default { | export default { | ||||
name: 'QuestionPage', | name: 'QuestionPage', | ||||
components: { HeadSearch, DataTable, ConfirmModal, PositionDrawer }, | components: { HeadSearch, DataTable, ConfirmModal, PositionDrawer }, | ||||
data.handleRowConfirm(data.selectRowKeys) | data.handleRowConfirm(data.selectRowKeys) | ||||
} | } | ||||
/* 调用确认忽略方法 */ | |||||
function batchHandleRow(handleType, id, type) { | |||||
if (handleType === 'confirm') { | |||||
data.handleRowConfirm([id], type) | |||||
} else if (handleType === 'ignore') { | |||||
data.handleRowIgnore([id], type) | |||||
} | |||||
} | |||||
/* 注册忽略确认方法 */ | |||||
provide('handleRow', batchHandleRow) | |||||
/** | /** | ||||
* @description: 生成报告 | * @description: 生成报告 | ||||
* @return {*} | * @return {*} |