zhangyihao před 8 měsíci
rodič
revize
100bb03688

+ 48 - 0
src/api/duty/eventing.ts

@@ -94,3 +94,51 @@ export function uploadEventCasualties(data) {
     data: data
   });
 }
+// 匹配应急预案
+export function matchingPlan(data) {
+  return request({
+    url: '/api/event_management/event/march_emergency_plan',
+    method: 'post',
+    data: data
+  });
+}
+// 列出应急预案
+export function listPlan(data) {
+  return request({
+    url: '/api/emergency_plan/event/avail_plan_list',
+    method: 'post',
+    data: data
+  });
+}
+// 启动应急预案
+export function launchPlan(data) {
+  return request({
+    url: '/api/event_management/event/lauch_emergency_plan',
+    method: 'post',
+    data: data
+  });
+}
+// 获取预案单位任务
+export function unitTask(data) {
+  return request({
+    url: '/api/emergency_plan/event/unit_task',
+    method: 'post',
+    data: data
+  });
+}
+// 预案任务下发
+export function sendTask(data) {
+  return request({
+    url: '/api/event_management/event/send_emergency_plan_task_by_yzy',
+    method: 'post',
+    data: data
+  });
+}
+// 获取预案通知
+export function taskList(data) {
+  return request({
+    url: '/api/event_management/event/emergency_plan_task_list',
+    method: 'post',
+    data: data
+  });
+}

+ 80 - 46
src/views/emergencyCommandMap/RightSection/SelectPlan.vue

@@ -1,85 +1,119 @@
 <template>
-  <el-dialog ref="formDialogRef" v-model="innerModelValue" :title="props.title || '选择预案'" width="900px" append-to-body @close="closeDialog">
+  <el-dialog ref="dialogRef" v-model="isDialogVisible" :title="dialogTitle" width="900px" append-to-body @close="handleCloseDialog">
+    <!-- 预案选择器 -->
     <div class="plan-selector">
       <label for="plan-select">预案名称:</label>
-      <select id="plan-select" v-model="selectedPlan">
-        <option v-for="plan in plans" :key="plan.id" :value="plan.id">{{ plan.name }}</option>
+      <select id="plan-select" v-model="selectedPlanId">
+        <option value="">请选择预案</option>
+        <option v-for="plan in plans" :key="plan.plan_id" :value="plan.plan_id">{{ plan.plan_name }}</option>
       </select>
     </div>
     <template #footer>
       <span class="dialog-footer">
-        <button class="custom-button" @click="visible = false">取消</button>
-        <button class="custom-button" @click="startPlan">确定并启动预案</button>
+        <button class="custom-button" @click="hideDialog">取消</button>
+        <button class="custom-button" @click="startSelectedPlan">确定并启动预案</button>
       </span>
     </template>
-    <StartPlan v-model="startPlanState.show" :title="startPlanState.title" />
+    <StartPlan v-model="startPlanVisible" :title="startPlanTitle" />
   </el-dialog>
 </template>
 
 <script lang="ts" setup>
-import { defineEmits, defineProps, ref, watch } from 'vue';
+import { defineEmits, defineProps, onMounted, ref, watch } from 'vue';
+import { listPlan } from '@/api/duty/eventing';
 import StartPlan from '@/views/emergencyCommandMap/RightSection/StartPlan.vue';
 
-// 假设 plans 是一个包含预案信息的数组
-const plans = [
-  { id: 1, name: '预案 A' },
-  { id: 2, name: '预案 B' }
-  // 更多预案...
-];
+// 用于存储预案信息的数组
+const plans = ref([]);
 
-const visible = ref(false);
-const selectedPlan = ref<number | null>(null); // 初始值可以根据实际情况设置
+// 初始化 selectedPlanId 为 null 表示没有选择任何预案
+const selectedPlanId = ref<number | null>(null);
 
-interface Props {
-  modelValue: boolean;
-  eventId: string;
-  title: string; // 确保 title 是必需的
-}
-const props = withDefaults(defineProps<Props>(), {
-  modelValue: false,
-  eventId: '',
-  title: '' // 提供一个默认值,如果允许为空
-});
+// 定义组件属性
+const props = withDefaults(
+  defineProps<{
+    modelValue: boolean;
+    event_id: string;
+    plan_id: string;
+    plan_name: string;
+    response_level: string;
+  }>(),
+  {
+    modelValue: false,
+    event_id: '',
+    plan_id: '',
+    plan_name: '',
+    response_level: ''
+  }
+);
 
+// 定义组件事件
 const emits = defineEmits(['update:modelValue']);
-const innerModelValue = ref(props.modelValue);
 
+// 控制内部模型值
+const isDialogVisible = ref(props.modelValue);
+
+// 设置默认对话框标题
+const dialogTitle = ref('选择预案');
+
+// 监听 modelValue 的变化
 watch(
   () => props.modelValue,
   (newValue) => {
-    innerModelValue.value = newValue;
+    isDialogVisible.value = newValue;
     if (newValue) {
-      visible.value = true; // 当对话框打开时显示子内容
+      fetchPlanList(); // 获取预案列表
     }
   }
 );
 
-const closeDialog = () => {
+// 控制对话框的显示
+const startPlanVisible = ref(false);
+const startPlanTitle = ref('');
+
+// 关闭对话框
+const handleCloseDialog = () => {
   emits('update:modelValue', false);
 };
 
-// 当 dialog 关闭时重置 visible
-watch(innerModelValue, (newVal) => {
-  if (!newVal) {
-    visible.value = false; // 当对话框关闭时隐藏子内容
+// 启动预案
+const startSelectedPlan = () => {
+  startPlanTitle.value = '启动预案';
+  startPlanVisible.value = true;
+};
+
+// 获取预案列表
+const fetchPlanList = async () => {
+  try {
+    const response = await listPlan();
+    if (response.data && Array.isArray(response.data)) {
+      plans.value = response.data;
+      console.log('Fetched plans:', response.data); // 调试信息
+    } else {
+      console.error('Invalid data format in the response:', response);
+    }
+  } catch (error) {
+    console.error('Error fetching plan list:', error);
   }
-});
-//启动预案弹窗
-const startPlanState = reactive({
-  show: false,
-  title: ''
-});
-// 处理选择预案的函数
-const startPlan = () => {
-  console.log('startPlan');
-  startPlanState.title = '启动预案';
-  startPlanState.show = true;
 };
 
+// 隐藏对话框
+const hideDialog = () => {
+  emits('update:modelValue', false);
+};
+
+// 组件挂载时尝试获取预案列表
+onMounted(() => {
+  if (props.modelValue) {
+    fetchPlanList();
+  }
+});
+
 // 调试信息
-console.log('Initial innerModelValue:', innerModelValue.value);
-console.log('Initial visible:', visible.value);
+console.log('Initial isDialogVisible:', isDialogVisible.value);
+console.log('Initial selectedPlanId:', selectedPlanId.value);
 </script>
+
 <style scoped>
 .plan-selector {
   display: flex;

+ 171 - 79
src/views/emergencyCommandMap/RightSection/StartPlan.vue

@@ -1,59 +1,56 @@
 <template>
-  <el-dialog ref="formDialogRef" v-model="props.modelValue" :title="props.title" width="1000px" append-to-body @close="closeDialog">
-    <div class="start-plan-content">
+  <el-dialog ref="dialogRef" v-model="visible" :title="title" width="1000px" append-to-body @close="onClose">
+    <div class="plan-content">
+      <!-- 响应等级选择和操作按钮 -->
       <el-row :gutter="20">
         <el-col :span="12">
           <div class="section-title select-level-container">
             <span>响应等级</span>
             <el-select v-model="selectedLevel" placeholder="请选择响应等级" class="select-level">
-              <el-option v-for="level in levels" :key="level.value" :label="level.name" :value="level.value"></el-option>
+              <el-option v-for="level in responseLevels" :key="level.value" :label="level.name" :value="level.value"></el-option>
             </el-select>
           </div>
         </el-col>
-        <el-col :span="12" class="buttons-container">
-          <el-button type="primary" @click="handleStartPlan">启动预案</el-button>
-          <el-button type="primary" @click="taskDelivery">预案任务下发内容</el-button>
+        <el-col :span="12" class="button-container">
+          <el-button type="primary" @click="onStartPlan">启动预案</el-button>
+          <el-button type="primary" @click="onTaskDelivery">预案任务下发</el-button>
         </el-col>
       </el-row>
-      <h2>xxx预案名称</h2>
-      <el-row shadow="hover" class="fixed-width-row">
-        <el-tabs v-model="activeName" type="border-card" class="demo-tabs" @tab-click="handleClick2">
-          <el-tab-pane label="总则" name="first">
+      <!-- 预案名称 -->
+      <h2>{{ planTitle }}</h2>
+      <!-- 预案内容的标签页 -->
+      <el-row class="content-row">
+        <el-tabs v-model="activeTab" type="border-card" @tab-click="onTabClick">
+          <el-tab-pane label="总则" name="principles">
             <div>
+              <!-- 锚点导航 -->
               <el-row>
                 <el-col :span="4">
-                  <el-anchor :container="containerRef" direction="vertical" type="default" :offset="30" @click="handleClick1">
-                    <el-anchor-link href="#part1" title="编制目的" />
-                    <el-anchor-link href="#part2" title="编制依据" />
-                    <el-anchor-link href="#part3" title="适用范围" />
-                    <el-anchor-link href="#part4" title="工作原则" />
+                  <el-anchor :container="contentContainer" direction="vertical" type="default" :offset="30">
+                    <el-anchor-link href="#purpose" title="编制目的" />
+                    <el-anchor-link href="#basis" title="编制依据" />
+                    <el-anchor-link href="#scope" title="适用范围" />
+                    <el-anchor-link href="#principles" title="工作原则" />
                   </el-anchor>
                 </el-col>
+                <!-- 可滚动的内容区域 -->
                 <el-col :span="20">
-                  <div ref="containerRef" style="height: 300px; overflow-y: auto">
-                    <div id="part1" style="height: auto; margin-top: 20px; font-size: 14px">
-                      <h3 style="font-weight: 600">1.1 编制目的</h3>
-                      <span style="text-indent: 2em"
-                        >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
-                      >
+                  <div ref="contentContainer" style="height: 300px; overflow-y: auto">
+                    <div id="purpose" style="margin-top: 20px; font-size: 14px">
+                      <h3>1.1 编制目的</h3>
+                      <p>{{ planData.purpose }}</p>
                     </div>
-                    <div id="part2" style="height: auto; margin-top: 15px; font-size: 14px">
-                      <h3 style="font-weight: 600">1.2 编制依据</h3>
-                      <span style="text-indent: 28px"
-                        >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
-                      >
+                    <div id="basis" style="margin-top: 15px; font-size: 14px">
+                      <h3>1.2 编制依据</h3>
+                      <p>{{ planData.basis }}</p>
                     </div>
-                    <div id="part3" style="height: auto; margin-top: 15px; font-size: 14px">
-                      <h3 style="font-weight: 600">1.3 适用范围</h3>
-                      <span style="text-indent: 28px"
-                        >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
-                      >
+                    <div id="scope" style="margin-top: 15px; font-size: 14px">
+                      <h3>1.3 适用范围</h3>
+                      <p>{{ planData.scope }}</p>
                     </div>
-                    <div id="part4" style="height: auto; margin-top: 15px; font-size: 14px">
-                      <h3 style="font-weight: 600">1.4 工作原则</h3>
-                      <span style="text-indent: 28px"
-                        >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
-                      >
+                    <div id="principles" style="margin-top: 15px; font-size: 14px">
+                      <h3>1.4 工作原则</h3>
+                      <p>{{ planData.principles }}</p>
                     </div>
                   </div>
                 </el-col>
@@ -69,79 +66,166 @@
         </el-tabs>
       </el-row>
     </div>
-    <TaskDelivery v-model="taskDeliveryState.show" :title="taskDeliveryState.title" />
+    <TaskDelivery v-model="taskDeliveryState.show" :title="taskDeliveryState.title" :plan-id="planData.plan_id" :event-id="props.eventId" />
   </el-dialog>
 </template>
 
 <script lang="ts" setup>
-import { defineProps, defineEmits, ref, watch } from 'vue';
+import { ref, watch, defineProps, defineEmits, reactive } from 'vue';
+import { ElMessage } from 'element-plus';
 import TaskDelivery from './TaskDelivery.vue';
-const visible = ref(false);
+import { matchingPlan, launchPlan } from '@/api/duty/eventing';
+
+// 定义组件接收的属性类型
 interface Props {
   modelValue: boolean;
   eventId: string;
   title: string;
 }
-const props = withDefaults(defineProps<Props>(), {
-  modelValue: false,
-  eventId: '',
-  title: ''
+
+// 初始化组件属性
+const props = defineProps<Props>();
+
+// 内部状态
+const visible = ref(props.modelValue); // 对话框是否可见
+const planTitle = ref(''); // 预案名称
+const selectedLevel = ref(''); // 默认响应等级为空
+const responseLevels = [
+  // 响应等级选项
+  { value: '1', name: '特重大(I级)' },
+  { value: '2', name: '重大(II级)' },
+  { value: '3', name: '较大(III级)' },
+  { value: '4', name: '一般(IV级)' }
+];
+const activeTab = ref('principles'); // 当前激活的标签页
+const planData = reactive({
+  purpose: '这是内容...', // 编制目的
+  basis: '这是内容...', // 编制依据
+  scope: '这是内容...', // 适用范围
+  principles: '这是内容...', // 工作原则
+  plan_id: '' // 添加 plan_id 属性
 });
 
 // 定义事件发射器
-const emits = defineEmits(['update:modelValue']);
-
-// 内部响应式变量
-const innerModelValue = ref(props.modelValue);
-// 响应等级选择
-const selectedLevel = ref('');
-
-// 响应等级选项
-const levels = [
-  { value: '1', name: '一级' },
-  { value: '2', name: '二级' },
-  { value: '3', name: '三级' }
-];
+const emit = defineEmits(['update:modelValue']);
 
-// 当props.modelValue改变时,更新内部变量
+// 监听 modelValue 变化
 watch(
   () => props.modelValue,
   (newValue) => {
-    innerModelValue.value = newValue;
+    visible.value = newValue;
   }
 );
 
 // 对话框关闭时执行的操作
-const closeDialog = () => {
-  emits('update:modelValue', false);
+const onClose = () => {
+  emit('update:modelValue', false);
 };
 
 // 处理启动预案的函数
-const handleStartPlan = () => {
-  console.log('启动预案');
-};
+const onStartPlan = async () => {
+  // 检查是否选择了响应等级
+  if (!selectedLevel.value) {
+    ElMessage.error('请先选择响应等级!');
+    return;
+  }
 
-const containerRef = ref<HTMLElement | null>(null);
-const handleClick1 = (e: MouseEvent) => {
-  e.preventDefault();
-};
+  // 收集数据
+  const data = {
+    response_level: selectedLevel.value,
+    eventId: props.eventId,
+    plan_id: planData.plan_id // 确保 planData 中包含正确的 plan_id
+  };
 
-const activeName = ref('first');
-const handleClick2 = (tab: TabsPaneContext, event: Event) => {
-  console.log(tab, event);
+  try {
+    // 调用后端API启动预案
+    const response = await launchPlan(data);
+    if (response && response.code === 200) {
+      ElMessage.success('预案启动成功!');
+    } else if (response && response.code !== 200) {
+      ElMessage.error(`预案启动失败,后端返回错误码:${response.code}`);
+    }
+  } catch (error) {
+    console.error('启动预案时发生的错误:', error);
+    if (error.response && error.response.data && error.response.data.message) {
+      ElMessage.error(error.response.data.message);
+    } else if (error.response && error.response.status) {
+      ElMessage.error(`启动预案时发生错误,HTTP 状态码:${error.response.status}`);
+    } else {
+      ElMessage.error('启动预案时发生未知错误,请稍后再试。');
+    }
+  }
+};
+// 处理标签页点击事件
+const onTabClick = (tab: any, event: Event) => {
+  // 实现标签页点击的逻辑
 };
+
 // 控制 taskDelivery 弹窗的显示状态
 const taskDeliveryState = reactive({
-  show: false,
-  title: ''
+  show: ref(false),
+  title: '' as string
 });
+
 // 处理预案任务下发内容的函数
-const taskDelivery = () => {
-  console.log('taskDelivery');
+const onTaskDelivery = () => {
   taskDeliveryState.title = '预案任务下发';
   taskDeliveryState.show = true;
 };
+
+// 调用接口获取预案数据
+const fetchPlanData = async () => {
+  try {
+    if (!props.eventId) {
+      ElMessage.warning('eventId 为空,无法获取预案数据');
+      return;
+    }
+    const response = await matchingPlan({ eventId: props.eventId });
+    if (response && response.code === 200) {
+      const data = response.data;
+      planTitle.value = `预案名称: ${data.plan_name}`;
+      if (data.response_level) {
+        const isValidLevel = responseLevels.some((level) => level.value === data.response_level);
+        if (isValidLevel) {
+          selectedLevel.value = data.response_level;
+        } else {
+          ElMessage.error('无效的响应等级,请检查数据');
+          selectedLevel.value = '';
+        }
+      } else {
+        selectedLevel.value = '';
+      }
+      planData.purpose = data.purpose || '这是内容...';
+      planData.basis = data.basis || '这是内容...';
+      planData.scope = data.scope || '这是内容...';
+      planData.principles = data.principles || '这是内容...';
+      planData.plan_id = data.plan_id; // 确保 planData 中包含 plan_id
+    } else {
+      ElMessage.error('未能从服务器获取有效的预案数据');
+    }
+  } catch (error) {
+    ElMessage.error('获取预案数据失败');
+  }
+};
+
+// 在组件挂载时尝试获取预案数据
+onMounted(() => {
+  if (props.eventId) {
+    fetchPlanData();
+  }
+});
+
+// 监听 eventId 变化
+watch(
+  () => props.eventId,
+  (newEventId) => {
+    if (newEventId) {
+      fetchPlanData();
+    }
+  }
+);
 </script>
+
 <style scoped>
 .start-plan-content .section-title {
   display: flex;
@@ -162,13 +246,21 @@ const taskDelivery = () => {
 .select-level {
   flex-grow: 1; /* 让下拉框尽可能占据剩余空间 */
 }
+h2 {
+  text-align: center;
+}
+/* 样式 */
+.plan-content {
+  display: flex;
+  flex-direction: column;
+}
 
-.buttons-container {
+.button-container {
   display: flex;
-  justify-content: flex-end; /* 靠右对齐 */
-  gap: 10px; /* 设置按钮之间的间距 */
+  justify-content: flex-end;
 }
-h2 {
-  text-align: center;
+
+.content-row {
+  margin-top: 20px;
 }
 </style>

+ 71 - 31
src/views/emergencyCommandMap/RightSection/TaskDelivery.vue

@@ -3,12 +3,23 @@
   <el-dialog ref="formDialogRef" v-model="props.modelValue" :title="props.title" width="900px" @close="closeDialog">
     <!-- 子对话框 -->
     <el-dialog v-model="dialogVisible" title="预任务任务下发" width="70%" :append-to-body="true" @close="handleClose">
-      <div class="task-list" v-if="dialogVisible">
-        <!-- 使用 v-for 循环遍历任务列表 -->
-        <div v-for="(task, index) in tasks" :key="index" class="task-item">
-          <p class="unit-name">{{ task.unit }}</p>
-          <p class="task-description">{{ task.description }}</p>
-        </div>
+      <div v-if="dialogVisible" class="task-list">
+        <!-- 加载提示 -->
+        <el-skeleton :loading="loading" animated>
+          <template #template>
+            <div v-for="n in 3" :key="n" class="task-item">
+              <el-skeleton-item variant="p" style="width: 80%" />
+              <el-skeleton-item variant="p" style="margin-top: 16px" />
+            </div>
+          </template>
+          <template #default>
+            <!-- 使用 v-for 循环遍历任务列表 -->
+            <div v-for="(task, index) in tasks" :key="index" class="task-item">
+              <p class="unit-name">{{ task.dept_name }}</p>
+              <p class="task-description">{{ task.content }}</p>
+            </div>
+          </template>
+        </el-skeleton>
       </div>
       <!-- 对话框底部按钮区域 -->
       <template #footer>
@@ -20,16 +31,20 @@
     </el-dialog>
   </el-dialog>
 </template>
+
 <script lang="ts" setup>
 import { defineProps, defineEmits, ref, watch, onMounted } from 'vue';
-import { ElMessage } from 'element-plus'; // 假设使用的是 Element Plus
+import { ElMessage, ElLoading } from 'element-plus'; // 假设使用的是 Element Plus
+import { unitTask, sendTask } from '@/api/duty/eventing'; // 导入已有的 unitTask 接口
 
 // 定义组件属性类型
 interface Props {
   modelValue: boolean;
-  eventId?: string; // 将 eventId 设置为可选属性
   title: string;
+  planId?: string; // 新增 planId prop
+  eventId?: string;
 }
+
 const props = defineProps<Props>();
 
 // 定义事件发射器
@@ -37,21 +52,19 @@ const emit = defineEmits(['update:modelValue']);
 
 // 内部响应式变量
 const dialogVisible = ref(props.modelValue); // 控制子对话框的显示状态
-const tasks = ref([
-  { unit: '市委宣传部', description: '负责救灾工作宣传报道协调工作。这是一段很长的描述文字,需要自动换行以适应容器的宽度。' },
-  { unit: '市委宣传部1', description: '负责救灾工作宣传报道协调工作。这也是一段很长的描述文字,需要自动换行以适应容器的宽度。' },
-  { unit: '市委宣传部2', description: '负责救灾工作宣传报道协调工作。这是一段很长的描述文字,需要自动换行以适应容器的宽度。' },
-  { unit: '市委宣传部3', description: '负责救灾工作宣传报道协调工作。这也是一段很长的描述文字,需要自动换行以适应容器的宽度。' }
-]); // 任务列表
+const tasks = ref<Array<{ id: string; dept_id: string; dept_name: string; content: string }>>([]);
+const loading = ref(false); // 控制加载提示的状态
 
 // 监听 modelValue 变化,确保当外部关闭时,内部对话框也关闭
 watch(
   () => props.modelValue,
   (newValue) => {
     dialogVisible.value = newValue;
+    if (newValue && props.planId && props.eventId) {
+      fetchDataWithLoading(props.planId, props.eventId);
+    }
   }
 );
-
 // 在组件挂载后显示对话框(仅用于测试)
 onMounted(() => {
   // 如果需要,可以在这里进行一些初始化操作
@@ -68,26 +81,53 @@ const handleClose = () => {
   emit('update:modelValue', false);
 };
 
+// 获取任务列表,并显示加载提示
+const fetchDataWithLoading = async () => {
+  loading.value = true;
+  try {
+    const response = await unitTask({ plan_id: props.planId });
+    if (response && response.data && Array.isArray(response.data)) {
+      tasks.value = response.data;
+    } else {
+      ElMessage.error('未能从服务器获取有效任务数据');
+    }
+  } catch (error) {
+    ElMessage.error('获取任务数据失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
 // 发送任务时的操作
 const sendTasks = () => {
-  // 模拟发送请求到后端接口
-  simulateBackendRequest(tasks.value).then(() => {
-    console.log('发送H5短信');
-    ElMessage.success('任务已成功发送!');
-    dialogVisible.value = false;
-    emit('update:modelValue', false);
-  });
-};
+  // 检查 props.eventId 是否存在
+  if (!props.eventId) {
+    ElMessage.error('事件ID未定义,无法发送任务!');
+    return;
+  }
 
-// 模拟发送请求到后端接口
-const simulateBackendRequest = async (tasks: Array<{ unit: string; description: string }>) => {
-  // 这里可以替换为实际的后端请求逻辑
-  return new Promise((resolve) => {
-    setTimeout(() => {
-      resolve(true);
-    }, 1000);
-  });
+  // 调用 sendTask 函数发送任务
+  sendTask({ eventId: props.eventId })
+    .then((response) => {
+      console.log('发送H5短信成功', response);
+      ElMessage.success('任务已成功发送!');
+      dialogVisible.value = false;
+      emit('update:modelValue', false);
+    })
+    .catch((error) => {
+      console.error('发送H5短信失败', error);
+      ElMessage.error('发送任务失败,请稍后再试!');
+    });
 };
+// 模拟发送请求到后端接口
+// const simulateBackendRequest = async (tasks: Array<{ id: string; dept_id: string; dept_name: string; content: string }>, planId: string) => {
+//   // 这里可以替换为实际的后端请求逻辑
+//   return new Promise((resolve) => {
+//     setTimeout(() => {
+//       resolve(true);
+//     }, 1000);
+//   });
+// };
 </script>
 
 <style scoped>

+ 38 - 130
src/views/emergencyCommandMap/RightSection/index.vue

@@ -35,89 +35,68 @@
         <div class="btn-text">返回上级</div>
       </div>
     </div>
-    <!--    <div class="video-card">-->
-    <!--      <div class="title gradient-text">视频监控</div>-->
-    <!--      <div class="card-content video-list">-->
-    <!--        <div v-for="(item, index) in videoMonitorState.listData" :key="index" class="video-box" @click="showVideoDialog(item)">-->
-    <!--          <div class="video-content">-->
-    <!--            <div style="width: 550px; height: 300px; position: relative">-->
-    <!--              <HKVideo :dot_data="item" :width="550" :height="300" />-->
-    <!--              <div class="video-label">-->
-    <!--                <span class="label">{{ item.name }}</span>-->
-    <!--              </div>-->
-    <!--            </div>-->
-    <!--          </div>-->
-    <!--        </div>-->
-    <!--      </div>-->
-    <!--    </div>-->
     <RightTop />
     <JointDuty />
-    <!--    <div class="message-card">-->
-    <!--      <div class="title gradient-text">动态消息</div>-->
-    <!--      <div class="message-menu">-->
-    <!--        <div :class="menuState.activeIndex === 0 ? 'menu-item menu-active' : 'menu-item'" @click="menuState.activeIndex = 0">消息动态</div>-->
-    <!--        <div :class="menuState.activeIndex === 1 ? 'menu-item menu-active' : 'menu-item'" @click="menuState.activeIndex = 1">任务跟踪</div>-->
-    <!--        <div :class="menuState.activeIndex === 2 ? 'menu-item menu-active' : 'menu-item'" @click="menuState.activeIndex = 2">资源调度</div>-->
-    <!--      </div>-->
-    <!--      <div v-show="menuState.activeIndex === 0" class="message-content">-->
-    <!--        <div v-for="(item, index) in menuState.messageData" :key="index" class="message-item">-->
-    <!--          <i :class="getIconClass(item.type)"></i>-->
-    <!--          <div class="message-box">-->
-    <!--            <div :class="getTagClass(item.type)">{{ item.text }}</div>-->
-    <!--            <div class="message-time">{{ item.time }}</div>-->
-    <!--          </div>-->
-    <!--        </div>-->
-    <!--      </div>-->
-    <!--    </div>-->
   </div>
-  <!--  <Dialog v-model="videoMonitorState.showListDialog" title="视频监控">-->
-  <!--    <videoList />-->
-  <!--  </Dialog>-->
-  <SelectPlan v-model="selectPlanState.show" :plans="selectPlanState.plans" @plan-selected="onPlanSelected" />
-  <StartPlan v-model="startPlanState.show" :title="startPlanState.title" />
+  <StartPlan v-model="startPlanState.show" :title="startPlanState.title" :event-id="eventId" />
+  <SelectPlan v-model="selectPlanState.show" :title="selectPlanState.title" />
 </template>
 
 <script lang="ts" setup>
-import router from '@/router';
-import { getEmergencyVideoCata } from '@/api/videoMonitor';
+import { onMounted, ref, reactive, nextTick } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
 import JointDuty from '@/views/emergencyCommandMap/RightSection/JointDuty.vue';
 import RightTop from '@/views/emergencyCommandMap/RightSection/RightTop.vue';
 import StartPlan from './StartPlan.vue';
 import SelectPlan from './SelectPlan.vue';
-import CloseCommand from '@/views/emergencyCommandMap/LeftSection/CloseCommand.vue';
-const goToHome = () => {
-  router.push({ path: '/' });
-};
-//启动预案弹窗
+
+let eventId = ref('');
+
+// 启动预案弹窗
 const startPlanState = reactive({
   show: false,
-  title: ''
+  title: '',
+  eventId: ''
 });
 
 // 控制 selectPlan 弹窗的显示状态
 const selectPlanState = reactive({
   show: false,
-  title: ''
+  title: '',
+  plans: [] as { id: number; name: string }[]
 });
-// 处理选择预案的函数
-// const selectPlan = () => {
-//   console.log('selectPlan');
-//   selectPlanState.title = '预案任务下发';
-//   selectPlanState.show = true;
-// };
 
-const startPlan = (eventId) => {
-  if (eventId) {
+// 从URL中获取event_id
+const getEventIdFromUrl = () => {
+  const route = useRoute();
+  const urlParams = new URLSearchParams(route.query);
+  eventId.value = urlParams.get('event_id') || '';
+};
+
+// 启动预案的方法
+const startPlan = () => {
+  console.log('Checking eventId:', eventId.value); // 输出 eventId
+  if (eventId.value) {
+    // 如果有eventId,则显示StartPlan弹窗,并传递eventId
     startPlanState.title = '启动预案';
+    startPlanState.eventId = eventId.value;
     startPlanState.show = true;
+    console.log('Showing StartPlan with eventId:', eventId.value, 'and state:', startPlanState.show);
+
+    // 使用 nextTick 确保 DOM 更新完成
+    nextTick().then(() => {
+      console.log('DOM updated, showing StartPlan:', startPlanState.show);
+    });
   } else {
-    // 如果没有eventId,则显示选择预案的弹窗
-    selectPlanState.show = true;
+    // 如果没有eventId,则显示SelectPlan弹窗
     selectPlanState.title = '预案任务下发';
-    // 可能需要加载预案列表
+    selectPlanState.show = true;
+    console.log('Showing SelectPlan with state:', selectPlanState.show);
+    // 可选操作:加载预案列表
     loadPlans();
   }
 };
+
 const loadPlans = () => {
   // 这里应该有一个API调用来获取所有可用的预案
   // 仅作示例,下面的数组是假定的预案数据
@@ -127,82 +106,11 @@ const loadPlans = () => {
     { id: 3, name: '应急预案C' }
   ];
 };
-const onPlanSelected = (plan) => {
-  selectPlanState.selectedPlan = plan;
-  // 当选择了一个预案后,可以关闭选择预案的弹窗并打开启动预案的弹窗
-  selectPlanState.show = false;
-  startPlanState.title = `启动预案 - ${plan.name}`;
-  startPlanState.show = true;
-};
-// 视频监控
-const videoMonitorState = reactive({
-  listData: [],
-  showListDialog: false,
-  showDetailDialog: false,
-  detailData: { name: '', url: '' }
-});
-// 显示视频列表
-const showVideoMonitorList = () => {
-  videoMonitorState.showListDialog = true;
-};
-// 显示视频弹窗
-const showVideoDialog = (item) => {
-  videoMonitorState.detailData = item;
-  videoMonitorState.showDetailDialog = true;
-};
-
-// 动态消息
-const menuState = reactive({
-  activeIndex: 0,
-  // type 1success 2 primary 3 warning 4danger
-  messageData: []
-});
-// 获取消息动态图标
-const getIconClass = (type) => {
-  let className = 'message-primary';
-  if (type === '1') {
-    className = 'message-success';
-  } else if (type === '2') {
-    className = 'message-primary';
-  } else if (type === '3') {
-    className = 'message-warning';
-  } else if (type === '4') {
-    className = 'message-danger';
-  }
-  return className;
-};
-// 获取消息动态tag
-const getTagClass = (type) => {
-  let className = 'tag-primary';
-  if (type === '1') {
-    className = 'tag-success';
-  } else if (type === '2') {
-    className = 'tag-primary';
-  } else if (type === '3') {
-    className = 'tag-warning';
-  } else if (type === '4') {
-    className = 'tag-danger';
-  }
-  return className;
-};
 
 // 初始化数据
 const initData = () => {
-  // 预案管理数据
-  getEmergencyVideoCata({
-    current: 1,
-    size: 8
-  }).then((res) => {
-    videoMonitorState.listData = res.rows;
-  });
-  // 动态消息
-  menuState.messageData = [
-    { type: '1', text: '结束处置', time: '2024-07-04 13:25:49' },
-    { type: '2', text: '发起粤政易群聊', time: '2024-07-04 13:25:49' },
-    { type: '3', text: '发起视频会商', time: '2024-07-04 13:25:49' },
-    { type: '4', text: '启动二级响应预案', time: '2024-07-04 13:25:49' },
-    { type: '4', text: '事件接报,详情:广东省茂名市茂南区东荟城发生洪涝灾害', time: '2024-07-04 13:25:49' }
-  ];
+  getEventIdFromUrl();
+  console.log('Event ID from URL:', eventId.value); // 输出从 URL 获取的 eventId
 };
 
 onMounted(() => {

+ 1 - 1
src/views/routineCommandMap/EventManage.vue

@@ -319,7 +319,7 @@ const emit = defineEmits(['update:modelValue']);
 const { modelValue } = toRefs(props);
 
 // 监听props的modelValue变化
-watch(modelValue,(newValue) => {
+watch(modelValue, (newValue) => {
   if (newValue) {
     getList();
   }

+ 1 - 1
src/views/routineCommandMap/MiddleSection.vue

@@ -4,7 +4,7 @@
       <el-button type="primary" @click="handleQuery1" :disabled="true">备战防御</el-button>
       <el-button type="primary" @click="handleQuery2">指挥调度</el-button>
     </div>
-<!--    <company-map v-model:visible="mapDialogVisible" @change="handleMapChange" />-->
+    <company-map v-model:visible="mapDialogVisible" @change="handleMapChange" />
     <GlobalMap is-component width="3894" height="2140" />
   </div>
 </template>