瀏覽代碼

风险防控风险源排查接口和样式

hmm 10 月之前
父節點
當前提交
628fe62569

+ 9 - 0
src/api/riskManagement/index.ts

@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+// 获取当前活动事件列表
+export function getTaskList(type:string) {
+  return request({
+    url: "/api/riskManagement/risk/children/task/list",
+    method: "get"
+  });
+}

+ 1 - 1
src/router/routes.ts

@@ -182,7 +182,7 @@ export const constantRoutes: Array<RouteRecordRaw> = [
     }
   },
   {
-    path: "/riskManagement",
+    path: "/riskManagement/index",
     name: "riskManagement",
     component: () => import("@/views/worker/riskManagement/index.vue"),
     meta: {

+ 248 - 160
src/views/event/detail.vue

@@ -1,17 +1,22 @@
 <template>
   <div class="container">
-    <div v-if="!hideMap" id="aMap" class="event_map"></div>
+    <div v-if="!hideMap" id="aMap" class="event_map" />
     <div class="box">
-      <div class="event_title">{{ eventInfo.event_title || "暂无事件标题" }}</div>
+      <div class="event_title">
+        {{ eventInfo.event_title || "暂无事件标题" }}
+      </div>
       <div class="event_prop">
         <div class="event_type">
-          <dict-tag :options="mm_event_type" :value="eventInfo.event_type"></dict-tag>
+          <dict-tag :options="mm_event_type" :value="eventInfo.event_type" />
         </div>
         <div class="event_level">
-          <dict-tag :options="mm_event_level" :value="eventInfo.event_level||'0'"></dict-tag>
+          <dict-tag
+            :options="mm_event_level"
+            :value="eventInfo.event_level || '0'"
+          />
         </div>
         <div class="event_status">
-          <dict-tag :options="mm_event_state" :value="eventInfo.event_status"></dict-tag>
+          <dict-tag :options="mm_event_state" :value="eventInfo.event_status" />
         </div>
       </div>
       <van-tabs v-model:active="active">
@@ -19,93 +24,117 @@
           <div class="event_tab">
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon6"/>
+                <i class="icon6" />
                 <div class="event-data-item-title">事件编号:</div>
               </div>
               <div class="event-data-item-value">{{ eventInfo.event_id }}</div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon1"/>
+                <i class="icon1" />
                 <div class="event-data-item-title">事件类型:</div>
               </div>
               <div class="event-data-item-value">
-                <dict-tag :options="mm_event_type" :value="eventInfo.event_type"></dict-tag>
+                <dict-tag
+                  :options="mm_event_type"
+                  :value="eventInfo.event_type"
+                />
               </div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon2"/>
+                <i class="icon2" />
                 <div class="event-data-item-title">事件等级:</div>
               </div>
               <div class="event-data-item-value">
-                <dict-tag :options="mm_event_level" :value="eventInfo.event_level||'0'"></dict-tag>
+                <dict-tag
+                  :options="mm_event_level"
+                  :value="eventInfo.event_level || '0'"
+                />
               </div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon3"/>
+                <i class="icon3" />
                 <div class="event-data-item-title">事件状态:</div>
               </div>
               <div class="event-data-item-value">
-                <dict-tag :options="mm_event_state" :value="eventInfo.event_status"></dict-tag>
+                <dict-tag
+                  :options="mm_event_state"
+                  :value="eventInfo.event_status"
+                />
               </div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon5"/>
+                <i class="icon5" />
                 <div class="event-data-item-title">事发地点:</div>
               </div>
               <div class="event-data-item-value">{{ eventInfo.address }}</div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon4"/>
+                <i class="icon4" />
                 <div class="event-data-item-title">事发时间:</div>
               </div>
-              <div class="event-data-item-value">{{ eventInfo.event_time }}</div>
+              <div class="event-data-item-value">
+                {{ eventInfo.event_time }}
+              </div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon4"/>
+                <i class="icon4" />
                 <div class="event-data-item-title">上报时间:</div>
               </div>
-              <div class="event-data-item-value">{{ eventInfo.report_time }}</div>
+              <div class="event-data-item-value">
+                {{ eventInfo.report_time }}
+              </div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon7"/>
+                <i class="icon7" />
                 <div class="event-data-item-title">伤亡情况:</div>
               </div>
-              <div class="event-data-item-value blue" @click="handleUploadCasualties">去上报</div>
+              <div
+                class="event-data-item-value blue"
+                @click="handleUploadCasualties"
+              >
+                去上报
+              </div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon8"/>
+                <i class="icon8" />
                 <div class="event-data-item-title">登记人:</div>
               </div>
-              <div class="event-data-item-value">{{ eventInfo.reported_by }}</div>
+              <div class="event-data-item-value">
+                {{ eventInfo.reported_by }}
+              </div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon4"/>
+                <i class="icon4" />
                 <div class="event-data-item-title">登记时间:</div>
               </div>
-              <div class="event-data-item-value">{{ eventInfo.reported_time }}</div>
+              <div class="event-data-item-value">
+                {{ eventInfo.reported_time }}
+              </div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon9"/>
+                <i class="icon9" />
                 <div class="event-data-item-title">联系方式:</div>
               </div>
               <div class="event-data-item-value">{{ eventInfo.contact }}</div>
             </div>
             <div class="event-data-item">
               <div class="item-left">
-                <i class="icon10"/>
+                <i class="icon10" />
                 <div class="event-data-item-title">事件来源:</div>
               </div>
-              <div class="event-data-item-value">{{ eventInfo.event_source }}</div>
+              <div class="event-data-item-value">
+                {{ eventInfo.event_source }}
+              </div>
             </div>
           </div>
         </van-tab>
@@ -115,7 +144,10 @@
         <van-tab title="事件跟踪">
           <div class="event_tab">
             <van-steps direction="vertical" :active="0">
-              <van-step v-for="(item,index) in eventTrackState.items" :key="item.id">
+              <van-step
+                v-for="(item, index) in eventTrackState.items"
+                :key="item.id"
+              >
                 <h3>{{ item.title }}</h3>
                 <p>{{ item.description }}</p>
               </van-step>
@@ -124,39 +156,70 @@
         </van-tab>
         <van-tab title="匹配预案">
           <div class="event_tab2">
-            <template v-if="!!eventInfo.plan_id && !!eventInfo.plan_files && eventInfo.plan_files.length > 0">
+            <template
+              v-if="
+                !!eventInfo.plan_id &&
+                !!eventInfo.plan_files &&
+                eventInfo.plan_files.length > 0
+              "
+            >
               <div class="plan-content">
                 <div class="content-header">
-                  <div class="plan-content-title">{{ eventInfo.plan_files[0]?.name }}</div>
-                  <i class="download-icon" @click="handleDownload(eventInfo.plan_files[0])"/>
+                  <div class="plan-content-title">
+                    {{ eventInfo.plan_files[0]?.name }}
+                  </div>
+                  <i
+                    class="download-icon"
+                    @click="handleDownload(eventInfo.plan_files[0])"
+                  />
                 </div>
                 <div class="content-text">
                   <div v-for="(item, index) in planFiles" :key="index">
                     <div>{{ item.title }}</div>
                     <div v-for="(item2, index2) in item.items" :key="index2">
                       <div>{{ item2.title }}</div>
-                      <div v-html="item2.value"></div>
+                      <div v-html="item2.value" />
                     </div>
                   </div>
                 </div>
               </div>
             </template>
             <template v-else>
-              <div class="emptyIcon"/>
+              <div class="emptyIcon" />
               <div class="emptyText">未关联到对应预案</div>
-              <van-button type="primary" size="small" @click="associationShow = true">手工关联</van-button>
+              <van-button
+                type="primary"
+                size="small"
+                @click="associationShow = true"
+                >手工关联</van-button
+              >
             </template>
           </div>
         </van-tab>
         <van-tab title="总结报告">
           <div class="event_tab2">
-            <div v-if="eventInfo.summary_file && eventInfo.summary_file.length > 0" class="file-list">
-              <div v-for="(item, index) in eventInfo.summary_file" :key="index" class="item" @click="handleDownload2(item)">{{item.file_name}}</div>
+            <div
+              v-if="eventInfo.summary_file && eventInfo.summary_file.length > 0"
+              class="file-list"
+            >
+              <div
+                v-for="(item, index) in eventInfo.summary_file"
+                :key="index"
+                class="item"
+                @click="handleDownload2(item)"
+              >
+                {{ item.file_name }}
+              </div>
             </div>
             <template v-else>
-              <div class="emptyIcon2"/>
+              <div class="emptyIcon2" />
               <div class="emptyText">暂未上传总结报告</div>
-              <van-button type="primary" size="small" @click="handleUploadCasualties">去上传</van-button>
+              <van-button
+                type="primary"
+                size="small"
+                @click="handleUploadCasualties"
+                >去上传</van-button
+              >
             </template>
           </div>
         </van-tab>
@@ -164,93 +227,119 @@
     </div>
 
     <div class="footer">
-      <div style="display: flex; flex-direction: row; justify-content: space-between;">
-        <van-button v-if="eventInfo.event_status == '0'" type="primary" @click="handleStartEvent">开始指挥</van-button>
-        <van-button v-if="eventInfo.event_status == '1'" type="primary" @click="handleEnterEvent">进入指挥</van-button>
-        <van-button v-if="eventInfo.event_status == '0' || eventInfo.event_status == '2'" type="danger"
-                    @click="handleCloseEvent">关闭事件
+      <div
+        style="
+          display: flex;
+          flex-direction: row;
+          justify-content: space-between;
+        "
+      >
+        <van-button
+          v-if="eventInfo.event_status == '0'"
+          type="primary"
+          @click="handleStartEvent"
+          >开始指挥</van-button
+        >
+        <van-button
+          v-if="eventInfo.event_status == '1'"
+          type="primary"
+          @click="handleEnterEvent"
+          >进入指挥</van-button
+        >
+        <van-button
+          v-if="eventInfo.event_status == '0' || eventInfo.event_status == '2'"
+          type="danger"
+          @click="handleCloseEvent"
+          >关闭事件
         </van-button>
       </div>
     </div>
-    <AssociationPlan v-model="associationShow" :eventId="eventId" @confirm="associationPlanConfirm" />
+    <AssociationPlan
+      v-model="associationShow"
+      :eventId="eventId"
+      @confirm="associationPlanConfirm"
+    />
     <UploadEventCasualtiesDialog
-        v-model="uploadCasualtiesState.show"
-        :data="uploadCasualtiesState.form"
-        @update:model-value="onUploadCasualtiesDialogClose"
-        @confirm="onUploadCasualtiesDialogClose"
+      v-model="uploadCasualtiesState.show"
+      :data="uploadCasualtiesState.form"
+      @update:model-value="onUploadCasualtiesDialogClose"
+      @confirm="onUploadCasualtiesDialogClose"
+    />
+    <StartEventDialog
+      v-model="startEventState.show"
+      :data="startEventState.form"
+      @update:model-value="onStartEventDialogClose"
     />
-    <StartEventDialog v-model="startEventState.show" :data="startEventState.form"
-                      @update:model-value="onStartEventDialogClose"></StartEventDialog>
   </div>
 </template>
 
 <script lang="ts" setup>
-import {getCurrentInstance, reactive, ref, toRefs, onMounted} from 'vue';
-import {useRouter, useRoute} from 'vue-router'
-import {getEventDetail, closeEvent} from "@/api/event";
+import { getCurrentInstance, reactive, ref, toRefs, onMounted } from "vue";
+import { useRouter, useRoute } from "vue-router";
+import { getEventDetail, closeEvent } from "@/api/event";
 import UploadEventCasualtiesDialog from "./UploadEventCasualtiesDialog.vue";
-import {showDialog, showConfirmDialog} from 'vant';
-import {useAMap} from "@/hooks/AMap/useAMap";
+import { showDialog, showConfirmDialog } from "vant";
+import { useAMap } from "@/hooks/AMap/useAMap";
 import StartEventDialog from "@/views/event/StartEventDialog.vue";
-import {download2} from "@/utils/request";
-import {getPlanDoc, listPlan} from "@/api/duty/eventing";
+import { download2 } from "@/utils/request";
+import { getPlanDoc, listPlan } from "@/api/duty/eventing";
 import AssociationPlan from "@/views/event/AssociationPlan.vue";
 
-const router = useRouter()
-const route = useRoute()
+const router = useRouter();
+const route = useRoute();
 const proxy = getCurrentInstance()?.proxy;
-const {
-  mm_event_type,
-  mm_event_level,
-  mm_event_state
-} = toRefs<any>(proxy?.useDict('mm_event_type', 'mm_event_level', 'mm_event_state'));
+const { mm_event_type, mm_event_level, mm_event_state } = toRefs<any>(
+  proxy?.useDict("mm_event_type", "mm_event_level", "mm_event_state")
+);
 
 const active = ref(0);
-const eventId = ref('');
+const eventId = ref("");
 const data = reactive({
   eventInfo: {
-    event_id: '',
-    event_title: '',
-    event_code: '',
-    event_type: '',
-    event_level: '',
-    event_status: '',
-    address: '',
-    event_time: '',
-    report_time: '',
-    contact: '',
-    event_source: '',
-    event_description: '',
-    reported_by: '',
-    reported_time: '',
-    longitude: '',
-    latitude: '',
-    plan_id: '',
-    plan_name: '',
+    event_id: "",
+    event_title: "",
+    event_code: "",
+    event_type: "",
+    event_level: "",
+    event_status: "",
+    address: "",
+    event_time: "",
+    report_time: "",
+    contact: "",
+    event_source: "",
+    event_description: "",
+    reported_by: "",
+    reported_time: "",
+    longitude: "",
+    latitude: "",
+    plan_id: "",
+    plan_name: "",
     summary_file: [],
     plan_files: [],
     // 伤亡情况
-    deaths: '',
-    injuries: '',
-    missing: '',
+    deaths: "",
+    injuries: "",
+    missing: ""
   },
   eventTrackState: {
     active: 0,
-    items: [{
-      id: 0,
-      title: '事件登记',
-      description: ''
-    }]
+    items: [
+      {
+        id: 0,
+        title: "事件登记",
+        description: ""
+      }
+    ]
   }
 });
-const {eventInfo, eventTrackState} = toRefs(data);
+const { eventInfo, eventTrackState } = toRefs(data);
 const startEventState = reactive({
   show: false,
   form: {
-    event_id: '',
-    event_title: '',
-    event_level: '',
-    event_level_text: '',
+    event_id: "",
+    event_title: "",
+    event_level: "",
+    event_level_text: ""
   }
 });
 const handleStartEvent = () => {
@@ -259,10 +348,10 @@ const handleStartEvent = () => {
   startEventState.form.event_level = eventInfo.value.event_level;
   startEventState.show = true;
   return false;
-}
+};
 const handleEnterEvent = () => {
   router.push({
-    path: '/leader/mobile_control',
+    path: "/leader/mobile_control",
     query: {
       event_id: eventId.value
     }
@@ -271,22 +360,22 @@ const handleEnterEvent = () => {
 
 // 关闭事件
 const handleCloseEvent = () => {
-  if (eventInfo.value.plan_id === '') {
-    showDialog({message: '关闭事件前请先匹配预案'});
+  if (eventInfo.value.plan_id === "") {
+    showDialog({ message: "关闭事件前请先匹配预案" });
     return false;
   }
   if (eventInfo.value.summary_file.length === 0) {
-    showDialog({message: '关闭事件前请先上传总结报告'});
+    showDialog({ message: "关闭事件前请先上传总结报告" });
     return false;
   }
   showConfirmDialog({
-    title: '提示',
-    message: '关闭事件所有事项相关数据将不能再修改,是否继续?'
+    title: "提示",
+    message: "关闭事件所有事项相关数据将不能再修改,是否继续?"
   }).then(() => {
-    closeEvent({eventId: eventId.value}).then((res) => {
-      refreshData()
-    })
-  })
+    closeEvent({ eventId: eventId.value }).then(res => {
+      refreshData();
+    });
+  });
 };
 
 let associationShow = ref(false);
@@ -295,16 +384,15 @@ let associationShow = ref(false);
 const uploadCasualtiesState = reactive({
   show: false,
   form: {
-    event_id: '',
-    deaths: '',
-    injuries: '',
-    missing: ''
+    event_id: "",
+    deaths: "",
+    injuries: "",
+    missing: ""
   }
-})
-
+});
 
 const handleUploadCasualties = () => {
-  console.log('handleUploadCasualties');
+  console.log("handleUploadCasualties");
   uploadCasualtiesState.form.event_id = eventId.value;
   uploadCasualtiesState.form.deaths = eventInfo.value.deaths;
   uploadCasualtiesState.form.injuries = eventInfo.value.injuries;
@@ -312,88 +400,88 @@ const handleUploadCasualties = () => {
   uploadCasualtiesState.show = true;
 };
 
-const onUploadCasualtiesDialogClose = (t) => {
-  console.log('onUploadCasualtiesDialogClose', t)
+const onUploadCasualtiesDialogClose = t => {
+  console.log("onUploadCasualtiesDialogClose", t);
   uploadCasualtiesState.show = false;
   if (t) {
     refreshData();
   }
-}
+};
 
-const onStartEventDialogClose = (t) => {
+const onStartEventDialogClose = t => {
   startEventState.show = false;
   console.log(startEventState.form);
   if (t) {
-    getEventDetail({event_id: eventId.value}).then((res) => {
-      eventInfo.value = res.data
+    getEventDetail({ event_id: eventId.value }).then(res => {
+      eventInfo.value = res.data;
       eventTrackState.value = res.data.event_status_tracks;
-    })
+    });
   }
 };
 let planFiles = ref([]);
 const getPlan = () => {
-  getPlanDoc({plan_id: eventInfo.value.plan_id}).then((res)=> {
+  getPlanDoc({ plan_id: eventInfo.value.plan_id }).then(res => {
     planFiles.value = res.data;
   });
-}
-const associationPlanConfirm = (plan_id) => {
+};
+const associationPlanConfirm = plan_id => {
   associationShow.value = false;
   eventInfo.value.plan_id = plan_id;
   getPlan();
-}
+};
 const baseUrl = import.meta.env.VITE_BASE_API;
 // 下载方法
 const handleDownload = (file: any) => {
-  download2(baseUrl + '/file/download/' + file.url, file.name);
+  download2(baseUrl + "/file/download/" + file.url, file.name);
 };
 const handleDownload2 = (file: any) => {
-  download2(baseUrl + '/file/download/' + file.url, file.file_name);
+  download2(baseUrl + "/file/download/" + file.url, file.file_name);
 };
 onMounted(() => {
   refreshData();
-
-})
+});
 let hideMap = ref(false);
 let map;
 const refreshData = () => {
   eventId.value = route.query.event_id as string;
-  getEventDetail({event_id: eventId.value}).then((res) => {
-    eventInfo.value = res.data
+  getEventDetail({ event_id: eventId.value }).then(res => {
+    eventInfo.value = res.data;
     eventTrackState.value = res.data.event_status_tracks;
     if (!!eventInfo.value.plan_id) {
       getPlan(eventInfo.value.plan_id);
     }
     if (!eventInfo.value.longitude || !eventInfo.value.latitude) {
-      hideMap.vlaue = true
+      hideMap.value.vlaue = true;
     } else {
       // 初始化地图
       const lnglat = [eventInfo.value.longitude, eventInfo.value.latitude];
-      const {getMap} = useAMap({
-        key: '30d3d8448efd68cb0b284549fd41adcf',
-        version: '2.0',
+      const { getMap } = useAMap({
+        key: "30d3d8448efd68cb0b284549fd41adcf",
+        version: "2.0",
         zoom: 16,
         center: lnglat,
         dragEnable: true,
         scrollWheel: true,
         // 加载完成事件
-        onLoadCompleted: (AMap) => {
+        onLoadCompleted: AMap => {
           map = getMap();
           let marker = new AMap.Marker({
             position: lnglat,
             icon: new AMap.Icon({
-              size: new AMap.Size(22, 28),  //图标所处区域大小
+              size: new AMap.Size(22, 28), //图标所处区域大小
               imageSize: new AMap.Size(22, 28), //图标大小
-              image: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
+              image:
+                "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png"
             }),
-            anchor: 'bottom-center',
+            anchor: "bottom-center",
             offset: new AMap.Pixel(0, 0)
           });
           marker.setMap(map);
         }
       });
     }
-  })
-}
+  });
+};
 </script>
 
 <style lang="scss" scoped>
@@ -412,7 +500,7 @@ const refreshData = () => {
 .event_title {
   font-weight: 600;
   min-height: 46px;
-  background-image: linear-gradient(180deg, #F3F7FD 0%, #FFFFFF 100%);
+  background-image: linear-gradient(180deg, #f3f7fd 0%, #ffffff 100%);
   padding: 12px;
 }
 
@@ -427,35 +515,35 @@ const refreshData = () => {
 
   .event_type {
     padding: 3px 10px;
-    border: 0.8px solid #2C81FF;
+    border: 0.8px solid #2c81ff;
     border-radius: 2px;
-    color: #2C81FF;
+    color: #2c81ff;
     margin-right: 7px;
   }
 
   .event_level {
     padding: 3px 10px;
-    border: 0.8px solid #2C81FF;
+    border: 0.8px solid #2c81ff;
     border-radius: 2px;
     margin-right: 7px;
-    color: #2C81FF;
+    color: #2c81ff;
   }
 
   .event_status {
     padding: 3px 10px;
-    border: 0.8px solid #2C81FF;
+    border: 0.8px solid #2c81ff;
     border-radius: 2px;
-    color: #2C81FF;
+    color: #2c81ff;
   }
 }
 
 .event_tab {
   padding: 16px;
-  color: #A6000000;
+  color: #a6000000;
 
   .event-data-item {
     font-size: 14px;
-    line-height: 8.0vmin;
+    line-height: 8vmin;
     display: flex;
     flex-direction: row;
     align-items: flex-start;
@@ -470,7 +558,7 @@ const refreshData = () => {
       .icon1 {
         width: 17px;
         height: 16px;
-        background: url('@/assets/images/event/icon1.png') no-repeat;
+        background: url("@/assets/images/event/icon1.png") no-repeat;
         background-size: 100% 100%;
         margin-right: 7px;
       }
@@ -478,7 +566,7 @@ const refreshData = () => {
       .icon2 {
         width: 17px;
         height: 16px;
-        background: url('@/assets/images/event/icon2.png') no-repeat;
+        background: url("@/assets/images/event/icon2.png") no-repeat;
         background-size: 100% 100%;
         margin-right: 7px;
       }
@@ -486,7 +574,7 @@ const refreshData = () => {
       .icon3 {
         width: 17px;
         height: 16px;
-        background: url('@/assets/images/event/icon3.png') no-repeat;
+        background: url("@/assets/images/event/icon3.png") no-repeat;
         background-size: 100% 100%;
         margin-right: 7px;
       }
@@ -494,7 +582,7 @@ const refreshData = () => {
       .icon4 {
         width: 17px;
         height: 16px;
-        background: url('@/assets/images/event/icon4.png') no-repeat;
+        background: url("@/assets/images/event/icon4.png") no-repeat;
         background-size: 100% 100%;
         margin-right: 7px;
       }
@@ -502,7 +590,7 @@ const refreshData = () => {
       .icon5 {
         width: 16px;
         height: 16px;
-        background: url('@/assets/images/event/icon5.png') no-repeat;
+        background: url("@/assets/images/event/icon5.png") no-repeat;
         background-size: 100% 100%;
         margin-right: 7px;
       }
@@ -564,7 +652,7 @@ const refreshData = () => {
 
   h3 {
     font-size: 4.2vmin;
-    line-height: 8.0vmin;
+    line-height: 8vmin;
   }
 }
 
@@ -598,14 +686,14 @@ const refreshData = () => {
 .emptyIcon {
   width: 110px;
   height: 108px;
-  background: url('@/assets/images/unrelatedPlan.png') no-repeat;
+  background: url("@/assets/images/unrelatedPlan.png") no-repeat;
   background-size: 100% 100%;
 }
 
 .emptyIcon2 {
   width: 111px;
   height: 110px;
-  background: url('@/assets/images/noReport.png') no-repeat;
+  background: url("@/assets/images/noReport.png") no-repeat;
   background-size: 100% 100%;
 }
 
@@ -621,7 +709,7 @@ const refreshData = () => {
     justify-content: center;
     align-items: center;
     font-size: 14px;
-    color: #2C81FF;
+    color: #2c81ff;
     font-weight: bold;
     padding: 5px 0;
     .plan-content-title {
@@ -632,7 +720,7 @@ const refreshData = () => {
       display: inline-block;
       width: 15px;
       height: 14px;
-      background: url('@/assets/images/download.png') no-repeat;
+      background: url("@/assets/images/download.png") no-repeat;
       background-size: 100% 100%;
       margin-left: 20px;
     }
@@ -646,7 +734,7 @@ const refreshData = () => {
   }
 }
 :deep(.van-tabs__wrap) {
-  border-bottom: 1px solid #F6F6F6;
+  border-bottom: 1px solid #f6f6f6;
 }
 .file-list {
   width: 100%;

+ 59 - 45
src/views/onlineRollCall/index.vue

@@ -1,6 +1,11 @@
 <template>
   <div class="container">
-    <div v-for="(item, index) in menuData" :key="index" class="box" @click="handleClick(item.key)">
+    <div
+      v-for="(item, index) in menuData"
+      :key="index"
+      class="box"
+      @click="handleClick(item.key)"
+    >
       <div class="box-left">
         <i :class="item.img" />
       </div>
@@ -10,52 +15,61 @@
 </template>
 
 <script lang="ts" setup name="onlineRollCall">
-import {reactive} from "vue";
-import {useRouter} from "vue-router";
-import {showConfirmDialog, showToast} from 'vant';
-import {create_by_city_to_area, create_by_city_to_district} from "@/api/onlineRollCall";
+import { reactive } from "vue";
+import { useRouter } from "vue-router";
+import { showConfirmDialog, showToast } from "vant";
+import {
+  create_by_city_to_area,
+  create_by_city_to_district
+} from "@/api/onlineRollCall";
 
 const router = useRouter();
 const menuData = reactive([
-  { name: '一键点名全市至区县', key: '1', img: 'icon1' },
-  { name: '一键点名全市至镇街', key: '2', img: 'icon1' },
-  { name: '分区/县点名', key: '3', img: 'icon1' },
-  { name: '在线点名记录', key: '4', img: 'icon2' },
-  { name: '点名应答记录', key: '5', img: 'icon3' }
-])
+  { name: "一键点名全市至区县", key: "1", img: "icon1" },
+  { name: "一键点名全市至镇街", key: "2", img: "icon1" },
+  { name: "分区/县点名", key: "3", img: "icon1" },
+  { name: "在线点名记录", key: "4", img: "icon2" },
+  { name: "点名应答记录", key: "5", img: "icon3" }
+]);
 const handleClick = (key: string) => {
-  if (key === '1') {
+  if (key === "1") {
     showConfirmDialog({
-      title: '提示',
-      message: '确认一键点名全市至区县?'
-    })
-    .then(() => {
-      create_by_city_to_area({}).then((res) => {
-        showToast({type: 'success', message: res.msg, onClose:()=>{
-          router.push({ name : 'RollCallDetails', query: { id: res.data }})
-        }});
-      })
-    })
-  } else if (key === '2') {
+      title: "提示",
+      message: "确认一键点名全市至区县?"
+    }).then(() => {
+      create_by_city_to_area({}).then(res => {
+        showToast({
+          type: "success",
+          message: res.msg,
+          onClose: () => {
+            router.push({ name: "RollCallDetails", query: { id: res.data } });
+          }
+        });
+      });
+    });
+  } else if (key === "2") {
     showConfirmDialog({
-      title: '提示',
-      message: '确认一键点名全市至镇街?'
-    })
-    .then(() => {
-      create_by_city_to_district({}).then((res) => {
-        showToast({type: 'success', message: res.msg, onClose:()=>{
-          router.push({ name : 'RollCallDetails', query: { id: res.data }})
-        }});
-      })
-    })
-  } else if (key === '3') {
-    router.push({ name : 'DistrictCountyRollCall'});
-  } else if (key === '4') {
-    router.push({ name : 'RollCallRecord'});
-  } else if (key === '5') {
-    router.push({ name : 'rollCallRecord2'});
+      title: "提示",
+      message: "确认一键点名全市至镇街?"
+    }).then(() => {
+      create_by_city_to_district({}).then(res => {
+        showToast({
+          type: "success",
+          message: res.msg,
+          onClose: () => {
+            router.push({ name: "RollCallDetails", query: { id: res.data } });
+          }
+        });
+      });
+    });
+  } else if (key === "3") {
+    router.push({ name: "DistrictCountyRollCall" });
+  } else if (key === "4") {
+    router.push({ name: "RollCallRecord" });
+  } else if (key === "5") {
+    router.push({ name: "rollCallRecord2" });
   }
-}
+};
 </script>
 
 <style lang="scss" scoped>
@@ -69,7 +83,7 @@ const handleClick = (key: string) => {
   .box {
     width: 358px;
     height: 89px;
-    background: url('@/assets/images/onlineRollCall/box.png') no-repeat;
+    background: url("@/assets/images/onlineRollCall/box.png") no-repeat;
     background-size: 100% 100%;
     display: flex;
     //justify-content: center;
@@ -86,25 +100,25 @@ const handleClick = (key: string) => {
       display: inline-block;
       width: 92px;
       height: 93px;
-      background: url('@/assets/images/onlineRollCall/icon1.png') no-repeat;
+      background: url("@/assets/images/onlineRollCall/icon1.png") no-repeat;
       background-size: 100% 100%;
     }
     .icon2 {
       display: inline-block;
       width: 97px;
       height: 94px;
-      background: url('@/assets/images/onlineRollCall/icon2.png') no-repeat;
+      background: url("@/assets/images/onlineRollCall/icon2.png") no-repeat;
       background-size: 100% 100%;
     }
     .icon3 {
       display: inline-block;
       width: 96px;
       height: 89px;
-      background: url('@/assets/images/onlineRollCall/icon3.png') no-repeat;
+      background: url("@/assets/images/onlineRollCall/icon3.png") no-repeat;
       background-size: 100% 100%;
     }
     .label {
-      color: #414F64;
+      color: #414f64;
       font-size: 16px;
       width: 144px;
       text-align: center;

+ 6 - 0
src/views/worker/inspectionWork/index.vue

@@ -10,3 +10,9 @@ import InspectionRecord from "./inspectionRecord.vue";
 import PatrolCalendar from "./patrolCalendar.vue";
 import PatrolTask from "./patrolTask.vue";
 </script>
+
+
+
+
+
+

+ 217 - 0
src/views/worker/riskManagement/HiddenSource.vue

@@ -0,0 +1,217 @@
+<!--隐患源排查-->
+
+<template>
+  <van-tabs v-model:active="activeName">
+    <van-tab title="隐患源排查" name="1">
+      <van-list
+        v-model:loading="loading"
+        v-model:error="error"
+        error-text="请求失败,点击重新加载"
+        :finished="finished"
+        finished-text="没有更多事件了"
+        class="list"
+        @load="getlist"
+      >
+        <div
+          v-for="(item, index) in taskData"
+          :key="item.id"
+          class="event-list-item"
+        >
+          <div class="item-title">
+            <div class="item-title-text">隐患源排查</div>
+            <div class="item-title-control">
+              <van-button type="primary" @click="handleStartEvent(index)">
+                上报
+              </van-button>
+            </div>
+          </div>
+          <div class="item-content">
+            <div class="item-data">
+              <div class="item-left">
+                <i class="icon4" />
+                <div class="item-data-label">巡检周期:</div>
+              </div>
+              <div class="item-data-value">{{ item.cycle }}</div>
+            </div>
+            <div class="item-data">
+              <div class="item-left">
+                <i class="icon4" />
+                <div class="item-data-label">巡检范围:</div>
+              </div>
+              <div class="item-data-value">{{ item.area }}</div>
+            </div>
+            <div class="item-data">
+              <div class="item-left">
+                <i class="icon4" />
+                <div class="item-data-label">要求巡检时间:</div>
+              </div>
+              <div class="item-data-value">{{ item.task_time }}</div>
+            </div>
+          </div>
+        </div>
+      </van-list>
+    </van-tab>
+  </van-tabs>
+</template>
+<script setup lang="ts">
+import { ref, onMounted, toRefs } from "vue";
+import { getTaskList } from "@/api/riskManagement";
+
+const total = ref(0);
+const loading = ref(false);
+const error = ref(false);
+const finished = ref(false);
+const name = ref("");
+
+const activeName = ref(0);
+const taskData = ref([]);
+
+const getlist = async () => {
+  try {
+    loading.value = true;
+    const res = await getTaskList("1");
+    loading.value = false;
+    taskData.value = res.data;
+    total.value = res.total;
+    // console.log(taskData);
+  } catch (error) {
+    console.error("请求失败", error);
+  }
+};
+onMounted(() => {
+  getlist();
+});
+</script>
+
+<style lang="scss" scoped>
+.list {
+  height: calc(100vh - 102px);
+  overflow-y: auto;
+}
+.van-doc-block__title {
+  color: var(--van-doc-text-color-4);
+  margin: 0;
+  padding: 32px 16px 16px;
+  font-size: 14px;
+  font-weight: 400;
+  line-height: 16px;
+}
+
+.event-list-item {
+  position: relative;
+  margin: 16px 16px 0;
+  background: #ffffff;
+  border-radius: 4px;
+  border: 0.5px solid #eaedf7;
+  box-shadow: 0 0 4px 0 #4554661a;
+  &:first-child {
+    margin-top: 0;
+  }
+  .item-title {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    min-height: 46px;
+    background-image: linear-gradient(180deg, #f3f7fd 0%, #ffffff 100%);
+    padding: 0 12px;
+    .item-title-text {
+      font-size: 16px;
+      color: #414f64;
+      font-weight: 600;
+    }
+
+    .item-title-control {
+      display: inline-flex;
+      justify-content: center;
+      align-items: center;
+    }
+    .van-button {
+      width: 73px;
+      height: 24px;
+      padding: 0;
+    }
+  }
+  .item-content {
+    padding: 0 12px 12px;
+  }
+  .item-data {
+    font-size: 14px;
+    display: flex;
+    flex-direction: row;
+    align-items: flex-start;
+    justify-content: start;
+    line-height: 26px;
+    .item-left {
+      display: flex;
+      align-items: center;
+      flex-shrink: 0;
+    }
+    .item-data-label {
+      flex-shrink: 0;
+      color: #414f64;
+    }
+
+    .item-data-value {
+      color: #414f64;
+    }
+  }
+}
+.van-dropdown-menu {
+  :deep(.van-dropdown-menu__bar) {
+    background: transparent;
+    box-shadow: none;
+  }
+}
+.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;
+    }
+  }
+}
+.icon1 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon1.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon2 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon2.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon3 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon3.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon4 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon4.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon5 {
+  width: 16px;
+  height: 16px;
+  background: url("@/assets/images/event/icon5.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+</style>

+ 5 - 0
src/views/worker/riskManagement/InvestigationRecords.vue

@@ -0,0 +1,5 @@
+<!--排查记录-->
+<template></template>
+
+<script lang="ts"></script>
+

+ 4 - 0
src/views/worker/riskManagement/dangerousSource.vue

@@ -0,0 +1,4 @@
+<!--危险源排查-->
+<template></template>
+
+<script lang="ts" setup></script>

+ 10 - 67
src/views/worker/riskManagement/index.vue

@@ -1,73 +1,16 @@
 <template>
-  <van-tabs v-model:active="active" type="card">
-    <van-tab title="风险源排查">
-      <div v-for="(item, index) in menuData" :key="index" class="task-item">
-        <div class="header">
-          <h>风险源排查任务</h>
-          <van-button type="primary" class="report-button">上报</van-button>
-        </div>
-        <p>巡检周期: {{ item.name }}</p>
-        <p>巡检范围: {{ item.range }}</p>
-        <p>要求巡检时间: {{ item.time }}</p>
-        <hr />
-      </div>
-    </van-tab>
-    <van-tab title="隐患源排查">
-      <div v-for="(item, index) in menuData" :key="index" class="task-item">
-        <div class="header">
-          <h>隐患源排查任务</h>
-          <van-button type="primary" class="report-button">上报</van-button>
-        </div>
-        <p>巡检周期: {{ item.name }}</p>
-        <p>巡检范围: {{ item.range }}</p>
-        <p>要求巡检时间: {{ item.time }}</p>
-        <hr />
-      </div>
-    </van-tab>
-    <van-tab title="危险源排查">
-      <div v-for="(item, index) in menuData" :key="index" class="task-item">
-        <div class="header">
-          <h>危险源排查任务</h>
-          <van-button type="primary" class="report-button">上报</van-button>
-        </div>
-        <p>巡检周期: {{ item.name }}</p>
-        <p>巡检范围: {{ item.range }}</p>
-        <p>要求巡检时间: {{ item.time }}</p>
-        <hr />
-      </div>
-    </van-tab>
-    <van-tab title="排查记录"></van-tab>
+  <van-tabs v-model:active="active">
+    <van-tab label="风险源排查" name="0"><riskSource /></van-tab>
+    <van-tab label="隐患源排查" name="1"><HiddenSource /></van-tab>
+    <van-tab label="危险源排查" name="2"><dangerousSource /></van-tab>
+    <van-tab label="排查记录"><investigationRecords /></van-tab>
   </van-tabs>
 </template>
 <script setup lang="ts">
-import { reactive, ref } from "vue";
+import riskSource from "./riskSource.vue";
+import HiddenSource from "./HiddenSource.vue";
+import dangerousSource from "./dangerousSource.vue";
+import investigationRecords from "./investigationRecords.vue";
+import { ref } from "vue";
 const active = ref(0);
-// 接口
-const getlist = index => {
-  console.log(index);
-};
-const menuData = reactive([
-  { name: "每周", range: "辖区内", time: "2024-10-10" },
-  { name: "每年", range: "辖区内", time: "2024-10-11" },
-  { name: "每月", range: "辖区内", time: "2024-10-12" },
-  { name: "每日", range: "辖区内", time: "2024-10-13" },
-  { name: "每周", range: "辖区内", time: "2024-10-14" }
-]);
 </script>
-
-<style scoped>
-.task-item .header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-
-.task-item .header h {
-  margin: 0;
-  flex: 1; /* 使标题占据尽可能多的空间 */
-}
-
-.task-item .header .report-button {
-  margin-left: auto; /* 将按钮推到最右边 */
-}
-</style>

+ 216 - 0
src/views/worker/riskManagement/riskSource.vue

@@ -0,0 +1,216 @@
+<!--风险源排查-->
+<template>
+  <van-tabs v-model:active="activeName">
+    <van-tab title="风险源排查" name="0">
+      <van-list
+        v-model:loading="loading"
+        v-model:error="error"
+        error-text="请求失败,点击重新加载"
+        :finished="finished"
+        finished-text="没有更多事件了"
+        class="list"
+        @load="getlist"
+      >
+        <div
+          v-for="(item, index) in taskData"
+          :key="item.id"
+          class="event-list-item"
+        >
+          <div class="item-title">
+            <div class="item-title-text">风险源排查</div>
+            <div class="item-title-control">
+              <van-button type="primary" @click="handleStartEvent(index)">
+                上报
+              </van-button>
+            </div>
+          </div>
+          <div class="item-content">
+            <div class="item-data">
+              <div class="item-left">
+                <i class="icon4" />
+                <div class="item-data-label">巡检周期:</div>
+              </div>
+              <div class="item-data-value">{{ item.cycle }}</div>
+            </div>
+            <div class="item-data">
+              <div class="item-left">
+                <i class="icon4" />
+                <div class="item-data-label">巡检范围:</div>
+              </div>
+              <div class="item-data-value">{{ item.area }}</div>
+            </div>
+            <div class="item-data">
+              <div class="item-left">
+                <i class="icon4" />
+                <div class="item-data-label">要求巡检时间:</div>
+              </div>
+              <div class="item-data-value">{{ item.task_time }}</div>
+            </div>
+          </div>
+        </div>
+      </van-list>
+    </van-tab>
+  </van-tabs>
+</template>
+<script setup lang="ts">
+import { ref, onMounted, toRefs } from "vue";
+import { getTaskList } from "@/api/riskManagement";
+
+const total = ref(0);
+const loading = ref(false);
+const error = ref(false);
+const finished = ref(false);
+const name = ref("");
+
+const activeName = ref(0);
+const taskData = ref([]);
+
+const getlist = async () => {
+  try {
+    loading.value = true;
+    const res = await getTaskList("0");
+    loading.value = false;
+    taskData.value = res.data;
+    total.value = res.total;
+    // console.log(taskData);
+  } catch (error) {
+    console.error("请求失败", error);
+  }
+};
+onMounted(() => {
+  getlist();
+});
+</script>
+
+<style lang="scss" scoped>
+.list {
+  height: calc(100vh - 102px);
+  overflow-y: auto;
+}
+.van-doc-block__title {
+  color: var(--van-doc-text-color-4);
+  margin: 0;
+  padding: 32px 16px 16px;
+  font-size: 14px;
+  font-weight: 400;
+  line-height: 16px;
+}
+
+.event-list-item {
+  position: relative;
+  margin: 16px 16px 0;
+  background: #ffffff;
+  border-radius: 4px;
+  border: 0.5px solid #eaedf7;
+  box-shadow: 0 0 4px 0 #4554661a;
+  &:first-child {
+    margin-top: 0;
+  }
+  .item-title {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    min-height: 46px;
+    background-image: linear-gradient(180deg, #f3f7fd 0%, #ffffff 100%);
+    padding: 0 12px;
+    .item-title-text {
+      font-size: 16px;
+      color: #414f64;
+      font-weight: 600;
+    }
+
+    .item-title-control {
+      display: inline-flex;
+      justify-content: center;
+      align-items: center;
+    }
+    .van-button {
+      width: 73px;
+      height: 24px;
+      padding: 0;
+    }
+  }
+  .item-content {
+    padding: 0 12px 12px;
+  }
+  .item-data {
+    font-size: 14px;
+    display: flex;
+    flex-direction: row;
+    align-items: flex-start;
+    justify-content: start;
+    line-height: 26px;
+    .item-left {
+      display: flex;
+      align-items: center;
+      flex-shrink: 0;
+    }
+    .item-data-label {
+      flex-shrink: 0;
+      color: #414f64;
+    }
+
+    .item-data-value {
+      color: #414f64;
+    }
+  }
+}
+.van-dropdown-menu {
+  :deep(.van-dropdown-menu__bar) {
+    background: transparent;
+    box-shadow: none;
+  }
+}
+.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;
+    }
+  }
+}
+.icon1 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon1.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon2 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon2.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon3 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon3.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon4 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon4.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon5 {
+  width: 16px;
+  height: 16px;
+  background: url("@/assets/images/event/icon5.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+</style>