| | |
| | | <div class="leftMap ztzf-cesium" id="mapContainer"></div> |
| | | <div class="rightInfo"> |
| | | <div v-if="readonly"> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <div>区域名称: {{ formData.areaName }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div>区域位置: {{ formatLocation(formData) }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div>区域面积: {{ formData.areaSize }}k㎡</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div>区域类型: {{ getDictLabel(formData.areaType, dictObj.areaType) }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div>触发条件: {{ formData.triggerCondition }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div>响应机制: {{ formData.responseMechanism }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div>管控级别: {{ getDictLabel(formData.controlLevel, dictObj.controlLevel) }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div>关联派出所: {{ formData.policeStationName }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div>可飞行时间段: {{ formatFlyDate(formData) }}</div> |
| | | </el-col> |
| | | </el-row> |
| | | <div>区域名称: {{ formData.areaName }}</div> |
| | | <div>区域位置: {{ formatLocation(formData) }}</div> |
| | | <div>区域面积: {{ formData.areaSize || '-' }}k㎡</div> |
| | | <div>区域类型: {{ getDictLabel(formData.areaType, dictObj.areaType) }}</div> |
| | | <div>触发条件: {{ formData.triggerCondition }}</div> |
| | | <div>响应机制: {{ formData.responseMechanism }}</div> |
| | | <div>管控级别: {{ getDictLabel(formData.controlLevel, dictObj.controlLevel) }}</div> |
| | | <div>关联派出所: {{ formData.policeStationName }}</div> |
| | | <div>可飞行时间段: {{ formatFlyDate(formData) }}</div> |
| | | <el-table ref="deviceTableRef" :data="deviceOptions" row-key="id"> |
| | | <el-table-column prop="deviceName" label="设备名称" /> |
| | | <el-table-column prop="deviceType" label="类型"> |
| | | <template v-slot="{ row }"> |
| | | {{ getDictLabel(row.deviceType, dictObj.deviceType) }} |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <el-form v-else ref="formRef" :model="formData" :rules="rules" :disabled="readonly" label-width="100px"> |
| | | <el-row> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="区域面积" prop="areaSize">{{ formData.areaSize }}k㎡</el-form-item> |
| | | <el-form-item label="区域面积" prop="areaSize">{{ formData.areaSize || '-' }}k㎡</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="区域类型" prop="areaType"> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="可飞行时段" prop="flyDateRange"> |
| | | <el-form-item label="可飞行时段" prop="flyDateStart"> |
| | | <el-date-picker |
| | | v-model="flyDateRange" |
| | | type="datetimerange" |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="关联设备" prop="deviceIds"> |
| | | <el-select v-model="deviceIdList" multiple collapse-tags placeholder="请选择" clearable> |
| | | <el-option v-for="item in deviceOptions" :key="item.id" :label="item.deviceName" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <div> |
| | | <div> |
| | | 关联设备 |
| | | <el-input v-model="searchName" placeholder="请输入" clearable></el-input> |
| | | </div> |
| | | <el-form-item prop="deviceIds" label-width="0"> |
| | | <el-table |
| | | ref="deviceTableRef" |
| | | :data="deviceOptions.filter(item => item.deviceName.includes(searchName))" |
| | | row-key="id" |
| | | @selection-change="handleDeviceSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="55" :reserve-selection="true" /> |
| | | <el-table-column prop="deviceName" label="设备名称" /> |
| | | <el-table-column prop="deviceType" label="类型"> |
| | | <template v-slot="{ row }"> |
| | | {{ getDictLabel(row.deviceType, dictObj.deviceType) }} |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-form-item> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | |
| | | <script setup> |
| | | import { computed, inject, nextTick, onMounted, ref, watch } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { |
| | | fwAreaDivideDetailApi, |
| | | fwAreaDivideSubmitApi, |
| | | } from './partitionApi' |
| | | import { fieldRules, getDictLabel } from '@ztzf/utils' |
| | | import { fwAreaDivideDetailApi, fwAreaDivideSubmitApi } from './partitionApi' |
| | | import { fieldRules, geomAnalysis, getDictLabel } from '@ztzf/utils' |
| | | import { PublicCesium } from '@/utils/cesium/publicCesium' |
| | | import { DrawPolygon } from '@/utils/cesium/DrawPolygon' |
| | | import { cartesian3Convert } from '@/utils/cesium/mapUtil' |
| | |
| | | const readonly = computed(() => dialogMode.value === 'view') |
| | | const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' }) |
| | | const flyDateRange = ref([]) // 飞行时间 |
| | | const deviceIdList = ref([]) // 关联设备ID |
| | | const deviceTableRef = ref(null) |
| | | const searchName = ref('') |
| | | const selectedDeviceRows = ref([]) |
| | | const policeStationOptions = ref([]) // 关联派出所 |
| | | const deviceOptions = ref([]) // 关联设备 |
| | | const dictObj = inject('dictObj') |
| | |
| | | let pointList = [] |
| | | |
| | | const rules = { |
| | | areaName: fieldRules(true, false, 50), |
| | | areaType: fieldRules(true, true), |
| | | controlLevel: fieldRules(true, true), |
| | | areaName: fieldRules(true, 50), |
| | | longitude: fieldRules(true), |
| | | areaType: fieldRules(true), |
| | | responseMechanism: fieldRules(true, 200), |
| | | triggerCondition: fieldRules(true, 200), |
| | | controlLevel: fieldRules(true), |
| | | flyDateStart: fieldRules(true), |
| | | policeStationId: fieldRules(true), |
| | | deviceIds: fieldRules(true), |
| | | } |
| | | |
| | | // 关闭弹框 |
| | |
| | | if (!isValid) return |
| | | submitting.value = true |
| | | try { |
| | | const [start, end] = flyDateRange.value ?? [] |
| | | formData.value.flyDateStart = start || '' |
| | | formData.value.flyDateEnd = end || '' |
| | | formData.value.deviceIds = deviceIdList.value.length ? deviceIdList.value.join(',') : '' |
| | | let str = [...pointList, pointList[0]].map(item => `${item.longitude} ${item.latitude}`).join(',') |
| | | formData.value.geom = `POLYGON((${str}))` |
| | | await fwAreaDivideSubmitApi(formData.value) |
| | |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => flyDateRange.value, |
| | | () => { |
| | | formData.value.flyDateStart = flyDateRange.value[0] || '' |
| | | formData.value.flyDateEnd = flyDateRange.value[1] || '' |
| | | } |
| | | ) |
| | | |
| | | // 加载详情 |
| | | async function loadDetail() { |
| | | if (!formData.value.id) return |
| | | const res = await fwAreaDivideDetailApi({ id: formData.value.id }) |
| | | formData.value = res?.data?.data ?? initForm() |
| | | flyDateRange.value = [formData.value.flyDateStart, formData.value.flyDateEnd].filter(Boolean) |
| | | deviceIdList.value = formData.value.deviceIds ? formData.value.deviceIds.split(',') : [] |
| | | } |
| | | |
| | | // 格式化区域位置 |
| | |
| | | drawPolygonExample.subscribe('getPolygonPositions', drawFinished) |
| | | } |
| | | |
| | | // 解析经纬度 |
| | | function getLonLat(str) { |
| | | if (!str) return [] |
| | | return str |
| | | .replace('POLYGON((', '') |
| | | .replace('))', '') |
| | | .split(',') |
| | | .map(pair => { |
| | | const [lon, lat] = pair.trim().split(' ').map(Number) |
| | | return [lon, lat] |
| | | }) |
| | | } |
| | | |
| | | // 编辑面 |
| | | function editPolygon() { |
| | | if (!formData.value?.geom) return |
| | | const grouped = getLonLat(formData.value.geom) |
| | | grouped.pop() |
| | | pointList = grouped.map(item => ({ longitude: item[0], latitude: item[1] })) |
| | | pointList = geomAnalysis(formData.value.geom) |
| | | drawPolygonExample?.destroy() |
| | | drawPolygonExample = new DrawPolygon(viewer) |
| | | let pointList1 = _.cloneDeep(pointList) |
| | | pointList1.pop() |
| | | drawPolygonExample.initPolygon( |
| | | viewer, |
| | | grouped.map(item => ({ lng: item[0], lat: item[1] })) |
| | | pointList.map(item => ({ lng: item.longitude, lat: item.latitude })) |
| | | ) |
| | | drawPolygonExample.subscribe('getPolygonPositions', drawFinished) |
| | | } |
| | |
| | | // 查看面 |
| | | function viewPolygon() { |
| | | if (!formData.value?.geom) return |
| | | const grouped = getLonLat(formData.value.geom) |
| | | grouped.pop() |
| | | pointList = grouped.map(item => ({ longitude: item[0], latitude: item[1] })) |
| | | const result = grouped.flat().flat() |
| | | pointList = geomAnalysis(formData.value.geom) |
| | | const result = pointList.map(item => [item.longitude, item.latitude]).flat() |
| | | const mian = viewer.entities?.add({ |
| | | customType: 'control_group', |
| | | position: Cesium.Cartesian3.fromDegrees(result[0], result[1]), |
| | |
| | | |
| | | // 获取设备列表 |
| | | async function getDeviceList() { |
| | | const res = await fwDeviceListApi({ isAreaSelect: 1 }) |
| | | if (deviceOptions.value.length) return |
| | | const res = await fwDeviceListApi({ isAreaSelect: 1, areaId: formData.value.id }) |
| | | deviceOptions.value = res?.data?.data ?? [] |
| | | if (dialogMode.value === 'view') { |
| | | deviceOptions.value = deviceOptions.value.filter(item => formData.value.deviceIds.includes(item.id)) |
| | | } |
| | | } |
| | | |
| | | // 关联设备变更 |
| | | function handleDeviceSelectionChange(rows) { |
| | | selectedDeviceRows.value = rows |
| | | const ids = rows.map(item => item.id) |
| | | formData.value.deviceIds = ids.join(',') |
| | | } |
| | | |
| | | // 同步选择状态 |
| | | function syncDeviceSelection() { |
| | | if (!deviceTableRef.value) return |
| | | deviceTableRef.value.clearSelection() |
| | | const rows = [] |
| | | const arr = formData.value.deviceIds.split(',') |
| | | deviceOptions.value.forEach(row => { |
| | | if (arr.includes(row.id)) { |
| | | deviceTableRef.value.toggleRowSelection(row, true) |
| | | rows.push(row) |
| | | } |
| | | }) |
| | | selectedDeviceRows.value = rows |
| | | } |
| | | |
| | | // 打开弹框 |
| | | async function open({ mode, row } = {}) { |
| | | dialogMode.value = mode || 'add' |
| | | formData.value = dialogMode.value === 'add' ? initForm() : row |
| | | selectedDeviceRows.value = [] |
| | | await nextTick() |
| | | initMap() |
| | | await getDeviceList() |
| | | if (dialogMode.value === 'add') { |
| | | addPolygon() |
| | | } else if (dialogMode.value === 'edit') { |
| | |
| | | await loadDetail() |
| | | viewPolygon() |
| | | } |
| | | await nextTick() |
| | | syncDeviceSelection() |
| | | } |
| | | |
| | | onMounted(() => { |