Procházet zdrojové kódy

工作人员端首页

lizhouming před 10 měsíci
rodič
revize
a1fe34dc4a

+ 37 - 30
src/api/emergencyCommandMap/JointDuty.ts

@@ -1,22 +1,24 @@
-import request from '@/utils/request';
-import CryptoJS from 'crypto-js';
-import { nanoid } from 'nanoid';
+import request from "@/utils/request";
+import CryptoJS from "crypto-js";
+import { nanoid } from "nanoid";
 
 // 二维码
-export const getMapProduct = (data) => {
+export const getMapProduct = data => {
   const nonce = nanoid();
   const timestampHeader = (Date.now() / 1000).toFixed();
-  const token = 'dsfsdfsdfsf';
-  const signatureHeader = CryptoJS.SHA256(timestampHeader + token + nonce + timestampHeader).toString(CryptoJS.enc.Hex);
+  const token = "dsfsdfsdfsf";
+  const signatureHeader = CryptoJS.SHA256(
+    timestampHeader + token + nonce + timestampHeader
+  ).toString(CryptoJS.enc.Hex);
   return request({
-    url: 'https://yzh.gdgov.cn/yzm-generator/generateCode',
-    method: 'POST',
+    url: "https://yzh.gdgov.cn/yzm-generator/generateCode",
+    method: "POST",
     headers: {
-      'x-yzm-nonce': nonce,
-      'x-yzm-signature': signatureHeader,
-      'x-yzm-paasid': token,
-      'x-yzm-timestamp': timestampHeader,
-      'Content-Type': 'application/json;charset=utf-8'
+      "x-yzm-nonce": nonce,
+      "x-yzm-signature": signatureHeader,
+      "x-yzm-paasid": token,
+      "x-yzm-timestamp": timestampHeader,
+      "Content-Type": "application/json;charset=utf-8"
     },
     data: {
       id: data.id,
@@ -30,8 +32,8 @@ export const getMapProduct = (data) => {
 // 获取签名列表
 export function getCheckinList(eventId: string) {
   return request({
-    url: '/api/event_management/checkin/list',
-    method: 'get',
+    url: "/api/event_management/checkin/list",
+    method: "get",
     params: {
       event_id: eventId
     }
@@ -39,10 +41,15 @@ export function getCheckinList(eventId: string) {
 }
 
 // 更新事发地点 (用于将表单数据发送到服务器以更新某个事件的位置信息)
-export function updateEventLocation(eventId: string, address: string, longitude: string, latitude: string) {
+export function updateEventLocation(
+  eventId: string,
+  address: string,
+  longitude: string,
+  latitude: string
+) {
   return request({
-    url: '/api/event_management/event/save_address',
-    method: 'post',
+    url: "/api/event_management/event/save_address",
+    method: "post",
     params: {
       eventId: eventId,
       address: address,
@@ -55,32 +62,32 @@ export function updateEventLocation(eventId: string, address: string, longitude:
 // 新建事件
 export function addEvent(data) {
   return request({
-    url: '/api/event_management/event/create',
-    method: 'post',
+    url: "/api/event_management/event/create",
+    method: "post",
     data: data
   });
 }
 // 任务新增
 export function addTask(data) {
   return request({
-    url: '/api/taskRegistration/create',
-    method: 'post',
+    url: "/api/taskRegistration/create",
+    method: "post",
     data: data
   });
 }
 // 任务查询
 export function selectTask(params) {
   return request({
-    url: '/api/taskRegistration/select',
-    method: 'get',
+    url: "/api/taskRegistration/select",
+    method: "get",
     params: params
   });
 }
 // 任务更新
 export function updateTaskRegistration(data) {
   return request({
-    url: '/api/taskRegistration/update',
-    method: 'put',
+    url: "/api/taskRegistration/update",
+    method: "put",
     data: data
   });
 }
@@ -88,8 +95,8 @@ export function updateTaskRegistration(data) {
 // 查看事业单位
 export function getUnits(params) {
   return request({
-    url: '/api/taskRegistration/selectUnit',
-    method: 'get',
+    url: "/api/taskRegistration/selectUnit",
+    method: "get",
     params: params
   });
 }
@@ -97,8 +104,8 @@ export function getUnits(params) {
 // 任务删除
 export function deleteTask(data) {
   return request({
-    url: '/api/taskRegistration/delete',
-    method: 'post',
+    url: "/api/taskRegistration/delete",
+    method: "post",
     data: data
   });
 }

+ 26 - 7
src/router/routes.ts

@@ -98,7 +98,8 @@ const routes: Array<RouteRecordRaw> = [
   {
     path: "/districtCountyRollCall",
     name: "DistrictCountyRollCall",
-    component: () => import("@/views/onlineRollCall/districtCountyRollCall.vue"),
+    component: () =>
+      import("@/views/onlineRollCall/districtCountyRollCall.vue"),
     meta: {
       title: "分区县点名",
       noCache: true
@@ -126,14 +127,32 @@ const routes: Array<RouteRecordRaw> = [
     path: "/worker",
     name: "Worker",
     component: Layout,
-    redirect: { name: "WokerIndex" },
+    redirect: { name: "WorkerIndex" },
     children: [
       {
         path: "index2",
-        name: "WokerIndex",
+        name: "WorkerIndex",
         component: () => import("@/views/worker/index.vue"),
         meta: {
-          title: "主页3"
+          title: "首页"
+        }
+      },
+      {
+        path: "event",
+        name: "Event",
+        component: () => import("@/views/event/detail.vue"),
+        meta: {
+          title: "事件管理",
+          noCache: true
+        }
+      },
+      {
+        path: "duty",
+        name: "DutyIndex",
+        component: () => import("@/views/duty/index.vue"),
+        meta: {
+          title: "值班管理",
+          noCache: true
         }
       },
       {
@@ -141,7 +160,7 @@ const routes: Array<RouteRecordRaw> = [
         name: "About",
         component: () => import("@/views/about/index.vue"),
         meta: {
-          title: "关于3",
+          title: "我的",
           noCache: true
         }
       }
@@ -181,11 +200,11 @@ const routes: Array<RouteRecordRaw> = [
     }
   },
   {
-    path: "/InformationReception/index",
+    path: "/InformationReception",
     name: "InformationReception",
     component: () => import("@/views/InformationReception/index.vue"),
     meta: {
-      title: "信息接报"
+      title: "信息发布"
     }
   }
 ];

+ 10 - 3
src/views/InformationReception/index.vue

@@ -52,7 +52,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, onMounted, reactive } from "vue";
+import { ref, onMounted, reactive, onUnmounted, watch } from "vue";
 import { selectTask } from "@/api/emergencyCommandMap/JointDuty";
 import { parseTime } from "@/utils/ruoyi";
 
@@ -65,7 +65,8 @@ const selectedTask = ref({
   task_id: "",
   sortBy: "creation_time",
   pageNum: 2,
-  pageSize: 20
+  pageSize: 20,
+  event_code: "YJSJ0000000001"
 });
 // ref()创建一个响应式对象
 const dataList = ref([]);
@@ -84,7 +85,13 @@ const eventManageState = reactive({
 const fetchData = async () => {
   try {
     console.log("请求任务数据:", props.eventId);
-    const res = await selectTask({ event_code: props.eventId });
+    // 构建请求参数对象
+    const params = {
+      event_code: selectedTask.value.event_code, // 确保这里的 props.eventId 是字符串类型,如果是数字类型需要转换为字符串
+      sortOrder: sortOrder.value, // 假设 sortOrder 是响应式的
+      sortBy: selectedTask.value.sortBy // 假设 sortBy 是 selectedTask 的一个属性
+    };
+    const res = await selectTask(params); // 确保 selectTask 函数正确处理了这些参数
     res.data.forEach(item => {
       item.update_time = parseTime(item.update_time);
       item.statusClass = getStatusClass(item.status);

+ 5 - 0
src/views/duty/index.vue

@@ -0,0 +1,5 @@
+<script setup lang="ts" name="About"></script>
+
+<template>
+  <div>值班管理</div>
+</template>

+ 111 - 122
src/views/leader/index.vue

@@ -3,25 +3,29 @@
     <div class="container-header">
       <div ref="searchBoxRef" class="search-box">
         <van-search
-            v-model="queryParams.keywords"
-            class="common-search"
-            :left-icon="searchImg"
-            :right-icon="closeImg"
-            placeholder="请输入搜索内容"
-            @search="on_search_keyword"
-            @click-right-icon.stop="on_search_cancel"
+          v-model="queryParams.keywords"
+          class="common-search"
+          :left-icon="searchImg"
+          :right-icon="closeImg"
+          placeholder="请输入搜索内容"
+          @search="on_search_keyword"
         />
         <div v-show="showSearch" class="search-list">
           <van-list
-              v-model:loading="loading"
-              v-model:error="error"
-              error-text="请求失败,点击重新加载"
-              :finished="finished"
-              finished-text="没有更多了"
-              :immediate-check="false"
-              @load="getSearchList"
+            v-model:loading="loading"
+            v-model:error="error"
+            error-text="请求失败,点击重新加载"
+            :finished="finished"
+            finished-text="没有更多事件了"
+            :immediate-check="false"
+            @load="getSearchList"
           >
-            <div v-for="(item, index) in searchList" :key="index" class="item" @click="handleClickItem(item)">
+            <div
+              v-for="(item, index) in searchList"
+              :key="index"
+              class="item"
+              @click="handleClickItem(item)"
+            >
               {{ item.name }}
             </div>
           </van-list>
@@ -30,19 +34,23 @@
     </div>
     <div class="container-content">
       <van-notice-bar
-          @click="handleNoticeBar"
-          v-show="noticeBarState.show"
-          :left-icon="noticeImg"
-          scrollable
-          background="linear-gradient(180deg, #F3F7FF 0%, #FDFEFF 100%)"
-          mode="closeable"
-          :text="noticeBarState.event_title"
+        v-show="noticeBarState.show"
+        :left-icon="noticeImg"
+        scrollable
+        background="linear-gradient(180deg, #F3F7FF 0%, #FDFEFF 100%)"
+        mode="closeable"
+        :text="noticeBarState.event_title"
+        @click="handleNoticeBar"
       />
       <div class="padding-content">
         <van-grid :column-num="2">
-          <van-grid-item v-for="(item, index) in menu" :key="index" @click="handleClickMenu(item.url)">
+          <van-grid-item
+            v-for="(item, index) in menu"
+            :key="index"
+            @click="handleClickMenu(item.url)"
+          >
             <div class="card">
-              <div :class="item.icon"></div>
+              <div :class="item.icon" />
               <van-badge :content="item.num" max="99" :show-zero="false">
                 <div class="card-title">{{ item.name }}</div>
               </van-badge>
@@ -54,7 +62,12 @@
           <div v-for="(item, index) in menu2" :key="index" class="box">
             <div class="box-title">{{ item.name }}</div>
             <div class="box-content">
-              <div v-for="(item2, index2) in item.children" :key="index2" class="box-item"  @click="handleClickMenu(item.url)">
+              <div
+                v-for="(item2, index2) in item.children"
+                :key="index2"
+                class="box-item"
+                @click="handleClickMenu(item.url)"
+              >
                 <img class="icon" :src="getImageUrl(item2.icon)" alt="" />
                 <span>{{ item2.name }}</span>
               </div>
@@ -67,73 +80,73 @@
 </template>
 
 <script lang="ts" setup>
-import {onClickOutside} from "@vueuse/core";
-import { ref, reactive, onMounted } from 'vue';
+import { onClickOutside } from "@vueuse/core";
+import { ref, reactive, onMounted } from "vue";
 import { getActiveEventList } from "@/api/event";
-import noticeImg from '@/assets/images/notice.png'
-import searchImg from '@/assets/images/search.png'
-import {useRouter} from "vue-router";
+import noticeImg from "@/assets/images/notice.png";
+import searchImg from "@/assets/images/search.png";
+import { useRouter } from "vue-router";
 import closeImg from "@/assets/images/close.png";
-import {getPointInfoComprehensiveSearch} from "@/api/globalMap";
+import { getPointInfoComprehensiveSearch } from "@/api/globalMap";
 
 const router = useRouter();
 const noticeBarState = reactive({
   show: false,
-  event_id: '',
-  event_title: ''
-})
+  event_id: "",
+  event_title: ""
+});
 
 const handleNoticeBar = () => {
   console.log(noticeBarState.event_title);
-}
+};
 // 菜单数据
 const menu = ref([
-  { name: '工作审批', icon: 'icon1', num: 0, url: '' },
-  { name: '信息接报', icon: 'icon2', num: 0, url: '' },
-  { name: '在线点名', icon: 'icon3', num: 0, url: 'OnlineRollCall' },
-  { name: '事件管理', icon: 'icon4', num: 0, url: 'EventList' },
+  { name: "工作审批", icon: "icon1", num: 0, url: "" },
+  { name: "信息接报", icon: "icon2", num: 0, url: "InformationReception" },
+  { name: "在线点名", icon: "icon3", num: 0, url: "" },
+  { name: "事件管理", icon: "icon4", num: 0, url: "EventList" }
 ]);
 
 // 综合应用菜单
 const menu2 = ref([
   {
-    name: '自然灾害风险监测',
+    name: "自然灾害风险监测",
     children: [
-      { name: '灾害监测', icon: 'monitor', url: '' },
-      { name: '大风灾害', icon: 'wind', url: '' },
-      { name: '森林火灾', icon: 'forestFire', url: '' },
-      { name: '台风实况', icon: 'typhoon', url: '' },
-      { name: '水文监测', icon: 'hydrology', url: '' }
+      { name: "灾害监测", icon: "monitor", url: "" },
+      { name: "大风灾害", icon: "wind", url: "" },
+      { name: "森林火灾", icon: "forestFire", url: "" },
+      { name: "台风实况", icon: "typhoon", url: "" },
+      { name: "水文监测", icon: "hydrology", url: "" }
     ]
   },
   {
-    name: '应急事件场景专题',
+    name: "应急事件场景专题",
     children: [
-      { name: '自然灾害', icon: 'nature', url: '' },
-      { name: '事故灾害', icon: 'accident', url: '' },
-      { name: '城市事件', icon: 'city', url: '' }
+      { name: "自然灾害", icon: "nature", url: "" },
+      { name: "事故灾害", icon: "accident", url: "" },
+      { name: "城市事件", icon: "city", url: "" }
     ]
   }
-])
-const handleClickMenu = (url) => {
+]);
+const handleClickMenu = url => {
   if (!url) return;
   router.push({ name: url });
-}
-const getImageUrl = (name) => {
+};
+const getImageUrl = name => {
   return new URL(`../../assets/images/index/${name}.png`, import.meta.url).href;
 };
 
 const initData = () => {
   // 通知栏数据
-  getActiveEventList().then((res) => {
-    if(res.data.event_id != noticeBarState.event_id) {
-      noticeBarState.show = true
+  getActiveEventList().then(res => {
+    if (res.data.event_id != noticeBarState.event_id) {
+      noticeBarState.show = true;
       noticeBarState.event_id = res.data.event_id;
       noticeBarState.event_title = res.data.event_title;
     }
-  })
+  });
   // 菜单数据
-}
+};
 // 搜索
 const searchBoxRef = ref();
 let showSearch = ref();
@@ -144,61 +157,57 @@ let finished = ref(false);
 const queryParams = reactive({
   page: 0,
   page_size: 15,
-  keywords: ''
+  keywords: ""
 });
 const searchList = ref([]);
-onClickOutside(searchBoxRef, (event) => {
+onClickOutside(searchBoxRef, event => {
   showSearch.value = false;
-})
+});
 const getSearchList = () => {
-  if (!queryParams.keywords){
-    return loading.value = false;
+  if (!queryParams.keywords) {
+    return (loading.value = false);
   }
   queryParams.page++;
-  getPointInfoComprehensiveSearch(queryParams).then((res) => {
-    const items = res.data.list || [];
-    total.value = res.data.total;
-    if (queryParams.page == 1) {
-      searchList.value = [];
-    }
-    items.forEach((val) => {
-      searchList.value.push(val)
-    });
-    if (queryParams.page_size * queryParams.page >= total.value) {
-      finished.value = true;
-    } else {
+  getPointInfoComprehensiveSearch(queryParams)
+    .then(res => {
+      const items = res.data.list || [];
+      total.value = res.data.total;
+      if (queryParams.page == 1) {
+        searchList.value = [];
+      }
+      items.forEach(val => {
+        searchList.value.push(val);
+      });
+      if (queryParams.page_size * queryParams.page >= total.value) {
+        finished.value = true;
+      } else {
+        finished.value = false;
+      }
+      showSearch.value = true;
+    })
+    .catch(() => {
+      error.value = true;
       finished.value = false;
-    }
-    showSearch.value = true;
-  }).catch(() => {
-    error.value = true;
-    finished.value = false;
-  }).finally(() => {
-    loading.value = false;
-  });
-}
-const on_search_keyword = (val) => {
+    })
+    .finally(() => {
+      loading.value = false;
+    });
+};
+const on_search_keyword = val => {
   queryParams.keywords = val;
   queryParams.page = 0;
   getSearchList();
-}
-const on_search_cancel = () => {
-  showSearch.value = false;
-  queryParams.keywords = '';
-  queryParams.page = 0;
-  finished.value = false;
-  searchList.value = [];
-}
-const handleClickItem = (item) => {
+};
+const handleClickItem = item => {
   showSearch.value = false;
-  queryParams.keywords = '';
+  queryParams.keywords = "";
   queryParams.page = 0;
   finished.value = false;
   searchList.value = [];
-}
+};
 onMounted(() => {
-  initData()
-})
+  initData();
+});
 </script>
 
 <style lang="scss" scoped>
@@ -211,7 +220,7 @@ onMounted(() => {
 .container-header {
   width: 100%;
   height: 370px;
-  background: url('@/assets/images/index/banner.png') no-repeat;
+  background: url("@/assets/images/index/banner.png") no-repeat;
   background-size: 100% 100%;
   display: flex;
   flex-direction: column;
@@ -239,7 +248,6 @@ onMounted(() => {
     border-top-width: 0 !important;
   }
   :deep(.van-grid) {
-
     .van-grid-item {
       &:nth-child(1) {
         padding-right: 12px;
@@ -275,7 +283,7 @@ onMounted(() => {
         }
         .card-title {
           font-size: 14px;
-          color: #414F64;
+          color: #414f64;
         }
       }
       .icon1 {
@@ -293,8 +301,7 @@ onMounted(() => {
       .icon1,
       .icon2,
       .icon3,
-      .icon4
-      {
+      .icon4 {
         width: 67px;
         height: 67px;
         background-size: 100% 100%;
@@ -316,7 +323,7 @@ onMounted(() => {
     height: 26px;
     font-weight: bold;
     font-size: 18px;
-    color: #414F64;
+    color: #414f64;
     letter-spacing: 0;
     margin-bottom: 4px;
   }
@@ -368,22 +375,4 @@ onMounted(() => {
     border-bottom: 1px solid #eeeeee;
   }
 }
-.common-search {
-  :deep(.van-field__left-icon) {
-
-    .van-icon__image {
-      width: 12px;
-      height: 12px;
-    }
-  }
-  :deep(.van-field__right-icon) {
-    width: 30px;
-    height: 30px;
-    padding: 0;
-    .van-icon__image {
-      width: 30px;
-      height: 30px;
-    }
-  }
-}
 </style>

+ 470 - 2
src/views/worker/index.vue

@@ -1,9 +1,477 @@
 <template>
-    工作人员首页
+  <dic class="container">
+    <div class="container-header">
+      <div ref="searchBoxRef" class="search-box">
+        <van-search
+          v-model="queryParams.keywords"
+          class="common-search"
+          :left-icon="searchImg"
+          :right-icon="closeImg"
+          placeholder="请输入搜索内容"
+          @search="on_search_keyword"
+          @click-right-icon.stop="on_search_cancel"
+        />
+        <div v-show="showSearch" class="search-list">
+          <van-list
+            v-model:loading="loading"
+            v-model:error="error"
+            error-text="请求失败,点击重新加载"
+            :finished="finished"
+            finished-text="没有更多了"
+            :immediate-check="false"
+            @load="getSearchList"
+          >
+            <div
+              v-for="(item, index) in searchList"
+              :key="index"
+              class="item"
+              @click="handleClickItem(item)"
+            >
+              {{ item.name }}
+            </div>
+          </van-list>
+        </div>
+      </div>
+    </div>
+    <div class="container-content">
+      <div class="notice-bar">
+        <!-- 静态的预警信息 -->
+        <div class="notice-item">
+          <span class="notice-label">预警信息</span>
+          <div class="notice-time">2023-10-10 10:00:00</div>
+          <div class="notice-content">
+            这里是静态的预警信息内容,不需要从变量中获取。
+          </div>
+        </div>
+        <!-- 查看更多的链接 -->
+        <div class="notice-more" @click="goToInformationReception">
+          查看更多 >>
+        </div>
+      </div>
+      <!--      <div v-if="noticeBarState.show" class="notice-bar">-->
+      <!--        <van-swipe :autoplay="false" indicator-color="back">-->
+      <!--          <van-swipe-item-->
+      <!--            v-for="(message, index) in latestMessages"-->
+      <!--            :key="index"-->
+      <!--          >-->
+      <!--            <div class="notice-item">-->
+      <!--              <span class="notice-label">预警信息</span>-->
+      <!--              <div class="notice-content">-->
+      <!--                {{ message.event_title }}-->
+      <!--              </div>-->
+      <!--              <div class="notice-time">-->
+      <!--                {{ message.event_time }}-->
+      <!--              </div>-->
+      <!--            </div>-->
+      <!--          </van-swipe-item>-->
+      <!--        </van-swipe>-->
+      <!--        <div class="notice-more" @click="goToInformationReception">-->
+      <!--          查看更多 >>-->
+      <!--        </div>-->
+      <!--      </div>-->
+      <div class="padding-content">
+        <van-grid :column-num="2">
+          <van-grid-item
+            v-for="(item, index) in menu"
+            :key="index"
+            @click="handleClickMenu(item.url)"
+          >
+            <div class="card">
+              <div :class="item.icon" />
+              <van-badge :content="item.num" max="99" :show-zero="false">
+                <div class="card-title">{{ item.name }}</div>
+              </van-badge>
+            </div>
+          </van-grid-item>
+        </van-grid>
+        <div class="app_panel">
+          <div class="app_panel_title">综合应用</div>
+          <div v-for="(item, index) in menu2" :key="index" class="box">
+            <div class="box-title">{{ item.name }}</div>
+            <div class="box-content">
+              <div
+                v-for="(item2, index2) in item.children"
+                :key="index2"
+                class="box-item"
+                @click="handleClickMenu(item.url)"
+              >
+                <img class="icon" :src="getImageUrl(item2.icon)" alt="" />
+                <span>{{ item2.name }}</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </dic>
 </template>
 
 <script lang="ts" setup>
+import { onClickOutside } from "@vueuse/core";
+import { onMounted, reactive, ref } from "vue";
+import { selectTask } from "@/api/emergencyCommandMap/JointDuty";
+import searchImg from "@/assets/images/search.png";
+import { useRouter } from "vue-router";
+import closeImg from "@/assets/images/close.png";
+import { getPointInfoComprehensiveSearch } from "@/api/globalMap";
+
+const router = useRouter();
+const noticeBarState = reactive({
+  show: false,
+  latestMessages: []
+});
+
+const goToInformationReception = () => {
+  router.push({ name: "InformationReception" });
+};
+// 菜单数据
+const menu = ref([
+  { name: "巡查工作", icon: "icon1", num: 0, url: "" },
+  { name: "风险防控", icon: "icon2", num: 0, url: "" },
+  { name: "数据管理", icon: "icon3", num: 0, url: "" },
+  { name: "在线点名", icon: "icon4", num: 0, url: "" }
+]);
+
+// 综合应用菜单
+const menu2 = ref([
+  {
+    name: "自然灾害风险监测",
+    children: [
+      { name: "灾害监测", icon: "monitor", url: "" },
+      { name: "大风灾害", icon: "wind", url: "" },
+      { name: "森林火灾", icon: "forestFire", url: "" },
+      { name: "台风实况", icon: "typhoon", url: "" },
+      { name: "水文监测", icon: "hydrology", url: "" }
+    ]
+  },
+  {
+    name: "应急事件场景专题",
+    children: [
+      { name: "自然灾害", icon: "nature", url: "" },
+      { name: "事故灾害", icon: "accident", url: "" },
+      { name: "城市事件", icon: "city", url: "" }
+    ]
+  }
+]);
+const handleClickMenu = url => {
+  if (!url) return;
+  router.push({ name: url });
+};
+const getImageUrl = name => {
+  return new URL(`../../assets/images/index/${name}.png`, import.meta.url).href;
+};
+
+// 请求数据
+const initData = async () => {
+  try {
+    const sortOrder = "desc";
+    const sortBy = "creation_time";
+    const event_code = "YJSJ0000000001";
+
+    console.log("请求任务数据:", event_code);
+    const res = await selectTask({
+      sortOrder: sortOrder,
+      sortBy: sortBy,
+      event_code: event_code
+    });
+    if (res && res.data) {
+      noticeBarState.latestMessages = res.data.slice(0, 3).map(msg => ({
+        event_title: msg.event_title,
+        event_time: msg.event_time
+      }));
+      noticeBarState.show = true;
+    } else {
+      console.error("API response data is empty or invalid");
+    }
+  } catch (error) {
+    console.error("请求任务数据失败:", error);
+    noticeBarState.show = false; // 如果请求失败,不显示通知栏
+  }
+};
+// 搜索
+const searchBoxRef = ref();
+let showSearch = ref();
+const total = ref(0);
+let loading = ref(false);
+let error = ref(false);
+let finished = ref(false);
+const queryParams = reactive({
+  page: 0,
+  page_size: 15,
+  keywords: ""
+});
+const searchList = ref([]);
+onClickOutside(searchBoxRef, event => {
+  showSearch.value = false;
+});
+const getSearchList = () => {
+  if (!queryParams.keywords) {
+    return (loading.value = false);
+  }
+  queryParams.page++;
+  getPointInfoComprehensiveSearch(queryParams)
+    .then(res => {
+      const items = res.data.list || [];
+      total.value = res.data.total;
+      if (queryParams.page == 1) {
+        searchList.value = [];
+      }
+      items.forEach(val => {
+        searchList.value.push(val);
+      });
+      finished.value = queryParams.page_size * queryParams.page >= total.value;
+      showSearch.value = true;
+    })
+    .catch(() => {
+      error.value = true;
+      finished.value = false;
+    })
+    .finally(() => {
+      loading.value = false;
+    });
+};
+const on_search_keyword = val => {
+  queryParams.keywords = val;
+  queryParams.page = 0;
+  getSearchList();
+};
+const on_search_cancel = () => {
+  showSearch.value = false;
+  queryParams.keywords = "";
+  queryParams.page = 0;
+  finished.value = false;
+  searchList.value = [];
+};
+const handleClickItem = item => {
+  showSearch.value = false;
+  queryParams.keywords = "";
+  queryParams.page = 0;
+  finished.value = false;
+  searchList.value = [];
+};
+onMounted(() => {
+  initData();
+});
 </script>
 
 <style lang="scss" scoped>
-</style>
+.container {
+  display: block;
+  width: 100%;
+  height: 100%;
+  padding-bottom: 20px;
+}
+.container-header {
+  width: 100%;
+  height: 370px;
+  background: url("@/assets/images/") no-repeat;
+  background-size: 100% 100%;
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-end;
+  align-items: center;
+  padding-bottom: 70px;
+  .search-box {
+    width: 100%;
+    position: relative;
+  }
+  .van-search {
+    width: 100%;
+  }
+}
+.container-content {
+  margin-top: -70px;
+  .van-notice-bar {
+    width: 100%;
+    margin-bottom: 11px;
+  }
+  .padding-content {
+    padding: 0 16px;
+  }
+  .van-hairline--top:after {
+    border-top-width: 0 !important;
+  }
+  :deep(.van-grid) {
+    .van-grid-item {
+      &:nth-child(1) {
+        padding-right: 12px;
+        padding-bottom: 12px;
+      }
+      &:nth-child(2) {
+        padding-bottom: 12px;
+      }
+      &:nth-child(3) {
+        padding-right: 12px;
+      }
+      .card {
+        width: 100%;
+        height: 89px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 9px 15px 9px 0;
+        font-size: 14px;
+        background: url(@/assets/images/index/cardBg1.png) no-repeat;
+        background-size: 100% 100%;
+        &:nth-child(2) {
+          background: url(@/assets/images/index/cardBg2.png) no-repeat;
+          background-size: 100% 100%;
+        }
+        &:nth-child(3) {
+          background: url(@/assets/images/index/cardBg3.png) no-repeat;
+          background-size: 100% 100%;
+        }
+        &:nth-child(4) {
+          background: url(@/assets/images/index/cardBg4.png) no-repeat;
+          background-size: 100% 100%;
+        }
+        .card-title {
+          font-size: 14px;
+          color: #414f64;
+        }
+      }
+      .icon1 {
+        background: url(@/assets/images/index/icon1.png) no-repeat;
+      }
+      .icon2 {
+        background: url(@/assets/images/index/icon2.png) no-repeat;
+      }
+      .icon3 {
+        background: url(@/assets/images/index/icon3.png) no-repeat;
+      }
+      .icon4 {
+        background: url(@/assets/images/index/icon4.png) no-repeat;
+      }
+      .icon1,
+      .icon2,
+      .icon3,
+      .icon4 {
+        width: 67px;
+        height: 67px;
+        background-size: 100% 100%;
+      }
+    }
+    .van-grid-item__content {
+      padding: 0;
+      background: transparent;
+      &::after {
+        border: none;
+      }
+    }
+  }
+}
+
+.app_panel {
+  padding-top: 12px;
+  .app_panel_title {
+    height: 26px;
+    font-weight: bold;
+    font-size: 18px;
+    color: #414f64;
+    letter-spacing: 0;
+    margin-bottom: 4px;
+  }
+  .box {
+    width: 100%;
+    height: 72px;
+    background: url("@/assets/images/index/boxBg.png") no-repeat;
+    background-size: 100% 100%;
+    margin-bottom: 12px;
+    &:last-child {
+      margin-bottom: 0;
+    }
+    .box-title {
+      font-size: 12px;
+      color: #3687fe;
+      padding: 0 10px;
+    }
+    .box-content {
+      display: flex;
+      flex-wrap: wrap;
+      padding-top: 3px;
+      .box-item {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        width: 20%;
+        font-size: 12px;
+        .icon {
+          width: 32px;
+          height: 34px;
+        }
+      }
+    }
+  }
+}
+.search-list {
+  position: absolute;
+  top: 50px;
+  left: 0;
+  z-index: 9;
+  width: 100%;
+  height: calc(100vh - 400px);
+  overflow-y: auto;
+  background-color: #ffffff;
+  border-top: 1px solid #eeeeee;
+  .item {
+    padding: 8px 15px;
+    border-bottom: 1px solid #eeeeee;
+  }
+}
+.common-search {
+  :deep(.van-field__left-icon) {
+    .van-icon__image {
+      width: 12px;
+      height: 12px;
+    }
+  }
+  :deep(.van-field__right-icon) {
+    width: 30px;
+    height: 30px;
+    padding: 0;
+    .van-icon__image {
+      width: 30px;
+      height: 30px;
+    }
+  }
+}
+.notice-bar {
+  background-color: #f3f7ff;
+  padding: 10px;
+  border-radius: 5px;
+  margin-bottom: 10px;
+}
+
+.notice-item {
+  margin-bottom: 10px;
+}
+
+.notice-label {
+  background-color: orange;
+  color: white;
+  padding: 5px;
+  border-radius: 3px;
+  margin-right: 5px;
+}
+
+.notice-content {
+  max-height: 45px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+}
+
+.notice-time {
+  font-size: 12px;
+  color: #888;
+}
+
+.notice-more {
+  float: right;
+  color: #007aff;
+  cursor: pointer;
+}
+</style>