You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

277 lines
7.2 KiB

<template>
<div>
<el-dialog
:title="title"
:visible.sync="dialogVisible"
width="500px"
:append-to-body="true"
:modal-append-to-body="true"
:close-on-click-modal="false"
:close-on-press-escape="true"
:destroy-on-close="true"
:before-close="handleCancel"
custom-class="locate-dialog"
:style="{ marginTop: '15vh' }"
>
<el-form ref="form" :model="formData" label-width="80px">
<el-form-item label="方案:">
<el-select
v-model="formData.scenarioId"
placeholder="请选择方案"
clearable
style="width: 100%"
@change="handleScenarioChange"
>
<el-option
v-for="item in scenarioList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="航线:">
<el-select
v-model="formData.routeId"
placeholder="请选择航线"
clearable
style="width: 100%"
:disabled="!formData.scenarioId"
@change="handleRouteChange"
>
<el-option
v-for="item in routeList"
:key="item.id"
:label="item.callSign"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="航点:">
<el-select
v-model="formData.waypointId"
placeholder="请选择航点"
clearable
style="width: 100%"
:disabled="!formData.routeId"
@change="handleWaypointChange"
>
<el-option
v-for="item in waypointList"
:key="item.id"
:label="`${item.name} (${degreesToDMS(item.lng)}, ${degreesToDMS(item.lat)})`"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="经度:">
<el-input
v-model="formData.lng"
placeholder="例如 116°23'48.64""
clearable
/>
</el-form-item>
<el-form-item label="纬度:">
<el-input
v-model="formData.lat"
placeholder="例如 39°54'33.48""
clearable
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listScenario } from '@/api/system/scenario'
import { listRoutes } from '@/api/system/routes'
import { listWaypoints } from '@/api/system/waypoints'
export default {
name: 'LocateDialog',
props: {
title: {
type: String,
default: '定位'
},
visible: {
type: Boolean,
default: false
}
},
data() {
return {
dialogVisible: false,
formData: {
scenarioId: null,
routeId: null,
waypointId: null,
lng: '116°23\'48.64"',
lat: '39°54\'33.48"'
},
scenarioList: [],
routeList: [],
waypointList: []
}
},
watch: {
visible: {
handler(newVal) {
this.dialogVisible = newVal
},
immediate: true
},
dialogVisible(newVal) {
if (newVal) {
this.resetForm()
this.loadScenarios()
}
this.$emit('update:visible', newVal)
}
},
methods: {
degreesToDMS(decimalDegrees) {
const degrees = Math.floor(decimalDegrees)
const minutesDecimal = (decimalDegrees - degrees) * 60
const minutes = Math.floor(minutesDecimal)
const seconds = ((minutesDecimal - minutes) * 60).toFixed(2)
return `${degrees}°${minutes}'${seconds}"`
},
dmsToDegrees(dms) {
const match = dms.match(/^(-?\d+)°(\d+)'([\d.]+)"$/)
if (!match) return null
const degrees = parseFloat(match[1])
const minutes = parseFloat(match[2])
const seconds = parseFloat(match[3])
const sign = degrees < 0 ? -1 : 1
return sign * (Math.abs(degrees) + minutes / 60 + seconds / 3600)
},
resetForm() {
this.formData = {
scenarioId: null,
routeId: null,
waypointId: null,
lng: '116°23\'48.64"',
lat: '39°54\'33.48"'
}
this.routeList = []
this.waypointList = []
},
async loadScenarios() {
try {
const res = await listScenario({})
this.scenarioList = res.rows || []
} catch (error) {
console.error('加载方案列表失败:', error)
this.$message.error('加载方案列表失败')
}
},
async handleScenarioChange(value) {
this.formData.routeId = null
this.formData.waypointId = null
this.routeList = []
this.waypointList = []
if (value) {
try {
const res = await listRoutes({ scenarioId: value })
this.routeList = res.rows || []
} catch (error) {
console.error('加载航线列表失败:', error)
this.$message.error('加载航线列表失败')
}
}
},
async handleRouteChange(value) {
this.formData.waypointId = null
this.waypointList = []
if (value) {
try {
const res = await listWaypoints({ routeId: value })
this.waypointList = res.rows || []
} catch (error) {
console.error('加载航点列表失败:', error)
this.$message.error('加载航点列表失败')
}
}
},
handleWaypointChange(value) {
if (value) {
const waypoint = this.waypointList.find(w => w.id === value)
if (waypoint) {
this.formData.lng = this.degreesToDMS(waypoint.lng)
this.formData.lat = this.degreesToDMS(waypoint.lat)
}
}
},
handleCancel() {
this.$emit('update:visible', false)
this.$emit('cancel')
},
handleConfirm() {
const { lng, lat } = this.formData
if (!lng || !lat) {
this.$message.error('请输入有效的经度和纬度!')
return
}
const lngDegrees = this.dmsToDegrees(lng)
const latDegrees = this.dmsToDegrees(lat)
if (lngDegrees === null || latDegrees === null || isNaN(lngDegrees) || isNaN(latDegrees)) {
this.$message.error('请输入有效的度分秒格式!格式:116°23\'48.64"')
return
}
if (lngDegrees < -180 || lngDegrees > 180 || latDegrees < -90 || latDegrees > 90) {
this.$message.error('经纬度超出有效范围!')
return
}
this.$emit('confirm', {
lng: lngDegrees,
lat: latDegrees
})
this.$emit('update:visible', false)
}
}
}
</script>
<style scoped>
.dialog-footer {
text-align: right;
}
.locate-dialog {
z-index: 99999 !important;
}
.locate-dialog >>> .el-dialog {
margin-top: 15vh !important;
position: fixed !important;
top: 15vh !important;
}
.locate-dialog >>> .el-dialog__body {
padding: 20px;
}
</style>