Jelajahi Sumber

Merge remote-tracking branch 'origin/dev' into dev

Hwf 8 bulan lalu
induk
melakukan
09896048ee

+ 35 - 0
src/api/emergencyCommandMap/JointDuty.ts

@@ -60,3 +60,38 @@ export function addEvent(data) {
     data: data
   });
 }
+// 任务新增
+export function addTask(data) {
+  return request({
+    url: '/api/taskRegistration/create',
+    method: 'post',
+    data: data
+  });
+}
+// 任务查询
+export function selectTask(data) {
+  return request({
+    url: '/api/taskRegistration/select',
+    method: 'post',
+    params: {
+      query: addTask.data
+    },
+    data: data
+  });
+}
+// 任务更新
+export function updateTask(data) {
+  return request({
+    url: '/api/taskRegistration/update',
+    method: 'post',
+    data: data
+  });
+}
+// 任务删除
+export function deleteTask(data) {
+  return request({
+    url: '/api/taskRegistration/delete',
+    method: 'post',
+    data: data
+  });
+}

TEMPAT SAMPAH
src/assets/images/map/rightMenu/content.png


+ 1 - 0
src/components/Map/index.vue

@@ -33,6 +33,7 @@ import {
   getHospitalDetails,
   getMiningcompanyDetails,
   getRescueMateriaDetails,
+  getChemicalcompanyDetails,
   getSchoolDetails,
   getWaterloggedRoadsDetails
 } from "@/api/globalMap/spatialAnalysis";

+ 1 - 1
src/views/emergencyCommandMap/LeftSection/index.vue

@@ -90,7 +90,7 @@
     <CloseCommand
       v-model="closeCommandState.show"
       :title="closeCommandState.title"
-      :flag="flag"
+      :flag="closeCommandState.flag"
       :event-id="eventId"
       @update:model-value="fetchEventDetail"
     />

+ 145 - 0
src/views/emergencyCommandMap/RightSection/RenWuDengJi.vue

@@ -0,0 +1,145 @@
+<template>
+  <div v-if="showRegisterDialog" class="dialog">
+    <div class="dialog-content">
+      <div class="dialog-header">
+        <span>任务登记</span>
+        <button @click="closeDialog">×</button>
+      </div>
+
+      <div class="dialog-body">
+        <div class="form-group">
+          <label>任务内容:</label>
+          <textarea v-model="newTask.description" placeholder="请输入相关任务描述"></textarea>
+        </div>
+        <div class="form-group">
+          <label>执行单位:</label>
+          <select v-model="newTask.unit">
+            <option disabled value="">请选择执行单位</option>
+            <option v-for="unit in units" :key="unit.value" :value="unit.value">{{ unit.label }}</option>
+          </select>
+        </div>
+        <div class="form-group">
+          <label>登记人:</label>
+          <input v-model="newTask.registrar" type="text" readonly />
+        </div>
+      </div>
+
+      <div class="dialog-footer">
+        <button @click="confirmRegister">确定</button>
+        <button @click="closeDialog">取消</button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, onMounted } from 'vue';
+import { addTask } from '@/api/emergencyCommandMap/JointDuty.ts'; // 确保API路径正确
+
+const showRegisterDialog = ref(true);
+const newTask = reactive({
+  description: '',
+  unit: '',
+  registrar: '当前用户' // 这里应该是从全局状态或API获取的当前用户
+});
+const units = ref([]);
+
+// 获取单位数据
+const fetchUnits = async () => {
+  try {
+    const response = await getUnits();
+    if (response.code === 200) {
+      units.value = response.data; // 假设返回的数据是数组 [{ label: '单位A', value: 'unitA' }, ...]
+    } else {
+      console.error('获取单位数据失败:', response.msg);
+    }
+  } catch (error) {
+    console.error('请求单位数据失败:', error);
+  }
+};
+
+// 关闭弹窗
+const closeDialog = () => {
+  showRegisterDialog.value = false;
+};
+
+// 确认登记任务
+const confirmRegister = async () => {
+  try {
+    const response = await addTask(newTask);
+    if (response.code === 200) {
+      console.log('任务登记成功');
+      closeDialog();
+    } else {
+      console.error('任务登记失败:', response.msg);
+    }
+  } catch (error) {
+    console.error('请求任务登记失败:', error);
+  }
+};
+
+// 在组件挂载时获取单位数据
+onMounted(() => {
+  fetchUnits();
+});
+</script>
+
+<style scoped>
+.dialog {
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  background-color: white;
+  border-radius: 8px;
+  box-shadow: 0 50px 50px rgba(0, 0, 0, 0.1);
+  width: 1500px;
+}
+
+.dialog-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  border-bottom: 1px solid #eee;
+  padding: 10px;
+}
+
+.dialog-body {
+  padding: 10px;
+}
+
+.form-group {
+  margin-bottom: 15px;
+}
+
+.dialog-footer {
+  display: flex;
+  justify-content: flex-end;
+  padding: 10px;
+}
+
+button {
+  margin-left: 10px;
+  padding: 5px 15px;
+  border: none;
+  background-color: #3498db;
+  color: white;
+  border-radius: 4px;
+  cursor: pointer;
+}
+
+button:hover {
+  background-color: #2980b9;
+}
+
+textarea,
+select,
+input[type='text'] {
+  width: 100%;
+  box-sizing: border-box;
+  padding: 5px;
+  margin-top: 5px;
+  border-radius: 4px;
+  border: 1px solid #ccc;
+}
+</style>

+ 198 - 0
src/views/emergencyCommandMap/RightSection/RenWuGenZong.vue

@@ -0,0 +1,198 @@
+<template>
+  <div class="duty-card">
+    <ul class="tabs">
+      <li v-for="(tab, index) in tabs" :key="index" :class="{ active: tab.id === activeTab }" @click="setActiveTab(tab.id)">
+        {{ tab.label }}
+      </li>
+    </ul>
+    <div class="card-content">
+      <div v-if="activeTab === '任务追踪'" class="custom-table">
+        <div class="table-content">
+          <div v-for="(notification, index) in notifications" :key="index" class="tr">
+            <div class="td">
+              <div class="unit-date">
+                <span class="unit">{{ notification.unit }}</span>
+                <span class="date">{{ notification.date }}</span>
+                <span class="status" :class="statusClasses[notification.status]">{{ notification.status }}</span>
+                <button @click="updateTask(index)">更新</button>
+              </div>
+              <div class="content">{{ notification.content }}</div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { onMounted, ref } from 'vue';
+import { selectTask, updateTask } from '@/api/emergencyCommandMap/JointDuty.ts'; // 确保API路径正确
+
+const props = defineProps<{
+  eventId?: string; // 使用可选属性
+}>();
+
+// 输出 eventId 以验证是否正确获取
+console.log('Received eventId in RightTop:', props.eventId);
+
+// 定义 tabs
+const tabs = reactive([
+  { id: '任务追踪', label: '任务追踪' },
+  { id: '预案通知', label: '预案通知' },
+  { id: '资源调度', label: '资源调度' }
+]);
+
+const activeTab = ref('任务追踪');
+const notifications = ref([]);
+const statusClasses = reactive({
+  '已完成': 'success',
+  '处理中': 'processing'
+});
+
+const setActiveTab = (id) => {
+  activeTab.value = id;
+};
+
+// 请求数据
+const fetchData = async () => {
+  try {
+    if (!props.eventId) {
+      console.error('eventId 未找到');
+      return;
+    }
+
+    const response = await selectTask({ eventId: props.eventId });
+
+    if (response.code === 200) {
+      console.log('查询成功:', response.data);
+      updateTaskList(response.data);
+    } else {
+      console.error('查询失败:', response.msg);
+    }
+  } catch (error) {
+    console.error('请求失败:', error);
+  }
+};
+
+// 更新任务列表
+const updateTask = (tasks) => {
+  notifications.value = tasks.map((task) => ({
+    unit: tasks.unit_name,
+    date: tasks.update_time,
+    status: task.processing_status,
+    content: task.task_description
+  }));
+};
+
+// 更新任务
+const updateTask = async (index) => {
+  try {
+    const task = notifications.value[index];
+    const response = await updateTask(task);
+
+    if (response.code === 200) {
+      console.log('任务更新成功');
+      fetchData(); // 重新加载任务列表
+    } else {
+      console.error('任务更新失败:', response.msg);
+    }
+  } catch (error) {
+    console.error('请求任务更新失败:', error);
+  }
+};
+
+// 在组件挂载时获取数据
+onMounted(() => {
+  console.log('Mounting RightTop component');
+  if (props.eventId) {
+    fetchData();
+  } else {
+    console.warn('RightTop did not receive eventId:', props.eventId);
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.tabs {
+  display: flex;
+  justify-content: flex-start; /* 选项卡靠左对齐 */
+  padding: 0 0;
+  background: rgba(0, 0, 0, 0.3);
+  .active {
+    border-bottom: 3px solid #00e8ff;
+  }
+  li {
+    cursor: pointer;
+    padding: 20px;
+    font-size: 36px;
+    color: #fff;
+    &:hover {
+      background-color: rgba(0, 0, 0, 0.5);
+    }
+  }
+}
+
+.custom-table {
+  width: 100%;
+  .table-content {
+    height: 600px;
+    overflow-y: auto;
+    .tr {
+      display: flex;
+      align-items: center;
+      .td {
+        flex: 1;
+        padding: 10px;
+        font-size: 36px;
+        .unit-date {
+          display: flex;
+          align-items: center; /* 确保垂直居中 */
+          justify-content: space-between; /* 使 status 靠右对齐 */
+          span {
+            white-space: nowrap;
+            &.unit {
+              font-size: 36px; /* 调整字体大小 */
+              margin-right: 5px; /* 减小单位与日期之间的间距 */
+            }
+            &.date {
+              font-size: 36px; /* 调整字体大小 */
+              margin-right: auto; /* 使用 auto 推动 status 靠右 */
+            }
+            &.status {
+              font-size: 36px; /* 调整字体大小 */
+              text-align: right; /* 可选:如果需要进一步对齐内部文本 */
+            }
+            &.error {
+              color: #ff4d4f; /* 发送失败时使用红色 */
+            }
+            &.success {
+              color: #fff; /* 发送成功时使用黑色 */
+            }
+          }
+        }
+        .content {
+          margin-top: 10px;
+          font-size: 36px; /* 内容字体大小 */
+          line-height: 1.5; /* 增加行高以适应较大的字体 */
+        }
+      }
+    }
+  }
+}
+
+.duty-card {
+  width: 2601px;
+  height: 879px;
+  background: url('@/assets/images/emergencyCommandMap/videoBox1.png') no-repeat 100% 100%;
+  position: relative;
+  color: #fff;
+  .card-content {
+    display: flex;
+    flex-wrap: wrap;
+    padding-top: 10px; /* 减小顶部填充 */
+    padding-left: 100px;
+    width: 2500px;
+  }
+}
+</style>

+ 138 - 0
src/views/emergencyCommandMap/RightSection/RenWuGengXin.vue

@@ -0,0 +1,138 @@
+<template>
+  <div v-if="showRegisterDialog" class="dialog">
+    <div class="dialog-content">
+      <div class="dialog-header">
+        <span>任务进度更新</span>
+        <button @click="closeDialog">×</button>
+      </div>
+
+      <div class="dialog-body">
+        <div class="form-group">
+          <label>任务描述:</label>
+          <input v-model="newTask.description" type="text" readonly />
+        </div>
+        <div class="form-group">
+          <label>执行单位:</label>
+          <input v-model="newTask.registrar" type="text" readonly />
+        </div>
+        <div class="form-group">
+          <label>完成进度:</label>
+          <select v-model="newTask.progress">
+            <option v-for="unit in units" :key="unit" :value="unit">{{ unit }}</option>
+          </select>
+        </div>
+      </div>
+
+      <div class="dialog-footer">
+        <button @click="confirmRegister">确定</button>
+        <button @click="closeDialog">取消</button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive } from 'vue';
+import { updateTask } from '@/api/emergencyCommandMap/JointDuty.ts'; // 确保API路径正确
+
+const showRegisterDialog = ref(false);
+const newTask = reactive({
+  description: '',
+  registrar: '当前用户',
+  progress: ''
+});
+const units = ref(['已处理', '已完成']);
+
+// 打开弹窗并初始化任务数据
+const openDialog = (task) => {
+  newTask.description = task.description;
+  newTask.registrar = task.registrar;
+  newTask.progress = task.progress || '';
+  showRegisterDialog.value = true;
+};
+
+// 关闭弹窗
+const closeDialog = () => {
+  showRegisterDialog.value = false;
+};
+
+// 确认登记任务
+const confirmRegister = async () => {
+  try {
+    const response = await updateTask({
+      id: newTask.id, // 假设任务有唯一ID
+      description: newTask.description,
+      registrar: newTask.registrar,
+      processing_status: newTask.progress
+    });
+    if (response.code === 200) {
+      console.log('任务进度更新成功');
+      closeDialog();
+    } else {
+      console.error('任务进度更新失败:', response.msg);
+    }
+  } catch (error) {
+    console.error('请求任务进度更新失败:', error);
+  }
+};
+</script>
+
+<style scoped>
+.dialog {
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  background-color: white;
+  border-radius: 8px;
+  box-shadow: 0 50px 50px rgba(0, 0, 0, 0.1);
+  width: 1500px;
+}
+
+.dialog-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  border-bottom: 1px solid #eee;
+  padding: 10px;
+}
+
+.dialog-body {
+  padding: 10px;
+}
+
+.form-group {
+  margin-bottom: 15px;
+}
+
+.dialog-footer {
+  display: flex;
+  justify-content: flex-end;
+  padding: 10px;
+}
+
+button {
+  margin-left: 10px;
+  padding: 5px 15px;
+  border: none;
+  background-color: #3498db;
+  color: white;
+  border-radius: 4px;
+  cursor: pointer;
+}
+
+button:hover {
+  background-color: #2980b9;
+}
+
+textarea,
+select,
+input[type='text'] {
+  width: 100%;
+  box-sizing: border-box;
+  padding: 5px;
+  margin-top: 5px;
+  border-radius: 4px;
+  border: 1px solid #ccc;
+}
+</style>

+ 141 - 0
src/views/emergencyCommandMap/RightSection/RenWuTanChuan.vue

@@ -0,0 +1,141 @@
+<template>
+  <div v-if="showModal" class="modal-overlay" @click="closeModal">
+    <div class="modal-content" @click.stop>
+      <div class="modal-header">
+        <h2>任务详情</h2>
+        <button @click="closeModal">关闭</button>
+      </div>
+      <div class="modal-body">
+        <table>
+          <thead>
+            <tr>
+              <th>任务内容</th>
+              <th>执行单位</th>
+              <th>登记人</th>
+              <th>登记时间</th>
+              <th>完成进度</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr v-for="(task, index) in paginatedTasks" :key="index">
+              <td>{{ task.content }}</td>
+              <td>{{ task.unit }}</td>
+              <td>{{ task.registrant }}</td>
+              <td>{{ task.time }}</td>
+              <td>{{ task.progress }}</td>
+            </tr>
+          </tbody>
+        </table>
+        <div class="pagination">
+          <button :disabled="currentPage === 1" @click="prevPage">上一页</button>
+          <span>第 {{ currentPage }} 页,共 {{ totalPages }} 页</span>
+          <button :disabled="currentPage === totalPages" @click="nextPage">下一页</button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted } from 'vue';
+import { selectTask } from '@/api/emergencyCommandMap/JointDuty.ts'; // 确保API路径正确
+
+const showModal = ref(false);
+const tasks = ref([]);
+const currentPage = ref(1);
+const pageSize = ref(5);
+
+const totalPages = computed(() => Math.ceil(tasks.value.length / pageSize.value));
+
+const paginatedTasks = computed(() => {
+  const start = (currentPage.value - 1) * pageSize.value;
+  const end = start + pageSize.value;
+  return tasks.value.slice(start, end);
+});
+const closeModal = () => {
+  showModal.value = false;
+};
+
+const prevPage = () => {
+  if (currentPage.value > 1) {
+    currentPage.value--;
+  }
+};
+
+const nextPage = () => {
+  if (currentPage.value < totalPages.value) {
+    currentPage.value++;
+  }
+};
+
+const fetchTasks = async () => {
+  try {
+    const response = await selectTask();
+    if (response.code === 200) {
+      tasks.value = response.data;
+    } else {
+      console.error('获取任务数据失败:', response.msg);
+    }
+  } catch (error) {
+    console.error('请求任务数据失败:', error);
+  }
+};
+
+onMounted(() => {
+  fetchTasks();
+});
+</script>
+
+<style scoped>
+.modal-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.modal-content {
+  background: white;
+  padding: 20px;
+  border-radius: 8px;
+  width: 80%;
+  max-width: 800px;
+}
+
+.modal-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+table {
+  width: 100%;
+  border-collapse: collapse;
+}
+
+th,
+td {
+  border: 1px solid #ddd;
+  padding: 8px;
+  text-align: left;
+}
+
+th {
+  background-color: #f2f2f2;
+}
+
+.pagination {
+  margin-top: 20px;
+  text-align: center;
+}
+
+button {
+  margin: 0 5px;
+}
+</style>

+ 34 - 0
src/views/globalMap/RightMenu/UAV.vue

@@ -0,0 +1,34 @@
+<template>
+  <div class="gradient-text title">无人机资源</div>
+  <div class="flex-box">
+    <el-form-item style="width: 200px" label="行政区选择" prop="planType">
+      <el-select v-model="planForm.planType" placeholder="请选择" clearable>
+        <el-option v-for="item in plan_type" :key="item.value" :label="item.label" :value="item.value"></el-option>
+      </el-select>
+    </el-form-item>
+  </div>
+  <div class="custom-table">
+    <div class="th">
+      <div class="td">无人机名称</div>
+      <div class="td">
+        <span>类型</span>
+        <select>
+          <!-- 下拉框选项 -->
+          <option value="option1">选项1</option>
+          <option value="option2">选项2</option>
+        </select>
+      </div>
+    </div>
+    <div class="table-content">
+      <div v-for="(item, index) in riverMonitorData.listData" :key="index" class="tr" @click="handleShowDialog(item)">
+        <div class="td">{{ item.name }}</div>
+        <div class="td">{{ item.area }}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { validateNum } from "@/utils/ruoyi";
+import Dialog from "@/views/globalMap/RightMenu/Dialog.vue";
+</script>