<link rel="icon" href="/favicon.ico" /> | <link rel="icon" href="/favicon.ico" /> | ||||
<title><%= title %></title> | <title><%= title %></title> | ||||
<link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.9.21/skins/default/aliplayer-min.css" /> | |||||
<script charset="utf-8" type="text/javascript" src="https://g.alicdn.com/de/prismplayer/2.9.21/aliplayer-h5-min.js"></script> | |||||
<link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.9.23/skins/default/aliplayer-min.css" /> | |||||
<script charset="utf-8" type="text/javascript" src="https://g.alicdn.com/de/prismplayer/2.9.23/aliplayer-h5-min.js"></script> | |||||
</head> | </head> | ||||
<body> | <body> |
import { defAxios as request } from '@/utils/http' | |||||
/** | |||||
* @description: 获取报告列表 | |||||
* @param {*} params | |||||
* @return {*} | |||||
*/ | |||||
export function getReportList(params) { | |||||
return request({ | |||||
url: '/report/page', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} | |||||
/** | |||||
* @description: 获取报告详情 | |||||
* @param {*} params | |||||
* @return {*} | |||||
*/ | |||||
export function getReportDetail(id) { | |||||
return request({ | |||||
url: `/report/${id}`, | |||||
method: 'GET' | |||||
}) | |||||
} | |||||
method: 'PUT' | method: 'PUT' | ||||
}) | }) | ||||
} | } | ||||
/** | |||||
* @description: 获取任务详情 | |||||
* @param {*} id 任务id | |||||
* @return {*} | |||||
*/ | |||||
export function getQuestionList(params) { | |||||
return request({ | |||||
url: '/question/page', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} | |||||
/** | |||||
* @description: 问题确认/忽略 | |||||
* @param {*} data | |||||
* @return {*} | |||||
*/ | |||||
export function changeQuestionStatus(data) { | |||||
return request({ | |||||
url: '/question/status', | |||||
method: 'PUT', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* @description: 生成报告 | |||||
* @param {*} 任务id | |||||
* @return {*} | |||||
*/ | |||||
export function generateReport(id) { | |||||
return request({ | |||||
url: `/report/generate/${id}`, | |||||
method: 'POST' | |||||
}) | |||||
} |
<template> | |||||
<div class="main_container"> | |||||
<div class="container-map" v-bind="getMapOptions" /> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { Map, View, Feature } from 'ol' | |||||
import 'ol/ol.css' | |||||
import { Tile, Vector as VectorLayer } from 'ol/layer' | |||||
import { XYZ, Vector as VectorSource } from 'ol/source' | |||||
import { transform, fromLonLat } from 'ol/proj' | |||||
import * as control from 'ol/control' | |||||
import Point from 'ol/geom/Point' | |||||
import { Style, Icon } from 'ol/style' | |||||
import plain from '@/assets/images/plain.png' | |||||
import { reactive, computed, toRefs, onMounted } from 'vue' | |||||
export default { | |||||
name: 'PositionMsg', | |||||
props: { | |||||
id: { | |||||
type: String, | |||||
default: 'map-track' | |||||
}, | |||||
coordinate: { | |||||
type: Array, | |||||
required: true | |||||
} | |||||
}, | |||||
emits: {}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
mapData: null, | |||||
mapView: null | |||||
}) | |||||
const getMapOptions = computed(() => { | |||||
return { | |||||
id: props.id | |||||
} | |||||
}) | |||||
/** | |||||
* 初始化底图 | |||||
*/ | |||||
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.mapView = new View({ | |||||
maxZoom: 18, | |||||
zoom: 4, | |||||
center: transform([108.94043, 31.008173], 'EPSG:4326', 'EPSG:3857') | |||||
}) | |||||
data.mapData = new Map({ | |||||
layers: layers, | |||||
target: props.id, | |||||
view: data.mapView, | |||||
controls: control.defaults({ | |||||
attribution: false, | |||||
rotate: false, | |||||
zoom: false | |||||
}) | |||||
}) | |||||
data.mapData.render() | |||||
} | |||||
function positionPoint(coordinate) { | |||||
data.mapView.animate( | |||||
{ center: transform(coordinate, 'EPSG:4326', 'EPSG:3857') }, | |||||
{ zoom: 18 } | |||||
) | |||||
} | |||||
/** | |||||
* 加载矢量图层 | |||||
*/ | |||||
const getLayer = function(coordinate) { | |||||
const pointFeatures = [] | |||||
const featureItem = new Feature(new Point(fromLonLat(coordinate))) | |||||
featureItem.setStyle(new Style({ | |||||
image: new Icon({ | |||||
anchor: [0.5, 0.5], | |||||
src: plain, | |||||
crossOrigin: '', | |||||
scale: [1, 1], | |||||
rotateWithView: true | |||||
}) | |||||
})) | |||||
pointFeatures.push(featureItem) | |||||
const pointSource = new VectorSource({ | |||||
wrapX: false, | |||||
features: pointFeatures | |||||
}) | |||||
const problemLayer = new VectorLayer({ | |||||
source: pointSource, | |||||
zIndex: 12 | |||||
}) | |||||
positionPoint(coordinate) | |||||
data.mapData.addLayer(problemLayer) | |||||
} | |||||
onMounted(() => { | |||||
initMap() | |||||
}) | |||||
return { | |||||
...toRefs(data), | |||||
getMapOptions, | |||||
initMap, | |||||
getLayer, | |||||
positionPoint | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped> | |||||
.main_container { | |||||
width: 100%; | |||||
height: 100%; | |||||
position: relative; | |||||
overflow: hidden; | |||||
} | |||||
.container-map { | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
</style> |
/* | |||||
* @Author: whyafterme | |||||
* @Date: 2022-07-21 13:44:46 | |||||
* @LastEditTime: 2022-07-27 09:04:01 | |||||
* @LastEditors: whyafterme | |||||
* @Description: | |||||
* @FilePath: \forest\src\router\guard\permission-guard.js | |||||
*/ | |||||
import { useUserStore } from '@/store/modules/user' | import { useUserStore } from '@/store/modules/user' | ||||
import { usePermissionStore } from '@/store/modules/permission' | import { usePermissionStore } from '@/store/modules/permission' | ||||
import { NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '@/router/routes' | import { NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '@/router/routes' |
{ label: '火灾隐患', value: 4 } | { label: '火灾隐患', value: 4 } | ||||
] | ] | ||||
export const QUESTION_STATUS = [ | |||||
{ label: '已确认', value: 1 }, | |||||
{ label: '已忽略', value: 2 }, | |||||
{ label: '待确认', value: 3 } | |||||
] | |||||
export const USER_STATUS = [ | export const USER_STATUS = [ | ||||
{ label: '正常', value: 1 }, | { label: '正常', value: 1 }, | ||||
{ label: '禁用', value: 2 } | { label: '禁用', value: 2 } |
label-placement="left" | label-placement="left" | ||||
> | > | ||||
<n-form-item label="机场选择:" path="airportId"> | <n-form-item label="机场选择:" path="airportId"> | ||||
<n-select v-model:value="videoForm.airportId" :options="airOptions" @change="getAirportInfo" /> | |||||
<n-select v-model:value="videoForm.airportId" :options="airOptions" @update:value="getAirportInfo" /> | |||||
</n-form-item> | </n-form-item> | ||||
</n-form> | </n-form> | ||||
</p> | </p> | ||||
<!-- <VideoPlayer :options="getVideoOptions.inner" /> --> | <!-- <VideoPlayer :options="getVideoOptions.inner" /> --> | ||||
</div> | </div> | ||||
<div class="video__item"> | <div class="video__item"> | ||||
<div class="item__weather"> | |||||
<ul> | |||||
<li v-for="(item,index) in weatherList" :key="index">{{ item.label }}:{{ item.value }}</li> | |||||
</ul> | |||||
</div> | |||||
<!-- <VideoPlayer :options="getVideoOptions.outer" /> --> | <!-- <VideoPlayer :options="getVideoOptions.outer" /> --> | ||||
<BaseMap ref="mapRef" :coordinate="coordinate" /> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</n-card> | </n-card> | ||||
import { dataToSelect } from '@/utils/handleData.js' | import { dataToSelect } from '@/utils/handleData.js' | ||||
import { airportList, airportWeather, airportTrack } from '@/api/dashboard/index.js' | import { airportList, airportWeather, airportTrack } from '@/api/dashboard/index.js' | ||||
import VideoPlayer from '@/components/VideoPlayer/index.vue' | import VideoPlayer from '@/components/VideoPlayer/index.vue' | ||||
import { reactive, computed, toRefs } from 'vue' | |||||
import BaseMap from '@/components/BaseMap/BaseMap.vue' | |||||
import { ref, reactive, computed, toRefs } from 'vue' | |||||
export default { | export default { | ||||
name: 'TaskCard', | name: 'TaskCard', | ||||
components: { VideoPlayer }, | |||||
components: { VideoPlayer, BaseMap }, | |||||
setup() { | setup() { | ||||
const mapRef = ref() | |||||
const data = reactive({ | const data = reactive({ | ||||
videoForm: { | videoForm: { | ||||
airportId: null | airportId: null | ||||
}, | }, | ||||
airOptions: [], | airOptions: [], | ||||
airOptionsAll: [] | |||||
airOptionsAll: [], | |||||
weatherList: [], | |||||
coordinate: [108.94043, 31.008173] | |||||
}) | }) | ||||
/** | /** | ||||
* @description: 加载表格数据 | |||||
* @description: 获取机场数据 | |||||
* @param {*} res | * @param {*} res | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
})() | })() | ||||
async function getAirportInfo(id) { | async function getAirportInfo(id) { | ||||
const airItem = data.airOptionsAll.find((item) => { return item.id === id }) | |||||
const coordinate = [airItem?.longitude, airItem?.latitude] | |||||
markPoint(coordinate) | |||||
const res = await airportWeather(id) | const res = await airportWeather(id) | ||||
if (res.code === 0) { | if (res.code === 0) { | ||||
// 1 | |||||
const parm = res.data.wth?.parm || [] | |||||
data.weatherList = parm.length !== 0 ? [ | |||||
{ label: '天气', value: '' }, | |||||
{ label: '气温', value: parm.tmp + '℃' }, | |||||
{ label: '湿度', value: parm.hum + 'RH' }, | |||||
{ label: '风度', value: parm.wspd + 'm/s' }, | |||||
{ label: '风向', value: parm.wdir } | |||||
] : [] | |||||
} | } | ||||
} | |||||
const res2 = await airportTrack(id) | |||||
if (res2.code === 0) { | |||||
// 1 | |||||
/* 地图标点 */ | |||||
const markPoint = function(coordinate) { | |||||
try { | |||||
mapRef.value.getLayer(coordinate) | |||||
} catch (e) { | |||||
markPoint(coordinate) | |||||
} | } | ||||
} | } | ||||
return { | return { | ||||
...toRefs(data), | ...toRefs(data), | ||||
mapRef, | |||||
loadAirport, | loadAirport, | ||||
getAirportInfo, | getAirportInfo, | ||||
getVideoOptions | getVideoOptions | ||||
height: calc(100% - 55px); | height: calc(100% - 55px); | ||||
.video__item{ | .video__item{ | ||||
width: calc(50% - 10px); | width: calc(50% - 10px); | ||||
position: relative; | |||||
&:first-child{ | &:first-child{ | ||||
margin-right: 20px | margin-right: 20px | ||||
} | } | ||||
.item__weather{ | |||||
position: absolute; | |||||
z-index: 100; | |||||
padding: 5px 6px; | |||||
font-size: 12px; | |||||
right: 0; | |||||
color: rgba(255, 255, 255, 1); | |||||
background: rgba(0, 0, 0, 0.4); | |||||
} | |||||
} | } | ||||
} | } | ||||
::v-deep(.n-form){ | ::v-deep(.n-form){ |
props: { | props: { | ||||
type: 'primary', | type: 'primary', | ||||
text: true, | text: true, | ||||
onClick: getRowData.bind(null, row, 'preview') | |||||
onPositiveClick: getRowData.bind(null, row, 'preview') | |||||
}, | }, | ||||
auth: 'basic_list' | auth: 'basic_list' | ||||
}, | }, | ||||
type: 'popconfirm', | type: 'popconfirm', | ||||
tip: '是否删除该数据?', | tip: '是否删除该数据?', | ||||
props: { | props: { | ||||
onClick: handleRowDelete.bind(null, row) | |||||
onPositiveClick: handleRowDelete.bind(null, row) | |||||
}, | }, | ||||
ButtonProps: { | ButtonProps: { | ||||
text: true, | text: true, |
<template> | |||||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | |||||
<n-drawer-content closable title="报告详情"> | |||||
<div class="report__container"> | |||||
<div class="report__item"> | |||||
<p class="report__item--title">林场信息</p> | |||||
<div> | |||||
<n-grid :cols="2"> | |||||
<n-gi><span>责任单位</span></n-gi> | |||||
<n-gi><span>{{ reportDetail.company }}</span></n-gi> | |||||
<n-gi><span>林场名称</span></n-gi> | |||||
<n-gi><span>{{ reportDetail.lcName }}</span></n-gi> | |||||
<n-gi><span>巡查里程</span></n-gi> | |||||
<n-gi><span>-</span></n-gi> | |||||
</n-grid> | |||||
</div> | |||||
</div> | |||||
<div class="report__item"> | |||||
<p class="report__item--title">巡检信息</p> | |||||
<div> | |||||
<n-grid :cols="2"> | |||||
<n-gi><span>气象信息</span></n-gi> | |||||
<n-gi><span v-for="(item,index) in weatherList" :key="index"> {{ item.label }}: {{ item.value }} </span></n-gi> | |||||
<n-gi><span>巡检方式</span></n-gi> | |||||
<n-gi><span>{{ reportDetail.lcName }}</span></n-gi> | |||||
<n-gi><span>巡检设备</span></n-gi> | |||||
<n-gi><span>-</span></n-gi> | |||||
<n-gi><span>巡检开始时间</span></n-gi> | |||||
<n-gi><span>{{ reportDetail?.mission?.executionStartTime }}</span></n-gi> | |||||
<n-gi><span>巡检结束时间</span></n-gi> | |||||
<n-gi><span>{{ reportDetail?.mission?.executionEndTime }}</span></n-gi> | |||||
<n-gi><span>问题数量</span></n-gi> | |||||
<n-gi><span>-</span></n-gi> | |||||
</n-grid> | |||||
</div> | |||||
</div> | |||||
<div class="report__item"> | |||||
<p class="report__item--title">巡检结果</p> | |||||
<div> | |||||
<n-grid :cols="2"> | |||||
<n-gi><span>巡检内容</span></n-gi> | |||||
<n-gi><span>巡检检查结果</span></n-gi> | |||||
<n-gi><span>林场问题图斑</span></n-gi> | |||||
<n-gi><span>-</span></n-gi> | |||||
<n-gi><span>病死树</span></n-gi> | |||||
<n-gi><span>-</span></n-gi> | |||||
<n-gi><span>人员活动</span></n-gi> | |||||
<n-gi><span>-</span></n-gi> | |||||
<n-gi><span>火灾隐患</span></n-gi> | |||||
<n-gi><span>-</span></n-gi> | |||||
</n-grid> | |||||
</div> | |||||
</div> | |||||
<div class="report__item"> | |||||
<p class="report__item--title">问题清单</p> | |||||
<!-- <n-image-group> --> | |||||
<div v-for="(item,index) in reportDetail.questionReportList" :key="index"> | |||||
<p>问题{{ index + 1 }}</p> | |||||
<n-grid :cols="2"> | |||||
<n-gi><span>坐标</span></n-gi> | |||||
<n-gi><span>{{ item.lng }},{{ item.lat }}</span></n-gi> | |||||
<n-gi><span>问题描述</span></n-gi> | |||||
<n-gi><span>{{ item.note ? item.note : '-' }}</span></n-gi> | |||||
<n-gi><span>问题图片</span></n-gi> | |||||
<n-gi><n-image :src="item.fileMarkerUrl" /></n-gi> | |||||
</n-grid> | |||||
</div> | |||||
<!-- </n-image-group> --> | |||||
</div> | |||||
<div class="report__operate"> | |||||
<n-button type="primary">下载</n-button> | |||||
</div> | |||||
</div> | |||||
</n-drawer-content> | |||||
</n-drawer> | |||||
</template> | |||||
<script> | |||||
import { getReportDetail } from '@/api/report/index.js' | |||||
import { defineComponent, reactive, toRefs, computed, watch } from 'vue' | |||||
export default defineComponent({ | |||||
name: 'LiveDrawer', | |||||
props: { | |||||
/* 可见 */ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
/* 选中的数据 */ | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
reportDetail: {}, | |||||
weatherList: [] | |||||
// problemsList: { | |||||
// 'type_1': 0, | |||||
// 'type_2': 0, | |||||
// 'type_3': 0, | |||||
// 'type_4': 0 | |||||
// } | |||||
}) | |||||
/* 获取抽屉的信息 */ | |||||
const getDrawerOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
width: '100%', | |||||
placement: 'right' | |||||
} | |||||
}) | |||||
/* 关闭抽屉 */ | |||||
function handleDrawerColse() { | |||||
emit('update:visible', false) | |||||
} | |||||
watch(() => props.data, | |||||
(val) => { | |||||
if (val.id) { | |||||
getReportDetail(val.id) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
data.reportDetail = res.data | |||||
const parm = res.data.airWeather.wth?.parm || [] | |||||
data.weatherList = parm.length !== 0 ? [ | |||||
{ label: '天气', value: '' }, | |||||
{ label: '气温', value: parm.tmp / 10 + '℃' }, | |||||
{ label: '湿度', value: parm.hum / 10 + 'RH' }, | |||||
{ label: '风度', value: parm.wspd + 'm/s' }, | |||||
{ label: '风向', value: parm.wdir } | |||||
] : [] | |||||
// data.problemsList = { | |||||
// 'type_1': 0, | |||||
// 'type_2': 0, | |||||
// 'type_3': 0, | |||||
// 'type_4': 0 | |||||
// } | |||||
// data.reportDetail.questionReportList.forEach((item, index) => { | |||||
// if (index === 0)item.fileMarkerUrl = 'https://image.t-aaron.com/XJRW20220720165837/2022-07-20-17-07-34_frame-6563-6720_type-%E6%B0%B4%E7%94%9F%E6%A4%8D%E8%A2%AB_o3MORSWHXz5pQ8F9_s-live-XJRW20220720165837-a0ec218ddd884ffcadd4f3c8fc27d825_AI.jpg' | |||||
// if (index === 1)item.fileMarkerUrl = 'https://image.t-aaron.com/XJRW20220720165837/2022-07-20-17-04-30_frame-1802-1920_type-%E6%B0%B4%E7%94%9F%E6%A4%8D%E8%A2%AB_b0N6GXoM178nUxhC_s-live-XJRW20220720165837-a0ec218ddd884ffcadd4f3c8fc27d825_AI.jpg' | |||||
// }) | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
return { | |||||
...toRefs(data), | |||||
getDrawerOptions, | |||||
handleDrawerColse | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.report__container{ | |||||
width: 900px; | |||||
margin: 0 auto 40px auto; | |||||
.report__item{ | |||||
margin-bottom: 40px; | |||||
.report__item--title{ | |||||
font-size: 18px; | |||||
color: #333333; | |||||
line-height: 44px; | |||||
} | |||||
.n-grid{ | |||||
border-top: 1px solid rgba(216, 216, 216, 1); | |||||
border-left: 1px solid rgba(216, 216, 216, 1); | |||||
>div{ | |||||
position: relative; | |||||
text-align: center; | |||||
font-size: 14px; | |||||
color: #333333; | |||||
line-height: 20px; | |||||
padding: 6px 12px; | |||||
word-wrap: break-word; | |||||
word-break: normal; | |||||
border-right: 1px solid rgba(216, 216, 216, 1); | |||||
border-bottom: 1px solid rgba(216, 216, 216, 1); | |||||
&:nth-child(2n-1){ | |||||
span{ | |||||
position: absolute; | |||||
left: 50%; | |||||
top: 50%; | |||||
transform: translate(-50%,-50%); | |||||
} | |||||
background: rgba(228, 231, 237, 1); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.report__operate{ | |||||
text-align: center; | |||||
} | |||||
} | |||||
::v-deep(.n-image){ | |||||
width: 100%; | |||||
img{ | |||||
width: 100%; | |||||
} | |||||
} | |||||
</style> |
<template> | <template> | ||||
<div> | <div> | ||||
全部报告 | |||||
<n-card> | |||||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||||
<DataTable | |||||
ref="tableRef" | |||||
:columns="columns" | |||||
:row-key="(row) => row.id" | |||||
:request="loadDataTable" | |||||
size="large" | |||||
/> | |||||
</n-card> | |||||
</div> | </div> | ||||
<ReportDrawer v-model:visible="detailDrawer" :data="rowData" /> | |||||
</template> | </template> | ||||
<script> | <script> | ||||
import table from './tools/table.js' | |||||
import search from './tools/search.js' | |||||
import HeadSearch from '@/components/Search/index.vue' | |||||
import DataTable from '@/components/DataTable/index.vue' | |||||
import ReportDrawer from './components/ReportDrawer.vue' | |||||
import { reactive, unref, toRefs } from 'vue' | |||||
import { getReportList } from '@/api/report/index.js' | |||||
export default { | export default { | ||||
name: 'AllReport', | |||||
name: 'TaskAll', | |||||
components: { HeadSearch, DataTable, ReportDrawer }, | |||||
setup() { | setup() { | ||||
const data = reactive({ | |||||
search, | |||||
...toRefs(table) | |||||
}) | |||||
/** | |||||
* @description: 加载表格数据 | |||||
* @param {*} res | |||||
* @return {*} | |||||
*/ | |||||
const loadDataTable = async(res) => { | |||||
const _params = { | |||||
...unref(data.searchParams), | |||||
...res | |||||
} | |||||
return await getReportList(_params) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
loadDataTable | |||||
} | |||||
} | } | ||||
} | } | ||||
import { reactive } from 'vue' | |||||
import { TASK_TYPE } from '@/utils/dictionary.js' | |||||
const data = reactive([ | |||||
{ | |||||
label: '任务编号', | |||||
key: 'code', | |||||
props: { | |||||
placeholder: '请输入任务编号' | |||||
} | |||||
}, | |||||
{ | |||||
label: '任务名称', | |||||
key: 'name', | |||||
props: { | |||||
placeholder: '请输入任务名称' | |||||
} | |||||
}, | |||||
{ | |||||
label: '巡检机场', | |||||
key: 'airportId', | |||||
type: 'select', | |||||
props: { | |||||
placeholder: '请选择巡检机场', | |||||
options: [], | |||||
onUpdateValue: () => { | |||||
const index = data.findIndex((item) => item.key === 'route') | |||||
data[index].value = '' | |||||
} | |||||
} | |||||
}, | |||||
{ | |||||
label: '任务类型', | |||||
key: 'type', | |||||
type: 'select', | |||||
value: 0, | |||||
props: { | |||||
placeholder: '请选择任务状态', | |||||
options: TASK_TYPE | |||||
} | |||||
} | |||||
]) | |||||
export default data | |||||
import { TASK_TYPE } from '@/utils/dictionary.js' | |||||
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 } | |||||
tableRef.value.reFetch({ searchParams }) | |||||
} | |||||
/** | |||||
* @description: 获取数据及操作 | |||||
* @param {*} row 单行数据 | |||||
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | |||||
* @return {*} | |||||
*/ | |||||
function getRowData(row) { | |||||
data.rowData = row | |||||
data.detailDrawer = true | |||||
} | |||||
const data = reactive({ | |||||
tableRef, | |||||
searchParams, | |||||
rowData: {}, | |||||
detailDrawer: false, | |||||
handleSearch, | |||||
columns: [ | |||||
{ | |||||
title: '序号', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '报告编号', | |||||
key: 'reportNo', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '生成时间', | |||||
key: 'generateTime', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '任务名称', | |||||
key: 'missionName', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '巡检机场', | |||||
key: 'airportName', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '任务类型', | |||||
key: 'type', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.type, | |||||
filters: TASK_TYPE | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '巡检时间', | |||||
key: 'executionStartTime', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '查看', | |||||
align: 'center', | |||||
width: 150, | |||||
fixed: 'right', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '巡检报告', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: getRowData.bind(null, row) | |||||
}, | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
} | |||||
] | |||||
}) | |||||
export default data |
<template> | |||||
<div class="main_container"> | |||||
<div id="track" ref="map" /> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { reactive, toRefs, onMounted, ref } from 'vue' | |||||
import { Map, View } from 'ol' | |||||
import 'ol/ol.css' | |||||
import { Tile } from 'ol/layer' | |||||
import { XYZ } from 'ol/source' | |||||
import { transform } from 'ol/proj' | |||||
import * as control from 'ol/control' | |||||
export default { | |||||
name: 'PositionMsg', | |||||
props: { | |||||
data: { | |||||
type: Array, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: {}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
problemList: props.data, // 问题矢量点列表 | |||||
problemData: {}, // 问题点数据 | |||||
mapData: null, | |||||
mapView: null | |||||
}) | |||||
/** | |||||
* 初始化底图 | |||||
*/ | |||||
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.mapView = new View({ | |||||
maxZoom: 18, | |||||
zoom: 4, | |||||
center: transform([108.94043, 31.008173], 'EPSG:4326', 'EPSG:3857') | |||||
}) | |||||
data.mapData = new Map({ | |||||
layers: layers, | |||||
target: 'track', | |||||
view: data.mapView, | |||||
controls: control.defaults({ | |||||
attribution: false, | |||||
rotate: false, | |||||
zoom: false | |||||
}) | |||||
}) | |||||
data.mapData.render() | |||||
} | |||||
// function playTrack(map, view, id, hisTrackList) { | |||||
// let animating = false | |||||
// let distance = 0 | |||||
// let lastTime | |||||
// let trackInfo = null | |||||
// let vectorLayer | |||||
// let changeTrack | |||||
// const initTrack = (coordinate) => { | |||||
// const route = new LineString(coordinate) | |||||
// const routeFeature = new Feature({ | |||||
// type: 'route', | |||||
// geometry: route | |||||
// }) | |||||
// const startMarker = new Feature({ | |||||
// type: 'icon', | |||||
// geometry: new Point(route.getFirstCoordinate()) | |||||
// }) | |||||
// const endMarker = new Feature({ | |||||
// type: 'icon', | |||||
// geometry: new Point(route.getLastCoordinate()) | |||||
// }) | |||||
// const position = startMarker.getGeometry().clone() | |||||
// const geoMarker = new Feature({ | |||||
// type: 'geoMarker', | |||||
// geometry: position | |||||
// }) | |||||
// geoMarker.setProperties({ type: 'geoMarker' }, false) | |||||
// const styles = { | |||||
// route: new Style({ | |||||
// stroke: new Stroke({ | |||||
// width: 3, | |||||
// color: 'red' | |||||
// }) | |||||
// }), | |||||
// icon: new Style({ | |||||
// image: new Icon({ | |||||
// offset: [0, 0], | |||||
// offsetOrigin: 'bottom-right', | |||||
// src: require('@/assets/img/point.png'), | |||||
// scale: [0.9, 0.9] | |||||
// }) | |||||
// }), | |||||
// geoMarker: new Style({ | |||||
// image: new Icon({ | |||||
// offset: [0, 0], | |||||
// offsetOrigin: 'bottom-right', | |||||
// src: require('@/assets/img/point.png'), | |||||
// scale: [0.5, 0.5] | |||||
// }) | |||||
// }) | |||||
// } | |||||
// if (this.vectorLayer) { | |||||
// this.vectorLayer.setSource( | |||||
// new VectorSource({ | |||||
// features: [geoMarker, routeFeature] | |||||
// }) | |||||
// ) | |||||
// vectorLayer = this.vectorLayer | |||||
// } else { | |||||
// vectorLayer = new VectorLayer({ | |||||
// source: new VectorSource({ | |||||
// features: [geoMarker, routeFeature] | |||||
// }), | |||||
// style: function(feature) { | |||||
// return styles[feature.get('type')] | |||||
// } | |||||
// }) | |||||
// } | |||||
// this.vectorLayer = vectorLayer | |||||
// map.addLayer(vectorLayer) | |||||
// // vectorLayer.on('postrender',changeTrack) | |||||
// vectorLayer.on('change', changeTrack) | |||||
// view.fit(route, { padding: [50, 50, 50, 50] }) | |||||
// this.routeLayer = vectorLayer | |||||
// // startAnimation({vectorLayer,geoMarker}) | |||||
// return { | |||||
// vectorLayer, | |||||
// geoMarker, | |||||
// route, | |||||
// styles, | |||||
// position | |||||
// } | |||||
// } | |||||
// if (hisTrackList.length > 1) { | |||||
// trackInfo = initTrack(hisTrackList) | |||||
// } | |||||
// changeTrack = (event) => { | |||||
// try { | |||||
// // trackInfo.route.appendCoordinate(coordinate); | |||||
// const vectorContext = getVectorContext(event) | |||||
// vectorContext.setStyle(trackInfo.styles.geoMarker) | |||||
// VectorContext.drawGeometry(trackInfo.position) | |||||
// vectorContext.drawGeometry(trackInfo.route) | |||||
// // tell OpenLayers to continue the postrender animation | |||||
// map.render() | |||||
// } catch {} | |||||
// } | |||||
// this.socket = setInterval(() => { | |||||
// this.$http.get(`/inspection/getFlightDataByInspectionId?inspectionId=${id}`) | |||||
// .then((res) => { | |||||
// const coordinate = fromLonLat([res.data?.data?.lng, res.data?.data?.lat]) | |||||
// const unUseableCoordinate = !coordinate.every((item) => !isNaN(item)) | |||||
// if (unUseableCoordinate) return | |||||
// // 赋值动态无人机坐标 | |||||
// if (this.btnList[0].flag) { | |||||
// if (coordinate.length) { | |||||
// this.trajectoryList.lng = coordinate[0] | |||||
// this.trajectoryList.lat = coordinate[1] | |||||
// } | |||||
// } | |||||
// this.trackList.push(coordinate) | |||||
// if (this.trackList.length > 1 && !trackInfo) { | |||||
// this.initTrack(this.trackList) | |||||
// } | |||||
// if (trackInfo) { | |||||
// trackInfo.route.appendCoordinate(coordinate) | |||||
// trackInfo.vectorLayer.getSource().changed() | |||||
// trackInfo.position.setCoordinates(coordinate) | |||||
// } | |||||
// }) | |||||
// }, 2000) | |||||
// const test = (event) => { | |||||
// const coordinate = toRaw(this.trackList).shift() | |||||
// if (!coordinate) return | |||||
// trackInfo.route.appendCoordinate(coordinate) | |||||
// const vectorContext = getVectorContext(event) | |||||
// vectorContext.setStyle(trackInfo.styles.geoMarker) | |||||
// vectorContext.drawGeometry(trackInfo.route) | |||||
// // tell OpenLayers to continue the postrender animation | |||||
// map.render() | |||||
// // if(!animating){ | |||||
// // // startAnimation(trackInfo); | |||||
// // } | |||||
// } | |||||
// function moveFeature(event) { | |||||
// const speed = Number(50) | |||||
// const time = event.frameState.time | |||||
// const elapsedTime = time - lastTime | |||||
// distance = (distance + (speed * elapsedTime) / 1e6) % 2 | |||||
// if (distance > 1) { | |||||
// stopAnimation(trackInfo) | |||||
// } | |||||
// lastTime = time | |||||
// const currentCoordinate = trackInfo.route.getCoordinateAt( | |||||
// distance > 1 ? 2 - distance : distance | |||||
// ) | |||||
// trackInfo.position.setCoordinates(currentCoordinate) | |||||
// const vectorContext = getVectorContext(event) | |||||
// vectorContext.setStyle(trackInfo.styles.geoMarker) | |||||
// vectorContext.drawGeometry(trackInfo.position) | |||||
// // tell OpenLayers to continue the postrender animation | |||||
// map.render() | |||||
// } | |||||
// function stopAnimation(trackInfo) { | |||||
// const { vectorLayer, geoMarker } = trackInfo | |||||
// animating = false | |||||
// // Keep marker at current animation position | |||||
// geoMarker.setGeometry(trackInfo.position) | |||||
// vectorLayer.un('postrender', moveFeature) | |||||
// } | |||||
// function startAnimation(trackInfo) { | |||||
// const { vectorLayer, geoMarker } = trackInfo | |||||
// animating = true | |||||
// lastTime = Date.now() | |||||
// vectorLayer.on('postrender', moveFeature) | |||||
// // hide geoMarker and trigger map render through change event | |||||
// geoMarker.setGeometry(null) | |||||
// } | |||||
// } | |||||
onMounted(() => { | |||||
initMap() | |||||
}) | |||||
return { | |||||
...toRefs(data) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped> | |||||
.main_container { | |||||
width: 100%; | |||||
height: 100%; | |||||
position: relative; | |||||
overflow: hidden; | |||||
} | |||||
#track { | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
</style> |
<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 /> | |||||
</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 { h, defineComponent, computed, reactive, toRefs } from 'vue' | ||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'LiveDrawer', | name: 'LiveDrawer', | ||||
components: { BaseMap }, | |||||
props: { | props: { | ||||
/* 可见 */ | /* 可见 */ | ||||
visible: { | visible: { |
<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="疑似问题核实"> | ||||
<QuestionPage /> | |||||
<QuestionPage :data="getMission" /> | |||||
</n-drawer-content> | </n-drawer-content> | ||||
</n-drawer> | </n-drawer> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import QuestionPage from '@/views/task-manage/question/index.vue' | import QuestionPage from '@/views/task-manage/question/index.vue' | ||||
import { defineComponent, computed, reactive, toRefs } from 'vue' | |||||
import { defineComponent, computed } from 'vue' | |||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'LiveDrawer', | name: 'LiveDrawer', | ||||
'update:visible': null | 'update:visible': null | ||||
}, | }, | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const data = reactive({ | |||||
}) | |||||
/* 获取抽屉的信息 */ | /* 获取抽屉的信息 */ | ||||
const getDrawerOptions = computed(() => { | const getDrawerOptions = computed(() => { | ||||
return { | return { | ||||
placement: 'right' | placement: 'right' | ||||
} | } | ||||
}) | }) | ||||
/* 获取选中的数据 */ | |||||
const getMission = computed(() => { | |||||
return props.data | |||||
}) | |||||
function handleDrawerColse() { | function handleDrawerColse() { | ||||
emit('update:visible', false) | emit('update:visible', false) | ||||
} | } | ||||
return { | return { | ||||
...toRefs(data), | |||||
getDrawerOptions, | getDrawerOptions, | ||||
getMission, | |||||
handleDrawerColse | handleDrawerColse | ||||
} | } | ||||
} | } |
<DataTable | <DataTable | ||||
ref="tableRef" | ref="tableRef" | ||||
:columns="columns" | :columns="columns" | ||||
:request="loadDataTable" | |||||
:row-key="(row) => row.id" | :row-key="(row) => row.id" | ||||
:request="loadDataTable" | |||||
size="large" | size="large" | ||||
> | > | ||||
<template #tableTitle> | <template #tableTitle> | ||||
setup() { | setup() { | ||||
const data = reactive({ | const data = reactive({ | ||||
search, | search, | ||||
...toRefs(table), | |||||
data: [{}] | |||||
...toRefs(table) | |||||
}) | }) | ||||
/** | /** |
columns: [ | columns: [ | ||||
{ | { | ||||
title: '任务标号', | |||||
title: '序号', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '任务编号', | |||||
key: 'code', | key: 'code', | ||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
type: 'popconfirm', | type: 'popconfirm', | ||||
tip: '是否删除该数据?', | tip: '是否删除该数据?', | ||||
props: { | props: { | ||||
onClick: handleRowDelete.bind(null, row) | |||||
onPositiveClick: handleRowDelete.bind(null, row) | |||||
}, | }, | ||||
ButtonProps: { | ButtonProps: { | ||||
text: true, | text: true, | ||||
type: 'popconfirm', | type: 'popconfirm', | ||||
tip: '是否立即开始执行任务?', | tip: '是否立即开始执行任务?', | ||||
props: { | props: { | ||||
onClick: handleImplement.bind(null, row) | |||||
onPositiveClick: handleImplement.bind(null, row) | |||||
}, | }, | ||||
ButtonProps: { | ButtonProps: { | ||||
text: true, | text: true, |
</n-icon> | </n-icon> | ||||
<div class="carousel__container"> | <div class="carousel__container"> | ||||
<label>问题描述</label> | <label>问题描述</label> | ||||
<n-carousel ref="carouselRef" :show-dots="false"> | |||||
<n-carousel ref="carouselRef" :default-index="selectIndex" :show-dots="false"> | |||||
<img | <img | ||||
v-for="item in getCarouselInfo" | v-for="item in getCarouselInfo" | ||||
:key="item.id" | :key="item.id" | ||||
<script> | <script> | ||||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | import { QUESTION_TYPE } from '@/utils/dictionary.js' | ||||
import { changeQuestionStatus } from '@/api/task/index.js' | |||||
import { LeftOutlined, RightOutlined } from '@vicons/antd' | import { LeftOutlined, RightOutlined } from '@vicons/antd' | ||||
import Modal from '@/components/Modal/index.vue' | import Modal from '@/components/Modal/index.vue' | ||||
import { defineComponent, computed, ref, reactive, toRefs } from 'vue' | import { defineComponent, computed, ref, reactive, toRefs } from 'vue' | ||||
data: { | data: { | ||||
type: Array, | type: Array, | ||||
default: () => null | default: () => null | ||||
}, | |||||
selectRow: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | } | ||||
}, | }, | ||||
emits: { | emits: { | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const formRef = ref() | const formRef = ref() | ||||
const data = reactive({ | const data = reactive({ | ||||
selectRow: props.data[0], | |||||
selectType: props.data[0].type, | |||||
selectRow: props.selectRow, | |||||
selectIndex: props.data.findIndex((item) => { return item.id === props.selectRow.id }), | |||||
selectType: props.selectRow.type, | |||||
QUESTION_TYPE | QUESTION_TYPE | ||||
}) | }) | ||||
/* 获取弹窗的属性 */ | /* 获取弹窗的属性 */ | ||||
show: props.visible, | show: props.visible, | ||||
title: '问题确认', | title: '问题确认', | ||||
width: 700, | width: 700, | ||||
negativeText: '忽略', | |||||
positiveText: '确认' | |||||
negativeText: data.selectRow.status !== 2 ? '忽略' : '', | |||||
positiveText: data.selectRow.status !== 1 ? '确认' : '' | |||||
} | } | ||||
}) | }) | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
const handleConfirm = () => { | const handleConfirm = () => { | ||||
emit('update-data') | |||||
const params = { | |||||
id: [data.selectRow.id], | |||||
type: data.selectType, | |||||
status: 1 | |||||
} | |||||
changeQuestionStatus(params) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
data.selectRow.status = 1 | |||||
emit('update-data') | |||||
} | |||||
}) | |||||
} | } | ||||
const handleIgnore = () => { | const handleIgnore = () => { | ||||
const params = { | |||||
id: [data.selectRow.id], | |||||
type: data.selectType, | |||||
status: 2 | |||||
} | |||||
changeQuestionStatus(params) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
data.selectRow.status = 2 | |||||
emit('update-data') | |||||
} | |||||
}) | |||||
} | } | ||||
/* 关闭弹窗 */ | /* 关闭弹窗 */ |
ref="tableRef" | ref="tableRef" | ||||
:columns="columns" | :columns="columns" | ||||
:row-key="(row) => row.id" | :row-key="(row) => row.id" | ||||
:data="data" | |||||
size="large" | |||||
scroll-x="1200" | |||||
:request="loadDataTable" | |||||
:checked-row-keys="selectRowKeys" | |||||
@fetch-success="getTableData" | @fetch-success="getTableData" | ||||
@update:checked-row-keys="handleRowsCheck" | @update:checked-row-keys="handleRowsCheck" | ||||
> | > | ||||
<template #tableTitle> | <template #tableTitle> | ||||
<n-button @click="handleIgnoreBatch">忽略</n-button> | |||||
<n-button style="margin-right:20px" @click="handleIgnoreBatch">忽略</n-button> | |||||
<n-button type="primary" @click="handleConfirmBatch"> | <n-button type="primary" @click="handleConfirmBatch"> | ||||
确认 | 确认 | ||||
</n-button> | </n-button> | ||||
</template> | |||||
<template #toolbar> | |||||
<n-button @click="handleReported"> | |||||
{{ isReported ? '修改并生成报告': '提交并生成报告' }} | |||||
</n-button> | |||||
</template> | </template> | ||||
</DataTable> | </DataTable> | ||||
<ConfirmModal v-if="confirmModal" v-model:visible="confirmModal" :data="pageData" @update-data="tableReload" /> | |||||
<ConfirmModal v-if="confirmModal" v-model:visible="confirmModal" :data="pageData" :select-row="rowData" @update-data="handleSearch" /> | |||||
<!-- 图片位置 --> | <!-- 图片位置 --> | ||||
<position-drawer v-model:visible="positionDrawer" :data="rowData" /> | <position-drawer v-model:visible="positionDrawer" :data="rowData" /> | ||||
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 { ref, reactive, toRefs } from 'vue' | |||||
import { getQuestionList, generateReport } from '@/api/task/index.js' | |||||
import { unref, reactive, toRefs } from 'vue' | |||||
export default { | export default { | ||||
name: 'QuestionPage', | name: 'QuestionPage', | ||||
components: { HeadSearch, DataTable, ConfirmModal, PositionDrawer }, | components: { HeadSearch, DataTable, ConfirmModal, PositionDrawer }, | ||||
setup() { | |||||
props: { | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | const data = reactive({ | ||||
search, | search, | ||||
...toRefs(table), | ...toRefs(table), | ||||
data: [ | |||||
{ id: 1, image: 'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel1.jpeg', position: '软件园', type: 1 }, | |||||
{ id: 2, image: 'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel2.jpeg', position: '东吉大道一号', type: 2 } | |||||
], | |||||
pageData: [] | |||||
pageData: [], | |||||
isReported: props.data?.isReported || false | |||||
}) | }) | ||||
/** | |||||
* @description: 加载表格数据 | |||||
* @param {*} res | |||||
* @return {*} | |||||
*/ | |||||
const loadDataTable = async(res) => { | |||||
const _params = { | |||||
...unref(data.searchParams), | |||||
...res | |||||
} | |||||
if (_params.status === 'all') _params.status = '' | |||||
return await getQuestionList(_params) | |||||
} | |||||
/** | /** | ||||
* @description: | * @description: | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
function getTableData(list) { | function getTableData(list) { | ||||
data.pageData = list | |||||
data.pageData = list.items | |||||
} | } | ||||
/** | /** | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
function handleRowsCheck(rowKeys) { | function handleRowsCheck(rowKeys) { | ||||
console.log(rowKeys) | |||||
data.selectRowKeys = rowKeys | |||||
} | } | ||||
/** | |||||
* @description: 批量忽略 | |||||
* @return {*} | |||||
*/ | |||||
function handleIgnoreBatch() { | function handleIgnoreBatch() { | ||||
if (data.selectRowKeys.length === 0) { | |||||
$message.error('请至少选择一条数据') | |||||
return | |||||
} | |||||
data.handleRowIgnore(data.selectRowKeys) | |||||
} | } | ||||
/** | |||||
* @description: 批量确认 | |||||
* @return {*} | |||||
*/ | |||||
function handleConfirmBatch() { | function handleConfirmBatch() { | ||||
if (data.selectRowKeys.length === 0) { | |||||
$message.error('请至少选择一条数据') | |||||
return | |||||
} | |||||
data.handleRowConfirm(data.selectRowKeys) | |||||
} | } | ||||
const tableRef = ref() | |||||
/* 刷新表格数据 */ | |||||
function tableReload(res) { | |||||
const _params = { | |||||
...res | |||||
} | |||||
tableRef.value.reFetch(_params) | |||||
/** | |||||
* @description: 生成报告 | |||||
* @return {*} | |||||
*/ | |||||
function handleReported() { | |||||
generateReport(props.data.id) | |||||
} | } | ||||
return { | return { | ||||
...toRefs(data), | ...toRefs(data), | ||||
tableRef, | |||||
loadDataTable, | |||||
getTableData, | getTableData, | ||||
handleRowsCheck, | handleRowsCheck, | ||||
handleIgnoreBatch, | handleIgnoreBatch, | ||||
handleConfirmBatch, | handleConfirmBatch, | ||||
tableReload | |||||
handleReported | |||||
} | } | ||||
} | } | ||||
} | } |
// import TableTags from '@/components/DataTable/tools/Tags.vue' | |||||
import { QUESTION_STATUS } from '@/utils/dictionary.js' | |||||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||||
import TableImage from '@/components/DataTable/tools/Image.vue' | import TableImage from '@/components/DataTable/tools/Image.vue' | ||||
import TableAction from '@/components/DataTable/tools/Action.vue' | import TableAction from '@/components/DataTable/tools/Action.vue' | ||||
import { h, reactive } from 'vue' | |||||
import { changeQuestionStatus } from '@/api/task/index.js' | |||||
import { h, ref, reactive } from 'vue' | |||||
/* 注册table */ | |||||
const tableRef = ref() | |||||
const searchParams = ref() | |||||
function handleSearch(params) { | |||||
searchParams.value = { ...params } | |||||
tableRef.value.reFetch({ searchParams }) | |||||
} | |||||
/* 问题忽略 */ | /* 问题忽略 */ | ||||
function handleRowIgnore(row) { | |||||
data.rowData = row | |||||
console.log('问题忽略') | |||||
function handleRowIgnore(ids, type = '') { | |||||
const params = { | |||||
id: ids, | |||||
type: type, | |||||
status: 2 | |||||
} | |||||
changeQuestionStatus(params) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
data.selectRowKeys = [] | |||||
handleSearch() | |||||
} | |||||
}) | |||||
} | } | ||||
/* 问题确认 */ | /* 问题确认 */ | ||||
function handleRowConfirm(row) { | |||||
data.rowData = row | |||||
console.log('问题确认') | |||||
function handleRowConfirm(ids, type = '') { | |||||
const params = { | |||||
id: ids, | |||||
type: type, | |||||
status: 1 | |||||
} | |||||
changeQuestionStatus(params) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
data.selectRowKeys = [] | |||||
handleSearch() | |||||
} | |||||
}) | |||||
} | } | ||||
/* 位置 */ | /* 位置 */ | ||||
data.positionDrawer = true | data.positionDrawer = true | ||||
} | } | ||||
function handleImgPreview() { | |||||
function handleImgPreview(row) { | |||||
data.rowData = row | |||||
data.confirmModal = true | data.confirmModal = true | ||||
} | } | ||||
const data = reactive({ | const data = reactive({ | ||||
tableRef, | |||||
searchParams, | |||||
rowData: {}, | rowData: {}, | ||||
selectRowKeys: [], | |||||
confirmModal: false, | confirmModal: false, | ||||
positionDrawer: false, | positionDrawer: false, | ||||
handleSearch, | |||||
handleRowIgnore, | |||||
handleRowConfirm, | |||||
columns: [ | columns: [ | ||||
{ | { | ||||
type: 'selection' | type: 'selection' | ||||
}, | }, | ||||
{ | { | ||||
title: '问题类型', | title: '问题类型', | ||||
key: 'name', | |||||
key: 'questionName', | |||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
{ | { | ||||
title: '问题图片', | title: '问题图片', | ||||
key: 'image', | |||||
key: 'fileMarkerUrl', | |||||
align: 'center', | align: 'center', | ||||
render(row) { | render(row) { | ||||
return h(TableImage, { | return h(TableImage, { | ||||
images: { | images: { | ||||
width: 36, | width: 36, | ||||
height: 36, | height: 36, | ||||
src: row.image, | |||||
src: row.fileMarkerUrl, | |||||
previewDisabled: true, | previewDisabled: true, | ||||
onClick: handleImgPreview.bind(null, row) | onClick: handleImgPreview.bind(null, row) | ||||
} | } | ||||
{ | { | ||||
title: '经纬度', | title: '经纬度', | ||||
key: 'name', | key: 'name', | ||||
align: 'center' | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: [{ name: row.lng }, { name: row.lat }] | |||||
}) | |||||
} | |||||
}, | }, | ||||
{ | { | ||||
title: '位置', | title: '位置', | ||||
text: true, | text: true, | ||||
onClick: handlePositionDrawer.bind(null, row) | onClick: handlePositionDrawer.bind(null, row) | ||||
}, | }, | ||||
auth: 'basic_list', | |||||
show: row.status !== 1 | |||||
auth: 'basic_list' | |||||
} | } | ||||
], | ], | ||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
{ | { | ||||
title: '备注', | title: '备注', | ||||
key: 'name', | |||||
key: 'note', | |||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
{ | { | ||||
title: '状态', | title: '状态', | ||||
key: 'name', | |||||
align: 'center' | |||||
key: 'status', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.status, | |||||
filters: QUESTION_STATUS | |||||
}) | |||||
} | |||||
}, | }, | ||||
{ | { | ||||
type: 'popconfirm', | type: 'popconfirm', | ||||
tip: '是否忽略该数据?', | tip: '是否忽略该数据?', | ||||
props: { | props: { | ||||
onClick: handleRowIgnore.bind(null, row) | |||||
onPositiveClick: handleRowIgnore.bind(null, [row.id], row.type) | |||||
}, | }, | ||||
ButtonProps: { | ButtonProps: { | ||||
text: true, | text: true, | ||||
type: 'primary' | type: 'primary' | ||||
}, | }, | ||||
auth: 'basic_list' | |||||
auth: 'basic_list', | |||||
hidden: row.status === 2 | |||||
}, | }, | ||||
{ | { | ||||
label: '确认', | label: '确认', | ||||
type: 'popconfirm', | type: 'popconfirm', | ||||
tip: '是否确认该数据?', | tip: '是否确认该数据?', | ||||
props: { | props: { | ||||
onClick: handleRowConfirm.bind(null, row) | |||||
onPositiveClick: handleRowConfirm.bind(null, [row.id], row.type) | |||||
}, | }, | ||||
ButtonProps: { | ButtonProps: { | ||||
text: true, | text: true, | ||||
type: 'primary' | type: 'primary' | ||||
}, | }, | ||||
auth: 'basic_list' | |||||
auth: 'basic_list', | |||||
hidden: row.status === 1 | |||||
} | } | ||||
], | ], | ||||
align: 'center' | align: 'center' |