无人机管理后台前端(已迁走)
张含笑
2025-12-09 5808f76456ca0d40de5074f132b73a5a488e3e13
src/views/layerManagement/components/rightEdit.vue
@@ -1,11 +1,17 @@
<template>
  <div class="rightContainer">
    <div class="contenttitle">围栏信息</div>
  <div class="rightContainer"  >
    <div class="contenttitle">{{ layerParams.fenceType === 1 ? '识别区' : '禁飞区' }}信息</div>
    <div class="centerBox">
      <div class="itemRow">
        <div class="label">文件夹名称</div>
        <div>
          <el-select class="ztzf-layer-search" v-model="formData.area" placeholder="Select">
          <el-select
            :disabled="isDisabled"
            class="ztzf-layer-search"
            clearable
            v-model="formData.folder_id"
            placeholder="请选择"
          >
            <el-option
              v-for="item in options"
              :key="item.value"
@@ -16,50 +22,125 @@
        </div>
      </div>
      <div class="itemRow">
        <div class="label">围栏名称</div>
        <div class="label">{{ layerParams.fenceType === 1 ? '识别区' : '禁飞区' }}名称</div>
        <div>
          <el-input class="ztzf-input inputName" v-model="detailData.name" placeholder="围栏名称" />
          <el-input
            :disabled="isDisabled"
            class="ztzf-layer-input inputName"
            v-model="formData.name"
            placeholder="请输入"
          />
        </div>
      </div>
      <div class="itemRow" v-if="layerParams.fenceType === 2">
        <div class="label">禁飞区管控时间</div>
        <div>
          <!-- popper-class="ztzf-layer-date-picker-popper  " -->
          <el-date-picker
            :disabled="isDisabled"
            class="ztzf-layer-date-picker"
            v-model="timeValue"
            type="datetimerange"
            format="YYYY-MM-DD HH:mm"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
                :disabled-date="disabledDate"
          />
        </div>
      </div>
      <div class="itemRow">
        <div class="label">围栏备注</div>
        <div class="label">{{ layerParams.fenceType === 1 ? '识别区' : '禁飞区' }}备注</div>
        <div>
          <el-input v-model="detailData.description" :rows="5" type="textarea" placeholder="请输入" />
          <el-input
            :disabled="isDisabled"
            v-model="formData.description"
            :rows="5"
            type="textarea"
            placeholder="请输入"
          />
        </div>
      </div>
    </div>
    <div class="detailInfo">
      <div class="infpItem">
      <div class="infpItem" v-if="layerParams.editNest && layerParams.fenceType === 1">
        <div class="itemData">
          <div class="title">围栏总数量</div>
          <div class="num"><span>{{totalCount}}</span>个</div>
        </div>
        <div class="itemData">
          <div class="title">围栏总面积</div>
          <div class="num"><span>{{totalArea}}</span>m²</div>
        </div>
      </div>
      <div class="infpItem">
        <div class="itemData">
          <div class="title">创建时间</div>
          <div class="num"><span>{{detailData.create_time}}</span></div>
          <div class="title">识别区面积</div>
          <div class="num">
            <span class="areaStyle">{{ fenceArea }}</span> m²
          </div>
        </div>
        <div class="itemData">
          <div class="title">创建人</div>
          <div class="num"><span>{{detailData.create_name}}</span></div>
          <div class="num">
            <span>{{ formData?.create_name }}</span>
          </div>
        </div>
      </div>
      <div class="infpItem" v-if="layerParams.fenceType === 2">
        <div class="itemData" v-if="layerParams.editNest && layerParams.fenceType === 2">
          <div class="title">禁飞区面积</div>
          <div class="num">
            <span class="areaStyle">{{ fenceArea }}</span> m²
          </div>
        </div>
        <div class="itemData">
          <div class="title">禁飞区高度</div>
          <div class="num noFly">
            <span
              ><el-input
                :disabled="isDisabled"
                class="ztzf-layer-input inputName"
                v-model="formData.altitude"
                placeholder="请输入"
            /></span>
            米
          </div>
        </div>
      </div>
      <div class="infpItem" v-if="layerParams.editNest && layerParams.fenceType === 2">
        <div class="itemData">
          <div class="title">创建时间</div>
          <div class="num">
            <span>{{ formData?.create_time }}</span>
          </div>
        </div>
        <div class="itemData">
          <div class="title">创建人</div>
          <div class="num">
            <span>{{ formData?.create_name }}</span>
          </div>
        </div>
      </div>
      <div class="infpItem" v-if="layerParams.editNest && layerParams.fenceType === 1">
        <div class="itemData">
          <div class="title">创建时间</div>
          <div class="num">
            <span>{{ formData?.create_time }}</span>
          </div>
        </div>
      </div>
    </div>
    <div class="btnGroups">
      <img src="/src/assets/images/layerManagement/savebtn.svg" alt="" @click="submitHandle" />
      <img src="/src/assets/images/layerManagement/cancelbtn.svg" @click="cancelHandel" alt="" />
      <img v-if="!layerParams.editingIsProhibited && layerParams.fenceArea / 1000000 > 50" src="/src/assets/images/layerManagement/disabled.svg" alt="" />
      <img v-if="!layerParams.editingIsProhibited && layerParams.fenceArea / 1000000 < 50" src="/src/assets/images/layerManagement/savebtn.svg" alt="" @click="submitHandle" />
      <img v-if="layerParams.editingIsProhibited" src="/src/assets/images/layerManagement/closeBtn.svg" @click="cancelHandel" alt="" />
      <img v-else src="/src/assets/images/layerManagement/cancelbtn.svg" @click="cancelHandel" alt="" />
    </div>
  </div>
</template>
<script setup>
const emit = defineEmits([ 'callParentMethod']);
import { ElMessage } from 'element-plus';
import dayjs from 'dayjs';
import { deitFenceApi, addFenceApi } from '@/api/layer/index';
import EventBus from '@/utils/eventBus';
const emit = defineEmits(['callParentMethod','update:loading']);
const layerParams = inject('layerParams');
const options = ref([]);
const timeValue = ref('');
options.value = layerParams.value.folderOption;
const formData = ref({
  folder_id: '',
  name: '',
@@ -70,24 +151,219 @@
  control_start_time: '',
  control_end_time: '',
  geo_data: '',
});
const detailData = ref(null)
detailData.value = layerParams.value.editDetailData
const totalArea = layerParams.value.total_area
const totalCount = layerParams.value.total_count
console.log('layerParams',layerParams
);
const cancelHandel = () => {
});
const loading = ref(false);
const detailData = ref(null);
const fenceArea = ref(0);
detailData.value = layerParams.value.editDetailData;
fenceArea.value = layerParams.value.fenceArea;
const isDisabled = computed(() => {
  return layerParams.value.editingIsProhibited;
});
// 禁用当天之前的日期
const disabledDate = time => {
  return time.getTime() < Date.now() - 8.64e7 // 86400000 = 24 * 60 * 60 * 1000
}
watch(
  () => layerParams.value.fenceArea,
  newArea => {
    if (newArea !== undefined && newArea !== null) {
      if (newArea / 1000000 < 50) {
        fenceArea.value = newArea;
        formData.value.area = newArea;
      }
    }
  },
  { immediate: true }
);
// 监听editDetailData的变化
watch(
  () => layerParams.value.editDetailData,
  newVal => {
    if (newVal && layerParams.value.editingIsProhibited) {
      // 当editDetailData有值时,填充表单
      formData.value = {
        ...formData.value,
        folder_id: newVal.folder_id || '',
        name: newVal.name || '',
        description: newVal.description || '',
        is_enabled: newVal.is_enabled || false,
        area: newVal.area || '',
        altitude: newVal.altitude || '',
        control_start_time: newVal.control_start_time || '',
        control_end_time: newVal.control_end_time || '',
        geo_data: newVal.geo_data || '',
        create_name: newVal.create_name || '',
        create_time: newVal.create_time ? dayjs(newVal.create_time).format('YYYY年MM月DD日') : '',
      };
      // 处理文件夹选择
      if (newVal.folder_id && options.value.length > 0) {
        const matchedFolder = options.value.find(item => item.value === String(newVal.folder_id));
        if (matchedFolder) {
          formData.value.folder_id = matchedFolder.value;
        }
      }
      // 处理时间选择
      if (newVal.control_start_time && newVal.control_end_time) {
        timeValue.value = [
          dayjs(newVal.control_start_time).toDate(),
          dayjs(newVal.control_end_time).toDate(),
        ];
      }
    }
  },
  { immediate: true, deep: true }
);
watch(
  () => timeValue.value,
  newTimeArr => {
    if (Array.isArray(newTimeArr) && newTimeArr.length === 2) {
      const startTime = newTimeArr[0];
      const endTime = newTimeArr[1];
      formData.value.control_start_time = dayjs(startTime).format('YYYY-MM-DD HH:mm:ss');
      formData.value.control_end_time = dayjs(endTime).format('YYYY-MM-DD HH:mm:ss');
    } else {
      formData.value.control_start_time = '';
      formData.value.control_end_time = '';
    }
  },
  { immediate: true }
);
const clearAllData = () => {
  detailData.value = {};
  layerParams.value.decideWhetherToAddOrEdit = 1;
  // 重置面板状态和缓存数据
  layerParams.value.addNest = false;
  layerParams.value.editNest = false;
   emit('callParentMethod');
  layerParams.value.editDetailData = null;
  layerParams.value.polygonPosition = null;
  layerParams.value.editingIsProhibited = false;
};
const cancelHandel = () => {
loading.value = false
 emit('update:loading', false);
  clearAllData();
  emit('callParentMethod');
  EventBus.emit('gettreeDataApi');
};
const submitHandle = () => {
  layerParams.value.addNest = false;
  layerParams.value.editNest = false;
   emit('callParentMethod');
if(layerParams.value.crossSurface){
  return ElMessage.warning('测区不支持交叉面')
}
  if (!formData.value.folder_id) {
    ElMessage.error('请选择文件夹');
    return;
  }
  if (!formData.value.name) {
    ElMessage.error('请输入名称');
    return;
  }
  if (!formData.value.altitude && layerParams.value.fenceType === 2) {
    ElMessage.error('请输入高度');
    return;
  }
  if (fenceArea.value === 0) {
    ElMessage.error('请绘制区域');
    return;
  }
  loading.value = true
  emit('update:loading', true);
  const params = {
    folder_id: formData.value.folder_id,
    name: formData.value.name,
    description: formData.value.description,
    is_enabled: true,
    area: formData.value.area,
    altitude: formData.value.altitude,
    geo_data: layerParams.value.polygonPosition
      ? layerParams.value.polygonPosition
      : formData.value.geo_data,
    control_start_time: formData.value.control_start_time,
    control_end_time: formData.value.control_end_time,
  };
  // 如果是编辑模式,才添加 id
  if (layerParams.value.decideWhetherToAddOrEdit === 2) {
    params.id = detailData.value.id;
  }
  if (layerParams.value.decideWhetherToAddOrEdit === 1) {
    //围栏新增
    addFenceApi(params)
      .then(res => {
       if(res.data.code ===0 ){
          ElMessage.success('新增成功');
          EventBus.emit('gettreeDataApi');
          loading.value = false;
          emit('update:loading', false);
          clearAllData();
          emit('callParentMethod');
 }
      })
      .catch(err => {
        ElMessage.error('新增失败,请重试');
      })
      .finally(() => {
        loading.value = false;
         emit('update:loading', false);
      });
  } else if (layerParams.value.decideWhetherToAddOrEdit === 2) {
    //围栏编辑
      deitFenceApi(params)
      .then(res => {
      if(res.data.code === 0){
        ElMessage.success('编辑成功');
        EventBus.emit('gettreeDataApi');
        clearAllData();
        emit('callParentMethod');
        loading.value = false;
         emit('update:loading', false);
      }
      })
      .catch(err => {
        ElMessage.error('编辑失败,请重试');
      })
      .finally(() => {
        loading.value = false;
         emit('update:loading', false);
      });
        }
};
onMounted(() => {
  // 获取判断状态(默认设为 1)
  const addOrEditStatus = layerParams.value.decideWhetherToAddOrEdit || 1;
  if (addOrEditStatus === 2) {
    // 编辑状态:回显数据
    const editData = layerParams.value.editDetailData || {};
    formData.value = {
      folder_id: editData.folder_id || '',
      name: editData.name || '',
      description: editData.description || '',
      is_enabled: editData.is_enabled || false,
      area: editData.area || '',
      altitude: editData.altitude || '',
      control_start_time: editData.control_start_time || '',
      control_end_time: editData.control_end_time || '',
      geo_data: editData.geo_data || '',
      create_name: editData.create_name,
      create_time: editData.create_time ? dayjs(editData.create_time).format('YYYY年MM月DD日') : '',
    };
    if (editData.folder_id && options.value.length > 0) {
      const matchedFolder = options.value.find(item => item.value === String(editData.folder_id));
      if (matchedFolder) {
        formData.value.folder_id = matchedFolder.value;
      }
    }
    if (editData.control_start_time && editData.control_end_time) {
      timeValue.value = [
        dayjs(editData.control_start_time).toDate(),
        dayjs(editData.control_end_time).toDate(),
      ];
    }
    fenceArea.value = editData.area || 0;
  }
});
</script>
<style scoped lang="scss">
@@ -95,19 +371,26 @@
  position: absolute;
  top: 0;
  right: 0;
  height: 95%;
height: calc(100% - 32px);
  z-index: 99;
  width: 324px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.8);
  background: rgba(0,0,0,0.51);
  backdrop-filter: blur(4px);
  border-radius: 8px 8px 8px 8px;
  padding: 16px 12px;
:deep(.el-select__wrapper.is-disabled .el-select__selected-item){
color: rgba(255,255,255,0.37) !important;
}
  :deep(.el-textarea__inner) {
    background: transparent !important;
    color: #ffffff !important;
    color: #ffffff;
  }
  :deep(.el-textarea.is-disabled .el-textarea__inner){
    color: var(--el-disabled-text-color) !important;
}
  .contenttitle {
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-weight: bold;
@@ -126,6 +409,13 @@
    .label {
      margin-bottom: 5px;
    }
    :deep(.el-date-editor.el-input__wrapper) {
      width: auto !important;
      background: transparent !important;
    }
    :deep(.el-range-editor.is-disabled input) {
      background-color: transparent !important;
    }
  }
  .detailInfo {
    .infpItem {
@@ -135,15 +425,25 @@
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 400;
      font-size: 14px;
      color: #ffffff;
      color: #dfdfdf;
      margin-bottom: 23px;
      .num {
        span {
          font-family: Source Han Sans CN, Source Han Sans CN;
          font-weight: bold;
          font-size: 14px;
          color: #ffffff;
        }
        .areaStyle {
          font-family: Source Han Sans CN, Source Han Sans CN;
          font-weight: bold;
          font-size: 20px;
          color: #ffffff;
        }
      }
      .noFly {
        display: flex;
        align-items: center;
      }
      .itemData {
        width: 50%;
@@ -154,7 +454,7 @@
    display: flex;
    justify-content: center;
    position: absolute;
    bottom: 59px;
    bottom: 29px;
    left: 0;
    right: 0;
    img {
@@ -162,6 +462,7 @@
      height: 39px;
      cursor: pointer;
    }
  }
}
</style>