Ver código fonte

事件简报界面

zhangyihao 5 meses atrás
pai
commit
3d69748444

+ 0 - 18
src/types/components.d.ts

@@ -21,7 +21,6 @@ declare module 'vue' {
     ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
     ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
     ElButton: typeof import('element-plus/es')['ElButton']
-    ElCard: typeof import('element-plus/es')['ElCard']
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElCol: typeof import('element-plus/es')['ElCol']
     ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
@@ -38,34 +37,22 @@ declare module 'vue' {
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
-    ElLink: typeof import('element-plus/es')['ElLink']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
-    ElPopover: typeof import('element-plus/es')['ElPopover']
-    ElRadio: typeof import('element-plus/es')['ElRadio']
-    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
     ElSkeletonItem: typeof import('element-plus/es')['ElSkeletonItem']
     ElSlider: typeof import('element-plus/es')['ElSlider']
-    ElStep: typeof import('element-plus/es')['ElStep']
-    ElSteps: typeof import('element-plus/es')['ElSteps']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
-    ElTable: typeof import('element-plus/es')['ElTable']
-    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
-    ElTabPane: typeof import('element-plus/es')['ElTabPane']
-    ElTabs: typeof import('element-plus/es')['ElTabs']
     ElText: typeof import('element-plus/es')['ElText']
     ElTimeline: typeof import('element-plus/es')['ElTimeline']
     ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
-    ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElTree: typeof import('element-plus/es')['ElTree']
-    ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']
     FooterSection: typeof import('./../components/FooterSection/index.vue')['default']
@@ -76,7 +63,6 @@ declare module 'vue' {
     HikvisionPlayer: typeof import('./../components/HKVideo/hikvision-player.vue')['default']
     HKVideo: typeof import('./../components/HKVideo/index.vue')['default']
     IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
-    IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default']
     IFrame: typeof import('./../components/iFrame/index.vue')['default']
     ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default']
     ImageUpload: typeof import('./../components/ImageUpload/index.vue')['default']
@@ -111,10 +97,6 @@ declare module 'vue' {
     VideoContainer2: typeof import('./../components/HKVideo/video-container2.vue')['default']
     VideoTagEdit: typeof import('./../components/VideoTagEdit/index.vue')['default']
     YMap: typeof import('./../components/Map/YMap.vue')['default']
-    YMapold: typeof import('./../components/Map/YMapold.vue')['default']
     YztMap: typeof import('./../components/Map/YztMap/index.vue')['default']
   }
-  export interface ComponentCustomProperties {
-    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
-  }
 }

+ 11 - 8
src/views/emergencyCommandMap/RightSection/RightTop.vue

@@ -43,6 +43,8 @@
       <div v-else-if="activeTab === '资源调度'" class="resource-scheduling">
         <div class="tip">暂无数据</div>
       </div>
+      <!-- 事件简报部分 -->
+      <ShiJianJieBao v-if="activeTab === '事件简报'" :event-id="eventId" />
     </div>
   </div>
 </template>
@@ -51,7 +53,7 @@
 import { ref, reactive } from 'vue';
 import { taskList } from '@/api/duty/eventing';
 import RenWuGenZong from '@/views/emergencyCommandMap/RightSection/RenWuGenZong.vue'; // 确保 eventing.ts 的路径正确
-
+import ShiJianJieBao from '@/views/emergencyCommandMap/RightSection/ShiJianJieBao.vue';
 const props = defineProps<{
   eventId?: string; // 使用可选属性
 }>();
@@ -60,14 +62,15 @@ const props = defineProps<{
 const tabs = reactive([
   { id: '任务跟踪', label: '任务跟踪' },
   { id: '预案通知', label: '预案通知' },
-  { id: '资源调度', label: '资源调度' }
+  { id: '资源调度', label: '资源调度' },
+  { id: '事件简报', label: '事件简报' }
 ]);
 
 const activeTab = ref('任务跟踪');
 
 const setActiveTab = (id) => {
   activeTab.value = id;
-  if(id === '预案通知') {
+  if (id === '预案通知') {
     fetchData();
   }
 };
@@ -113,13 +116,13 @@ const updateTaskList = (tasks) => {
 // 设置定时器
 const fetchInterval = process.env.NODE_ENV === 'development' ? 60000 : 1500; // 每60秒刷新一次(刷新太频繁影响调试)
 
-const nextFetchData = ()=> {
-  setTimeout(()=>{
-    if(notifications.value.length === 0) {
+const nextFetchData = () => {
+  setTimeout(() => {
+    if (notifications.value.length === 0) {
       fetchData();
     }
-  }, fetchInterval)
-}
+  }, fetchInterval);
+};
 
 watch(
   () => props.eventId,

+ 247 - 0
src/views/emergencyCommandMap/RightSection/ShiJianJieBao.vue

@@ -0,0 +1,247 @@
+<template>
+  <div class="table-content">
+    <div v-for="(item, index) in dataList" :key="index" class="box1">
+      <div class="box2">
+        <div class="box3">
+          <div class="box-header">
+            <div class="box-title">{{ item.name }}单位名称</div>
+            <div class="time">{{ item.update_time }}</div>
+          </div>
+          <div class="">
+            <div class="box-title">{{ item.content }}内容</div>
+          </div>
+          <div class="box-title">{{ item.feedback_content }}</div>
+          <div class="time">附件</div>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="more" @click="showMoreEventManageList">查看更多</div>
+
+  <!--弹窗-->
+  <ShiJianJieBaoInfo v-if="eventManageState.showListDialog" v-model="eventManageState.showListDialog" :event-id="eventId" />
+</template>
+
+<script lang="ts" setup>
+import { onMounted, ref, reactive } from 'vue';
+import { selectTask } from '@/api/emergencyCommandMap/JointDuty';
+import { parseTime } from '@/utils/ruoyi';
+import ShiJianJieBaoInfo from '@/views/emergencyCommandMap/RightSection/ShiJianJieBaoInfo.vue';
+
+// ref()创建一个响应式对象
+const dataList = ref([]);
+
+const props = defineProps<{
+  eventId?: string; // 使用可选属性
+}>();
+
+// 事件接报
+const eventManageState = reactive({
+  showListDialog: false
+});
+
+// 显示事件管理列表弹窗
+const showMoreEventManageList = () => {
+  eventManageState.showListDialog = true;
+};
+
+// 请求数据
+const fetchData = async () => {
+  try {
+    console.log('请求任务数据:', props.eventId);
+    const res = await selectTask({ event_code: props.eventId });
+    res.data.forEach((item) => {
+      item.update_time = parseTime(item.update_time);
+    });
+    dataList.value = res.data;
+  } catch (error) {
+    console.error('请求任务数据失败:', error);
+  }
+};
+
+// 设置定时器
+const fetchInterval = process.env.NODE_ENV === 'development' ? 60000 : 3000; // 每60秒刷新一次(刷新太频繁影响调试)
+let intervalId: any | null = null;
+
+const startFetchingData = () => {
+  if (!intervalId) {
+    intervalId = setInterval(() => {
+      fetchData();
+    }, fetchInterval);
+  }
+};
+
+const stopFetchingData = () => {
+  if (intervalId) {
+    clearInterval(intervalId);
+    intervalId = null;
+  }
+};
+
+// 在组件挂载时开始定时获取数据
+onMounted(() => {
+  if (props.eventId) {
+    fetchData();
+    startFetchingData();
+  }
+});
+
+// 在组件卸载时清除定时器
+onUnmounted(() => {
+  stopFetchingData();
+});
+
+watch(
+  () => props.eventId,
+  (newValue) => {
+    if (newValue) {
+      fetchData();
+      startFetchingData();
+    } else {
+      stopFetchingData();
+    }
+  },
+  { immediate: true }
+);
+</script>
+
+<style lang="scss" scoped>
+.table-content {
+  width: 100%;
+  height: 550px;
+  overflow-y: auto;
+  &.show-scroll {
+    overflow-y: auto;
+  }
+  .box1 {
+    width: 100%;
+    display: flex;
+    align-items: center;
+  }
+  .box2 {
+    width: 1642px;
+    min-height: 170px;
+    background-image: url('@/assets/images/taskTracking/box1.png');
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    background-position: bottom left;
+    padding: 20px 20px 20px 60px;
+    margin-top: 20px;
+    position: relative;
+    &:first-child {
+      margin-top: 0;
+    }
+  }
+  .box-header {
+    display: flex;
+    justify-content: space-between;
+    .header-left {
+      display: flex;
+      align-items: center;
+      .box-title {
+        font-size: 44px;
+        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;
+      }
+      .time {
+        font-size: 32px;
+        color: #00e8ff;
+        margin-left: 70px;
+      }
+    }
+    .success-bg,
+    .processing-bg,
+    .btn {
+      width: 154px;
+      height: 56px;
+      line-height: 56px;
+      font-size: 32px;
+      color: #ffffff;
+      border-radius: 10px;
+      text-align: center;
+      margin-left: 30px;
+    }
+    .btn {
+      background-color: #247dff;
+      cursor: pointer;
+    }
+  }
+  .box-content {
+    color: #fff;
+    font-size: 38px;
+    line-height: 98px;
+  }
+  .success-icon {
+    margin-right: -50px;
+    margin-top: 15px;
+    z-index: 1;
+    width: 123px;
+    height: 79px;
+    background: url('@/assets/images/taskTracking/success.png') no-repeat;
+  }
+  .processing-icon {
+    margin-right: -50px;
+    margin-top: 15px;
+    z-index: 1;
+    width: 123px;
+    min-width: 123px;
+    height: 79px;
+    background: url('@/assets/images/taskTracking/processing.png') no-repeat;
+  }
+}
+.more {
+  position: absolute;
+  bottom: 20px; /* 根据需要调整位置 */
+  right: 50%; /* 根据需要调整位置 */
+  transform: translateX(50%);
+  color: #1890ff;
+  cursor: pointer;
+}
+@keyframes slide {
+  0% {
+    transform: translateX(-100%);
+  }
+  80% {
+    transform: translateX(92px);
+  }
+  100% {
+    transform: translateX(0);
+  }
+}
+.box-box {
+  display: flex;
+  justify-content: space-between;
+
+  .header-left {
+    display: flex;
+    align-items: center;
+
+    .box-title {
+      font-size: 44px;
+      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;
+    }
+
+    .time {
+      font-size: 32px;
+      color: #00e8ff;
+      margin-left: 70px;
+    }
+    .people {
+      font-size: 32px;
+      color: #00e8ff;
+      margin-left: 70px;
+    }
+  }
+}
+</style>

+ 220 - 0
src/views/emergencyCommandMap/RightSection/ShiJianJieBaoInfo.vue

@@ -0,0 +1,220 @@
+<template>
+  <Dialog :hide-title="false" custom-show type="xl" title="事件简报列表" hide-footer @close="closeDialog">
+    <!-- 表格组件 -->
+    <div class="common-table">
+      <div class="table-header">
+        <div class="td">简报ID</div>
+        <div class="td">单位名称</div>
+        <div class="td">简报描述</div>
+        <div class="td">发布时间</div>
+        <div class="td">附件</div>
+      </div>
+      <div v-for="(item, index) in taskList" :key="index" class="tr">
+        <div class="td">{{ item.task_id }}</div>
+        <div class="td">{{ item.unit_name }}</div>
+        <div class="td">{{ item.task_description }}</div>
+        <div class="td">{{ formatDateTime(item.update_time) }}</div>
+        <div class="td">{{ item.picture }}</div>
+      </div>
+    </div>
+    <div class="footer">
+      <pagination
+        v-show="total > 0"
+        v-model:page="queryParams.page"
+        v-model:limit="queryParams.page_size"
+        :total="total"
+        layout="total, prev, pager, next"
+        @pagination="getList"
+      />
+    </div>
+  </Dialog>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive } from 'vue';
+import { selectTask } from '@/api/emergencyCommandMap/JointDuty';
+
+const taskList = ref([]);
+const total = ref(0);
+const queryParams = reactive({
+  page: 1,
+  page_size: 10,
+  task_id: '',
+  event_code: '',
+  sortBy: '',
+  sortOrder: ''
+});
+
+const getList = () => {
+  if (props.eventId) {
+    queryParams.event_code = props.eventId; // 使用 eventId
+  }
+
+  selectTask(queryParams).then((res) => {
+    if (res.code === 200) {
+      taskList.value = res.data;
+      total.value = res.total;
+    }
+  });
+};
+const formatDateTime = (dateTimeString: string) => {
+  const date = new Date(dateTimeString);
+  return date.toLocaleString();
+};
+// 选中的任务
+const props = defineProps<{
+  modelValue?: boolean;
+  title?: string;
+  height?: string;
+  eventId?: string;
+}>();
+const emit = defineEmits(['update:modelValue']);
+
+// 你可以在这里使用 props.eventId,例如在 fetchData 函数中:
+watch(
+  () => props.modelValue,
+  (newValue) => {
+    if (newValue) {
+      getList();
+    }
+  },
+  {
+    immediate: true
+  }
+);
+
+// 关闭弹窗
+const closeDialog = () => {
+  emit('update:modelValue', false);
+};
+</script>
+
+<style lang="scss" scoped>
+.dialog-wrap {
+  position: fixed;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+  z-index: 2000;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+  .overlay {
+    background-color: rgba(0, 0, 0, 0.5);
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    z-index: -1;
+    cursor: pointer;
+  }
+
+  .dialog {
+    width: 5000px;
+    height: 2000px;
+    margin: 0 auto;
+    background-color: #fff;
+    border-radius: 20px;
+  }
+}
+
+.dialog {
+  padding: 0 50px;
+
+  .dialog-header {
+    width: 100%;
+    height: 150px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .icon-close {
+      cursor: pointer;
+    }
+  }
+}
+
+.footer {
+  height: 64px;
+  display: flex;
+  justify-content: flex-end;
+  margin-bottom: 30px;
+
+  .pagination-container {
+    height: 64px;
+    margin: 0;
+  }
+
+  :deep(.el-pagination__total) {
+    color: #a7ccdf;
+    font-size: 32px;
+  }
+
+  :deep(.el-pagination) {
+    .btn-next,
+    .btn-prev {
+      background-color: transparent;
+      border: none;
+
+      .el-icon {
+        font-size: 22px;
+        color: #a7ccdf;
+      }
+    }
+
+    .btn-prev:disabled,
+    .btn-next:disabled {
+      background-color: transparent;
+      border: none;
+    }
+
+    .el-pager li {
+      width: 64px;
+      height: 64px;
+      line-height: 64px;
+      text-align: center;
+      font-size: 32px;
+      color: #a7ccdf;
+      background-color: #0e3064;
+      border: 1px solid #0c57a7;
+      margin: 0 6px;
+
+      &:hover {
+        background-color: #038dff;
+        border: 1px solid #038dff;
+      }
+    }
+
+    .el-pager li.is-active {
+      background-color: #038dff;
+      border: 1px solid #038dff;
+    }
+  }
+}
+
+.flex {
+  display: flex;
+  align-items: flex-start;
+}
+.success-bg,
+.processing-bg,
+.btn {
+  width: 154px;
+  height: 56px;
+  line-height: 56px;
+  font-size: 32px;
+  color: #ffffff;
+  border-radius: 10px;
+  text-align: center;
+  margin-left: 30px;
+}
+.btn {
+  background-color: #247dff;
+  cursor: pointer;
+}
+</style>