forked from drone/command-center-dashboard

罗广辉
2025-04-21 2800fa4f32f3900509cb4d6eefaf2bfaf54efdd7
src/views/TaskManage/TaskIntermediateContent/AddTask.vue
@@ -1,49 +1,72 @@
<!-- 机巢列表详情 -->
<!-- 新建任务 -->
<template>
   <el-dialog
      class="ztzf-dialog"
      modal-class="add-task"
      v-model="isShowAddTask"
      title="新建任务"
      :width="pxToRem(1500)"
      :close-on-click-modal="false"
      :destroy-on-close="true">
      :destroy-on-close="true"
      @close="cancel"
   >
      <!-- <el-divider content-position="left">新建任务</el-divider> -->
      <div class="task-contain">
         <div class="left">
            <div class="search">
               <div class="item"><span class="required">*</span>任务名称:<el-input v-model="searchForm.name" placeholder="请输入任务名称"></el-input></div>
               <div class="item"><span class="required">*</span>任务日期:
               <div class="item">
                  <el-input class="ztzf-input" v-model="searchForm.name" placeholder="请输入任务/机巢名称"></el-input>
               </div>
               <div class="item">
                  <el-date-picker
                     popper-class="custom-date-picker"
                     class="ztzf-date-picker"
                     v-model="taskData"
                     format="YYYY-MM-DD"
                     type="daterange"
                     range-separator="至"
                     start-placeholder="开始日期"
                     end-placeholder="结束日期"
                     value-format="YYYY-MM-DD"
                     :disabled-date="disabledDate"
                  />
               </div>
               <div class="item">任务时间:
               <div class="item">
                  <div class="itemchild">任务时间:</div>
                  <el-time-picker
                     v-model="searchForm.execute_time_arr"
                     placeholder="选择时间"
                   popper-class="custom-time-picker"
                     class="ztzf-date-picker tasktimer"
                     v-model="timeSlot"
                     placeholder="请选择"
                     format="HH:mm"
                     value-format="HH:mm"/>
                     value-format="HH:mm"
                  />
               </div>
               <div class="item">选择航线:
               <div class="item">
                  <div class="itemchild">选择航线:</div>
                  <el-select
                     :teleported="false"
                     class="ztzf-select"
                     v-model="searchForm.file_id"
                     @change="getWayLineFile"
                     placeholder="请选择航线"
                     clearable>
                     clearable
                  >
                     <el-option
                        v-for="item in routeOptions"
                        :key="item.wayline_id"
                        :label="item.name"
                        :value="item.wayline_id"/>
                     </el-select>
                  </div>
                  <div class="item">关联算法:
                     <TaskAlgorithmBusiness :showAlgorithm="true" @algorithmChange="algorithmChange"/>
                  </div>
               <div class="item">任务描述:<el-input v-model="searchForm.remark" placeholder="请输入任务名称"></el-input></div>
                        :value="item.wayline_id"
                     />
                  </el-select>
               </div>
               <div class="item">
                  <div class="itemchild">关联算法:</div>
                  <TaskAlgorithmBusiness :setWidth="200" :showAlgorithm="true" @algorithmChange="algorithmChange" />
               </div>
               <div class="item">
                  <div class="itemchild">任务描述:</div>
                  <el-input class="ztzf-input" v-model="searchForm.remark" placeholder="请输入任务名称"></el-input>
               </div>
            </div>
            <div class="lines">
               <div class="wayline-type">
@@ -52,26 +75,28 @@
                     <el-radio :value="2" label="智能规划选区"></el-radio>
                  </el-radio-group>
               </div>
               <TaskMap class="wayline-map"
               <TaskMap
                  class="wayline-map"
                  :wayLineFile="wayLineFile"
                  :checkedTableData="checkedTableData"
                  :waylineTypeTest="waylineType"
                  :waylineTypeTest="waylineType"
                  @clickPosition="clickSignPosition"
                  @saveWayline="savePlanerWayline"
               />
            </div>
         </div>
         <div class="right">
            <TaskTable ref="taskTableRef"
               :waylineId="waylineId"
               :waylineType="waylineType"
            <TaskTable
               ref="taskTableRef"
               :waylineId="waylineId"
               :waylineType="waylineType"
               :singlePoint="singlePoint"
               :planarPoints="planarPoints"
               @update:selected="handleSelected"
               @update:selected="handleSelected"
            />
            <div class="btn">
               <el-button type="primary" @click="cancel">取消</el-button>
               <el-button type="primary" @click="submitClick">发布</el-button>
               <img @click="cancel" style="margin-right: 23px" src="@/assets/images/task/cancel.png" alt="" />
               <img @click="submitClick" src="@/assets/images/task/publish.png" alt="" />
            </div>
         </div>
      </div>
@@ -79,25 +104,26 @@
</template>
<script setup>
import { ElMessage } from 'element-plus';
import { pxToRem } from '@/utils/rem';
import { getWaylineList, createTask } from '@/api/home/task';
import TaskAlgorithmBusiness from '../components/TaskAlgorithmBusiness.vue';
import TaskMap from './TaskMap.vue';
import TaskTable from './TaskTable.vue';
import { ElMessage } from 'element-plus'
import { pxToRem } from '@/utils/rem'
import { getWaylineList, createTask } from '@/api/home/task'
import TaskAlgorithmBusiness from '../components/TaskAlgorithmBusiness.vue'
import TaskMap from './TaskMap.vue'
import TaskTable from './TaskTable.vue'
const emit = defineEmits(['refresh']);
const emit = defineEmits(['refresh'])
const rangDate = ref([]);
const rangDate = ref([])
// 航线ID
const waylineId = ref('');
const waylineId = ref('')
// 航线文件
const wayLineFile = ref('');
const wayLineFile = ref('')
// 航线类型
const waylineType = ref(3);
const waylineType = ref(3)
// 添加子组件引用
const taskTableRef = ref(null);
const taskData = ref('');
const taskTableRef = ref(null)
const taskData = ref('')
const timeSlot = ref('')
const searchForm = reactive({
   name: '',
   ai_types: [],
@@ -111,204 +137,237 @@
   longitude: '',
   latitude: '',
   polygon: [],
});
const isShowAddTask = defineModel('show');
})
const isShowAddTask = defineModel('show')
// 禁用当天之前的日期
const disabledDate = (time) => {
  return time.getTime() < Date.now() - 8.64e7; // 86400000 = 24 * 60 * 60 * 1000
};
const disabledDate = time => {
   return time.getTime() < Date.now() - 8.64e7 // 86400000 = 24 * 60 * 60 * 1000
}
// 获取航线列表数据
const routeOptions = ref([]);
const routeOptions = ref([])
const getRouteList = async () => {
  const res = await getWaylineList();
  if (res.data.code === 0) {
    routeOptions.value = res.data.data;
  }
};
   const res = await getWaylineList()
   if (res.data.code === 0) {
      routeOptions.value = res.data.data
   }
}
// 关联算法
const algorithmChange = (val) => {
  searchForm.ai_types = val;
};
const algorithmChange = val => {
   searchForm.ai_types = val
}
// 切换航线类型
const radioChange = (val) => {
const radioChange = val => {
   // 清空选中航线值
   searchForm.file_id = '';
   searchForm.file_id = ''
   // 航线ID也清空
   waylineId.value = '';
   wayLineFile.value = '';
  waylineType.value = val;
   searchForm.type = val;
   waylineId.value = ''
   wayLineFile.value = ''
   waylineType.value = val
   searchForm.type = val
   // 清空列表数据
   nextTick(() => {
    if (taskTableRef.value) {
      taskTableRef.value.clearTableData();
    }
  });
};
      if (taskTableRef.value) {
         taskTableRef.value.clearTableData()
      }
   })
}
// 获取航线文件
const getWayLineFile = async (val) => {
   searchForm.type = 0;
   waylineType.value = 0;
   waylineId.value = val;
   const currentRoute = routeOptions.value.find(item => item.wayline_id === val);
  wayLineFile.value = currentRoute.object_key;
};
const getWayLineFile = async val => {
   searchForm.type = 0
   waylineType.value = 0
   waylineId.value = val
   const currentRoute = routeOptions.value.find(item => item.wayline_id === val)
   wayLineFile.value = currentRoute?.object_key || ''
}
// 获取选中机场列表数据,并且发布
let checkedTableData = ref([]);
const handleSelected = (val) => {
  searchForm.dock_sns = val.map(item => item.device_sn);
   checkedTableData.value = val;
};
let checkedTableData = ref([])
const handleSelected = val => {
   searchForm.dock_sns = val.map(item => item.device_sn)
   checkedTableData.value = val
}
// 地图点击事件 表格重新刷新数据
let singlePoint = ref({});
const clickSignPosition = (val) => {
  singlePoint.value = val;
   searchForm.longitude = val.longitude;
   searchForm.latitude = val.latitude;
};
let singlePoint = ref({})
const clickSignPosition = val => {
   singlePoint.value = val
   searchForm.longitude = val.longitude
   searchForm.latitude = val.latitude
}
// 保存面状航线
let planarPoints = ref([]);
const savePlanerWayline = (val) => {
  planarPoints.value = val;
   const polygonArray = val.map(point => [point.longitude, point.latitude]);
   searchForm.polygon = polygonArray;
};
let planarPoints = ref([])
const savePlanerWayline = val => {
   planarPoints.value = val
   const polygonArray = val.map(point => [point.longitude, point.latitude])
   searchForm.polygon = polygonArray
}
// 提交
const submitClick = () => {
   if (!taskData.value) {
    ElMessage({
      message: '请选择任务日期',
      type: 'warning'
    });
    return;
  }
      ElMessage({
         message: '请选择任务日期',
         type: 'warning',
      })
      return
   }
   if (!searchForm.name) {
    ElMessage({
      message: '请输入任务名称',
      type: 'warning'
    });
    return;
  }
      ElMessage({
         message: '请输入任务名称',
         type: 'warning',
      })
      return
   }
   // 检查任务时间
  if (searchForm.execute_time_arr) {
    const now = new Date();
    const today = now.toDateString();
    const selectedDate = new Date(taskData.value).toDateString();
    if (today === selectedDate) {
      const [hours, minutes] = searchForm.execute_time_arr.split(':');
      const selectedTime = new Date();
      selectedTime.setHours(parseInt(hours), parseInt(minutes));
      if (selectedTime < now) {
        ElMessage({
          message: '任务时间不能小于当前时间',
          type: 'warning'
        });
        return;
      }
    }
  }
   searchForm.begin_time = `${taskData.value} 00:00:00`;
  searchForm.end_time = `${taskData.value} 23:59:59`;
   createTask(searchForm).then((res) => {
      if (res.data.code === 0) {
         ElMessage.success('任务创建成功');
         // 关闭当前窗口,刷新任务管理列表
         isShowAddTask.value = false;
         emit('refresh');
   if (timeSlot.value) {
      const now = new Date()
      const today = now.toDateString()
      const selectedDate = new Date(taskData.value).toDateString()
      if (today === selectedDate) {
         const [hours, minutes] = timeSlot.value.split(':')
         const selectedTime = new Date()
         selectedTime.setHours(parseInt(hours), parseInt(minutes))
         if (selectedTime < now) {
            ElMessage({
               message: '任务时间不能小于当前时间',
               type: 'warning',
            })
            return
         }
      }
   });
};
   }
   if (searchForm.dock_sns.length === 0) {
      ElMessage({
         message: '请选择机场',
         type: 'warning',
      })
      return
   }
   searchForm.begin_time = `${taskData.value[0]} 00:00:00`
   searchForm.end_time = `${taskData.value[1]} 23:59:59`
   searchForm.execute_time_arr = timeSlot.value ? [timeSlot.value] : []
   createTask(searchForm).then(res => {
      if (res.data.code === 0) {
         ElMessage.success('任务创建成功')
         // 关闭当前窗口,刷新任务管理列表
         isShowAddTask.value = false
         // 清除数据
         cancel()
         emit('refresh')
      }
   })
}
const cancel = () => {
  isShowAddTask.value = false;
   isShowAddTask.value = false
   // 清除搜索数据
   searchForm.name = '';
  searchForm.ai_types = [];
  searchForm.file_id = '';
  searchForm.begin_time = '';
  searchForm.end_time = '';
  searchForm.execute_time_arr = '';
  searchForm.remark = '';
  searchForm.dock_sns = [];
  rangDate.value = [];
  waylineId.value = '';
  wayLineFile.value = '';
   taskData.value = '';
};
   searchForm.name = ''
   searchForm.ai_types = []
   searchForm.file_id = ''
   searchForm.begin_time = ''
   searchForm.end_time = ''
   timeSlot.value = ''
   searchForm.remark = ''
   searchForm.dock_sns = []
   rangDate.value = []
   waylineId.value = ''
   wayLineFile.value = ''
   taskData.value = ''
}
onMounted(() => {
  getRouteList();
   getRouteList()
})
</script>
<style lang="scss">
.add-task{
.add-task {
   .el-pagination {
      text-align: left;
      padding: 20px;
   }
}
/* 修改日期单元格背景色 */
.custom-date-picker .el-picker-panel__body {
   background: #012350 !important;
   color: #fff !important;
}
</style>
<style lang="scss" scoped>
.task-contain {
   display: flex;
   padding: 20px 32px 32px 27px;
   .left {
      width: 68%;
      margin-right: 35px;
      .search {
         display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-template-rows: repeat(2, 1fr);
      gap: 30px; // 增加间距使布局更合理
      margin-bottom: 8px; // 添加底部间距
         grid-template-columns: repeat(3, 1fr);
         grid-template-rows: repeat(2, 1fr);
         gap: 30px; // 增加间距使布局更合理
         margin-bottom: 8px; // 添加底部间距
         .item {
            position: relative;
        display: flex;
        align-items: center;
        :deep(.el-input),
        :deep(.el-select),
        :deep(.el-date-picker),
        :deep(.el-time-picker) {
          width: 240px;
          // margin-left: 10px;
        }
            :deep(.el-date-editor.el-input__wrapper) {
          width: 200px;  // 调整日期选择器宽度
        }
            .required {
               color: #f56c6c;
               margin-left: 4px;
               position: absolute;
               left: -10px;
               top: 8px;
            display: flex;
            align-items: center;
            font-size: 16px;
            color: #ffffff;
            .itemchild {
               width: 68px;
               white-space: nowrap;
               margin-right: 5px;
            }
      }
            :deep(.el-date-editor.el-input__wrapper) {
               width: 200px; // 调整日期选择器宽度
            }
         }
      }
   }
   .right {
      width: 32%;
      display: flex;
    flex-direction: column;
    justify-content: space-between;
    .btn {
      margin-top: 20px;
      text-align: center;
      .el-button {
        margin: 0 10px;
      }
    }
      flex-direction: column;
      justify-content: space-between;
      .btn {
         display: flex;
         justify-content: center;
         align-items: center;
         img {
            width: 137px;
            height: 32px;
            cursor: pointer;
         }
      }
   }
   :deep(.tasktimer .el-input__wrapper) {
      background: none !important;
      color: #8ac3fd !important;
   }
   :deep(.el-input__inner) {
      color: #8ac3fd !important;
      &::placeholder {
         color: #8ac3fd !important;
      }
   }
   :deep(.el-radio__inner) {
      background: none !important;
      border: 1px solid #1b5d9a !important;
   }
   :deep(.el-radio__label) {
      color: #fff !important;
   }
   :deep(.el-radio__inner:after) {
      background: #65b5ff !important;
   }
}
</style>