瀏覽代碼

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

hmm 9 月之前
父節點
當前提交
75e8c5cdf4

+ 1 - 1
.env.development

@@ -5,7 +5,7 @@ VITE_APP_TITLE = 应急指挥一张图
 VITE_APP_ENV = 'development'
 
 # 开发环境
-VITE_APP_BASE_API = 'http://10.181.7.235'
+VITE_APP_BASE_API = 'http://10.181.7.236:9988'
 VITE_APP_BASE_API2 = 'http://10.181.7.235/'
 
 # 应用访问路径 例如使用前缀 /admin/

+ 20 - 4
src/views/emergencyCommandMap/RightSection/RenWuDengJi.vue

@@ -9,14 +9,18 @@
       <div class="dialog-body">
         <div class="form-group">
           <label>任务内容:</label>
-          <textarea v-model="newTask.description" placeholder="请输入相关任务描述"></textarea>
+          <!--          <textarea v-model="newTask.description" placeholder="请输入相关任务描述"></textarea>-->
+          <el-input v-model="newTask.description" style="font-size: 36px; width: 100%" :rows="1" type="textarea" placeholder="请输入相关任务描述" />
         </div>
         <div class="form-group">
           <label>执行单位:</label>
-          <select v-model="newTask.unit">
+          <!--          <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>
+          </select>-->
+          <el-select v-model="newTask.unit" placeholder="请选择执行单位" class="custom-el-select" style="width: 100%">
+            <el-option v-for="unit in units" :key="unit.value" :label="unit.label" :value="unit.value" />
+          </el-select>
         </div>
         <div class="form-group">
           <label>登记人:</label>
@@ -87,7 +91,7 @@ onMounted(() => {
 });
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
 .dialog {
   position: fixed;
   top: 50%;
@@ -129,6 +133,7 @@ button {
   color: white;
   border-radius: 4px;
   cursor: pointer;
+  font-size: 36px;
 }
 
 button:hover {
@@ -144,5 +149,16 @@ input[type='text'] {
   margin-top: 5px;
   border-radius: 4px;
   border: 1px solid #ccc;
+  font-size: 36px;
+}
+.custom-el-select {
+  :deep(.el-select__wrapper) {
+    height: 60px; // 根据你的字体大小适配高度
+    line-height: 60px; // 保持与高度一致
+    font-size: 36px;
+  }
+  :deep(.el-select__placeholder) {
+    font-size: 36px;
+  }
 }
 </style>

+ 69 - 34
src/views/emergencyCommandMap/RightSection/RenWuGenZong.vue

@@ -1,63 +1,85 @@
 <template>
-  <div class="table-content">
-    <div v-for="(item, index) in dataList" :key="index" class="box1">
-      <div :class="item.processing_status === '已完成' ? 'success-icon' : 'processing-icon'"></div>
-      <div class="box2">
-        <div class="box-header">
-          <div class="header-left">
-            <div class="box-title">{{ item.unit_name }}</div>
-            <div class="time">{{ item.update_time }}</div>
-            <div :class="item.processing_status === '已完成' ? 'success' : 'processing'">{{ item.processing_status }}</div>
+  <div>
+    <div class="table-content" :class="{ 'show-scroll': showScroll }">
+      <div v-for="(item, index) in dataList" :key="index" class="box1">
+        <div :class="item.processing_status === '已完成' ? 'success-icon' : 'processing-icon'"></div>
+        <div class="box2">
+          <div class="box-header">
+            <div class="header-left">
+              <div class="box-title">{{ item.unit_name }}</div>
+              <div class="time">{{ item.update_time }}</div>
+              <div :class="item.processing_status === '已完成' ? 'success' : 'processing'">{{ item.processing_status }}</div>
+            </div>
+            <div class="btn" @click="openUpdateDialog(item)">更新</div>
           </div>
-          <div class="btn" @click="updateTask">更新</div>
+          <div class="box-content">{{ item.task_description }}</div>
         </div>
-        <div class="box-content">{{ item.task_description }}</div>
       </div>
     </div>
+    <button @click="toggleScroll" class="toggle-scroll-btn">{{ showScroll ? '收起' : '查看更多 >>' }}</button>
   </div>
+
+  <RenWuTanChuan
+    v-model="newSectionState.showListDialog"
+    :task="selectedTask"
+    @update-success="handleUpdateSuccess"
+    title="任务进度更新"
+    width="70%"
+  />
 </template>
 
 <script lang="ts" setup>
-import { onMounted, ref } from 'vue';
-import { selectTask, updateTaskRegistration } from '@/api/emergencyCommandMap/JointDuty';
+import { onMounted, ref, reactive } from 'vue';
+import { selectTask } from '@/api/emergencyCommandMap/JointDuty';
 import { parseTime } from '@/utils/ruoyi';
+import RenWuTanChuan from '@/views/emergencyCommandMap/RightSection/RenWuTanChuan.vue';
+
+const newSectionState = reactive({
+  showListDialog: false,
+});
+
+const selectedTask = ref({
+  id: '',
+  description: '',
+  registrar: '',
+  progress: ''
+});
+
+const dataList = ref([]);
+const showScroll = ref(false);
 
 const props = defineProps<{
   eventId?: string; // 使用可选属性
 }>();
 
-const dataList = ref([]);
-
 // 请求数据
 const fetchData = async () => {
-  selectTask({ eventId: props.eventId }).then((res) => {
+  try {
+    const res = await selectTask({ eventId: props.eventId });
     res.data.forEach((item) => {
       item.update_time = parseTime(item.update_time);
     });
     dataList.value = res.data;
-  });
+  } catch (error) {
+    console.error('请求任务数据失败:', error);
+  }
 };
 
-// 更新任务
-const updateTask = async (index) => {
-  try {
-    const task = dataList.value[index];
-    const response = await updateTaskRegistration(task);
+const openUpdateDialog = (task) => {
+  selectedTask.value = { ...task };
+  newSectionState.showListDialog = true;
+};
 
-    if (response.code === 200) {
-      console.log('任务更新成功');
-      fetchData(); // 重新加载任务列表
-    } else {
-      console.error('任务更新失败:', response.msg);
-    }
-  } catch (error) {
-    console.error('请求任务更新失败:', error);
-  }
+const handleUpdateSuccess = (updatedData) => {
+  console.log('任务进度更新成功:', updatedData);
+  fetchData(); // 重新加载任务列表
+};
+
+const toggleScroll = () => {
+  showScroll.value = !showScroll.value;
 };
 
-// 在组件挂载时获取数据
 onMounted(() => {
-  console.log('Mounting RightTop component');
   if (props.eventId) {
     fetchData();
   } else {
@@ -69,7 +91,10 @@ onMounted(() => {
 <style lang="scss" scoped>
 .table-content {
   height: 600px;
-  overflow-y: auto;
+  overflow-y: hidden;
+  &.show-scroll {
+    overflow-y: auto;
+  }
   .box1 {
     display: flex;
     align-items: center;
@@ -154,4 +179,14 @@ onMounted(() => {
     background: url('@/assets/images/taskTracking/processing.png') no-repeat;
   }
 }
+
+.toggle-scroll-btn {
+  display: block;
+  margin: 20px auto;
+  font-size: 36px;
+  color: #3498db;
+  background: none;
+  border: none;
+  cursor: pointer;
+}
 </style>

+ 100 - 107
src/views/emergencyCommandMap/RightSection/RenWuTanChuan.vue

@@ -1,141 +1,134 @@
 <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>
+  <Dialog v-model="visible" title="任务进度更新" width="70%">
+    <div class="dialog-content">
+      <div class="form-group">
+        <label>任务描述:</label>
+        <input v-model="task.description" type="text" readonly />
       </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 class="form-group">
+        <label>执行单位:</label>
+        <input v-model="task.registrar" type="text" readonly />
       </div>
+      <div class="form-group">
+        <label>完成进度:</label>
+        <select v-model="task.progress">
+          <option value="" disabled>请选择进度</option>
+          <option v-for="unit in units" :key="unit" :value="unit">{{ unit }}</option>
+        </select>
+        <span v-if="!isFormValid" class="error-message">请选择完成进度</span>
+      </div>
+    </div>
+    <div class="dialog-footer">
+      <button @click="confirmRegister" :disabled="!isFormValid">确定</button>
+      <button @click="closeDialog">取消</button>
     </div>
-  </div>
+  </Dialog>
 </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);
+import { defineProps, defineEmits, reactive, watch, computed } from 'vue';
+import Dialog from '@/components/Dialog/index.vue';
+import { updateTaskRegistration } from '@/api/emergencyCommandMap/JointDuty.ts';
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    required: true
+  },
+  task: {
+    type: Object,
+    default: () => ({
+      id: '',
+      description: '',
+      registrar: '',
+      progress: ''
+    })
+  }
+});
 
-const totalPages = computed(() => Math.ceil(tasks.value.length / pageSize.value));
+const emit = defineEmits(['update:modelValue', 'update-success']);
 
-const paginatedTasks = computed(() => {
-  const start = (currentPage.value - 1) * pageSize.value;
-  const end = start + pageSize.value;
-  return tasks.value.slice(start, end);
+const visible = computed({
+  get: () => props.modelValue,
+  set: (val) => emit('update:modelValue', val)
 });
-const closeModal = () => {
-  showModal.value = false;
-};
 
-const prevPage = () => {
-  if (currentPage.value > 1) {
-    currentPage.value--;
-  }
-};
+const task = reactive({ ...props.task });
 
-const nextPage = () => {
-  if (currentPage.value < totalPages.value) {
-    currentPage.value++;
+watch(
+  () => props.task,
+  (newTask) => {
+    Object.assign(task, newTask);
   }
+);
+
+const units = ['已处理', '已完成'];
+
+const isFormValid = computed(() => {
+  return task.progress !== '';
+});
+
+const closeDialog = () => {
+  visible.value = false;
 };
 
-const fetchTasks = async () => {
+const confirmRegister = async () => {
   try {
-    const response = await selectTask();
+    const response = await updateTaskRegistration({
+      id: task.id,
+      description: task.description,
+      registrar: task.registrar,
+      processing_status: task.progress
+    });
     if (response.code === 200) {
-      tasks.value = response.data;
+      console.log('任务进度更新成功');
+      emit('update-success', response.data);
+      closeDialog();
     } else {
-      console.error('获取任务数据失败:', response.msg);
+      console.error('任务进度更新失败:', response.msg);
     }
   } catch (error) {
-    console.error('请求任务数据失败:', 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;
+.dialog-content {
   padding: 20px;
-  border-radius: 8px;
-  width: 80%;
-  max-width: 800px;
 }
-
-.modal-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 20px;
+.form-group {
+  margin-bottom: 15px;
 }
-
-table {
-  width: 100%;
-  border-collapse: collapse;
+.dialog-footer {
+  display: flex;
+  justify-content: flex-end;
+  padding: 10px;
 }
-
-th,
-td {
-  border: 1px solid #ddd;
-  padding: 8px;
-  text-align: left;
+button {
+  margin-left: 10px;
+  padding: 5px 15px;
+  border: none;
+  background-color: #3498db;
+  color: white;
+  border-radius: 4px;
+  cursor: pointer;
 }
-
-th {
-  background-color: #f2f2f2;
+button:hover {
+  background-color: #2980b9;
 }
-
-.pagination {
-  margin-top: 20px;
-  text-align: center;
+textarea,
+select,
+input[type='text'] {
+  width: 100%;
+  box-sizing: border-box;
+  padding: 5px;
+  margin-top: 5px;
+  border-radius: 4px;
+  border: 1px solid #ccc;
 }
-
-button {
-  margin: 0 5px;
+.error-message {
+  color: red;
+  font-size: 14px;
 }
 </style>

+ 134 - 43
src/views/emergencyCommandMap/RightSection/RightTop.vue

@@ -7,23 +7,41 @@
       </li>
     </ul>
     <div class="card-content">
-      <RenWuGenZong v-if="activeTab === '任务跟踪'" :eventId="eventId" />
-      <div v-else-if="activeTab === '预案通知'" class="custom-table">
+      <!-- 任务跟踪部分 -->
+      <RenWuGenZong v-if="activeTab === '任务跟踪'" :event-id="eventId" />
+
+      <!-- 预案通知部分修改为卡片式布局 -->
+      <div v-else-if="activeTab === '预案通知'" class="preplan-notification">
         <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', { error: notification.status === '发送失败', success: notification.status === '已发送' }]">
-                  {{ notification.status === '发送失败' ? '发送失败' : `接收人:${notification.receiver}` }}
-                </span>
+          <div v-for="(notification, index) in notifications" :key="index" class="box1">
+            <div :class="notification.status === '发送失败' ? 'error-icon' : 'success-icon'"></div>
+            <div class="box2">
+              <div class="box-header">
+                <div class="header-left">
+                  <div class="box-title">{{ notification.unit }}</div>
+                  <div class="time">{{ notification.date }}</div>
+                  <div :class="notification.status === '发送失败' ? 'status error' : 'status success'">
+                    {{ notification.status === '发送失败' ? '发送失败' : `接收人:${notification.receiver}` }}
+                  </div>
+                </div>
+                <!-- 如果需要更新按钮,可以取消注释以下代码 -->
+                <!--
+                <div class="btn" @click="openUpdateDialog(notification)">
+                  更新
+                </div>
+                -->
               </div>
-              <div class="content">{{ notification.content }}</div>
+              <div class="box-content">{{ notification.content }}</div>
             </div>
           </div>
         </div>
       </div>
+
+      <!-- 资源调度部分保持不变 -->
+      <div v-else-if="activeTab === '资源调度'" class="resource-scheduling">
+        <!-- 资源调度内容,可以根据需要进行填充 -->
+        <p>资源调度内容正在开发中...</p>
+      </div>
     </div>
   </div>
 </template>
@@ -67,10 +85,10 @@ const fetchData = async () => {
     const response = await taskList({ eventId: props.eventId });
 
     if (response.code === 200) {
-      console.log('查询成功:', response.data);
+      console.log('查询成功预案:', response.data);
       updateTaskList(response.data);
     } else {
-      console.error('查询失败:', response.msg);
+      console.error('预案查询失败:', response.msg);
     }
   } catch (error) {
     console.error('请求失败:', error);
@@ -106,9 +124,11 @@ onMounted(() => {
   padding: 0;
   margin-left: 80px;
   margin-top: 75px;
+
   .active {
     background: url('@/assets/images/emergencyCommandMap/tabActive.png') no-repeat;
   }
+
   li {
     cursor: pointer;
     padding: 20px;
@@ -121,54 +141,114 @@ onMounted(() => {
     justify-content: center;
     align-items: flex-end;
     font-family: YouSheBiaoTiHei;
+
     &:hover {
       background: url('@/assets/images/emergencyCommandMap/tabActive.png') no-repeat;
     }
   }
 }
 
-.custom-table {
+.preplan-notification {
   width: 100%;
+
   .table-content {
     height: 600px;
     overflow-y: auto;
-    .tr {
+
+    .box1 {
       display: flex;
-      align-items: center;
-      .td {
+      align-items: flex-start;
+      margin-bottom: 20px;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+
+      .success-icon,
+      .error-icon {
+        width: 123px;
+        height: 79px;
+        background-repeat: no-repeat;
+        background-size: contain;
+        margin-right: 20px;
+      }
+
+      .success-icon {
+        background-image: url('@/assets/images/taskTracking/success.png');
+      }
+
+      .error-icon {
+        background-image: url('@/assets/images/taskTracking/processing.png');
+      }
+
+      .box2 {
         flex: 1;
-        padding: 10px;
-        font-size: 36px;
-        .unit-date {
+        background-image: url('@/assets/images/taskTracking/box1.png');
+        background-repeat: no-repeat;
+        background-size: 100% 377px; /* 适应容器宽度 */
+        padding: 20px 60px 20px 20px;
+        position: relative;
+
+        .box-header {
           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; /* 发送失败时使用红色 */
+          justify-content: space-between;
+          align-items: center;
+
+          .header-left {
+            display: flex;
+            align-items: center;
+
+            .box-title {
+              font-size: 38px;
+              font-family: YouSheBiaoTiHei;
+              color: #ffffff;
+              background-image: url('@/assets/images/taskTracking/titleBox.png');
+              background-repeat: no-repeat;
+              background-size: 311px 56px;
+              background-position: bottom left;
+              padding-left: 50px;
             }
-            &.success {
-              color: #fff; /* 发送成功时使用黑色 */
+
+            .time {
+              font-size: 32px;
+              color: #00e8ff;
+              margin-left: 70px;
             }
           }
+
+          .status {
+            width: 154px;
+            height: 56px;
+            line-height: 56px;
+            font-size: 32px;
+            color: #ffffff;
+            border-radius: 10px;
+            text-align: center;
+            margin-left: 30px;
+          }
+
+          .success {
+            background-color: #38c95a;
+          }
+
+          .error {
+            background-color: #ff4d4f;
+          }
+
+          /* 如果需要更新按钮,可以添加样式 */
+          /*
+          .btn {
+            background-color: #247dff;
+            cursor: pointer;
+          }
+          */
         }
-        .content {
+
+        .box-content {
+          color: #fff;
+          font-size: 38px;
+          line-height: 1.5;
           margin-top: 10px;
-          font-size: 36px; /* 内容字体大小 */
-          line-height: 1.5; /* 增加行高以适应较大的字体 */
         }
       }
     }
@@ -181,6 +261,7 @@ onMounted(() => {
   background: url('@/assets/images/commandDynamic/dialog.png') no-repeat;
   position: relative;
   color: #fff;
+
   .card-content {
     display: flex;
     flex-wrap: wrap;
@@ -188,10 +269,20 @@ onMounted(() => {
     width: 2500px;
   }
 }
+
 .title {
   position: absolute;
   top: 6px;
   left: 141px;
   font-size: 60px;
 }
+
+.resource-scheduling {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 36px;
+  color: #fff;
+}
 </style>