|
@@ -3,26 +3,31 @@
|
|
|
<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"
|
|
|
- :clearable="false"
|
|
|
- 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"
|
|
|
+ :clearable="false"
|
|
|
+ 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"
|
|
|
+ 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>
|
|
@@ -31,19 +36,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>
|
|
@@ -55,7 +64,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(item2.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>
|
|
@@ -64,58 +78,71 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <van-dialog class="custom-dialog" v-model:show="show" title="在线点名提醒" confirmButtonText="确认点名" @confirm="handleToRollCall">
|
|
|
+ <van-dialog
|
|
|
+ v-model:show="show"
|
|
|
+ class="custom-dialog"
|
|
|
+ title="在线点名提醒"
|
|
|
+ confirmButtonText="确认点名"
|
|
|
+ @confirm="handleToRollCall"
|
|
|
+ >
|
|
|
<div class="btn" @click="handleHideDialog">浮窗显示</div>
|
|
|
<div class="line">
|
|
|
<i class="icon-tip" />
|
|
|
<div class="text1">{{ durationTime }}</div>
|
|
|
</div>
|
|
|
</van-dialog>
|
|
|
- <van-dialog class="custom-dialog2" v-model:show="show2" title="在线点名提醒" :showConfirmButton="false">
|
|
|
+ <van-dialog
|
|
|
+ v-model:show="show2"
|
|
|
+ class="custom-dialog2"
|
|
|
+ title="在线点名提醒"
|
|
|
+ :showConfirmButton="false"
|
|
|
+ >
|
|
|
<div class="dialog-content">
|
|
|
- <div class="img-box"></div>
|
|
|
+ <div class="img-box" />
|
|
|
<div v-show="!img" class="text1">即将通过摄像头捕捉画面</div>
|
|
|
<div v-show="!img" class="text2">请稍等</div>
|
|
|
- <div v-show="img" class="btn" @click="handleToRollCall2">上传视频截图</div>
|
|
|
+ <div v-show="img" class="btn" @click="handleToRollCall2">
|
|
|
+ 上传视频截图
|
|
|
+ </div>
|
|
|
<div v-show="img" class="text3">已完成</div>
|
|
|
</div>
|
|
|
</van-dialog>
|
|
|
- <div v-if="!!rollCallData.id" class="float-box" @click="show = true"></div>
|
|
|
+ <div v-if="!!rollCallData.id" class="float-box" @click="show = true" />
|
|
|
</dic>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import {onClickOutside} from "@vueuse/core";
|
|
|
-import {ref, reactive, onMounted, onUnmounted} from 'vue';
|
|
|
+import { onClickOutside } from "@vueuse/core";
|
|
|
+import { ref, reactive, onMounted, onUnmounted } 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: "OnlineRollCall" },
|
|
|
+ { name: "事件管理", icon: "icon4", num: 0, url: "EventList" }
|
|
|
]);
|
|
|
|
|
|
// 综合应用菜单
|
|
|
const menu2 = ref([
|
|
|
{
|
|
|
- name: '自然灾害风险监测',
|
|
|
+ name: "自然灾害风险监测",
|
|
|
children: [
|
|
|
{ name: '预警态势', icon: 'monitor', url: 'WarningSituation' },
|
|
|
{ name: '大风灾害', icon: 'wind', url: 'GaleDisaster' },
|
|
@@ -125,33 +152,33 @@ const menu2 = ref([
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
- 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();
|
|
@@ -162,83 +189,86 @@ 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.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 = [];
|
|
|
-}
|
|
|
+};
|
|
|
// 在线点名弹窗
|
|
|
let timer;
|
|
|
let show = ref();
|
|
|
-let durationTime = ref('');
|
|
|
+let durationTime = ref("");
|
|
|
let rollCallData = ref({
|
|
|
- id: '',
|
|
|
- time1: ''
|
|
|
-})
|
|
|
+ id: "",
|
|
|
+ time1: ""
|
|
|
+});
|
|
|
// 在线点名
|
|
|
let show2 = ref();
|
|
|
-let img = ref('');
|
|
|
+let img = ref("");
|
|
|
const handleToRollCall = () => {
|
|
|
show.value = false;
|
|
|
show2.value = true;
|
|
|
setTimeout(() => {
|
|
|
- img.value = '2';
|
|
|
- }, 3000)
|
|
|
-}
|
|
|
+ img.value = "2";
|
|
|
+ }, 3000);
|
|
|
+};
|
|
|
const handleToRollCall2 = () => {
|
|
|
router.push({
|
|
|
- name: 'RollCallDetails',
|
|
|
+ name: "RollCallDetails",
|
|
|
query: { id: rollCallData.value.id }
|
|
|
});
|
|
|
-}
|
|
|
-const calculateDuration = (startTimeStr) => {
|
|
|
+};
|
|
|
+const calculateDuration = startTimeStr => {
|
|
|
// 将起始时间字符串转换为日期对象
|
|
|
const startTime = new Date(startTimeStr);
|
|
|
|
|
@@ -247,7 +277,7 @@ const calculateDuration = (startTimeStr) => {
|
|
|
|
|
|
// 确保起始时间在结束时间之前(可选,用于验证输入)
|
|
|
if (startTime > endTime) {
|
|
|
- return '';
|
|
|
+ return "";
|
|
|
}
|
|
|
|
|
|
// 计算时间差(以毫秒为单位)
|
|
@@ -256,36 +286,36 @@ const calculateDuration = (startTimeStr) => {
|
|
|
// 将毫秒转换为秒、分钟和小时
|
|
|
const seconds = Math.floor((timeDifference / 1000) % 60);
|
|
|
const minutes = Math.floor((timeDifference / (1000 * 60)) % 60);
|
|
|
- const hours = Math.floor((timeDifference / (1000 * 60 * 60)));
|
|
|
+ const hours = Math.floor(timeDifference / (1000 * 60 * 60));
|
|
|
|
|
|
// 格式化时间为 HH:MM:SS
|
|
|
- const formattedDuration = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
|
|
|
+ const formattedDuration = `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
|
|
|
|
|
|
// 返回格式化的持续时间
|
|
|
return formattedDuration;
|
|
|
};
|
|
|
const updateTime = () => {
|
|
|
- durationTime.value = calculateDuration(rollCallData.value.time1)
|
|
|
-}
|
|
|
+ durationTime.value = calculateDuration(rollCallData.value.time1);
|
|
|
+};
|
|
|
const handleHideDialog = () => {
|
|
|
show.value = false;
|
|
|
};
|
|
|
onMounted(() => {
|
|
|
- initData()
|
|
|
- rollCallData.value = {
|
|
|
- id: '11111',
|
|
|
- time1: '2024-10-22 12:00:00'
|
|
|
- };
|
|
|
- show.value = true;
|
|
|
+ initData();
|
|
|
+ // rollCallData.value = {
|
|
|
+ // id: '11111',
|
|
|
+ // time1: '2024-10-22 12:00:00'
|
|
|
+ // };
|
|
|
+ // show.value = true;
|
|
|
if (!timer && !!rollCallData.value.time1) {
|
|
|
- timer = setInterval(updateTime, 1000)
|
|
|
+ timer = setInterval(updateTime, 1000);
|
|
|
}
|
|
|
-})
|
|
|
+});
|
|
|
onUnmounted(() => {
|
|
|
if (!!timer) {
|
|
|
- clearInterval(timer)
|
|
|
+ clearInterval(timer);
|
|
|
}
|
|
|
-})
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
@@ -298,7 +328,7 @@ onUnmounted(() => {
|
|
|
.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;
|
|
@@ -326,7 +356,6 @@ onUnmounted(() => {
|
|
|
border-top-width: 0 !important;
|
|
|
}
|
|
|
:deep(.van-grid) {
|
|
|
-
|
|
|
.van-grid-item {
|
|
|
&:nth-child(1) {
|
|
|
padding-right: 12px;
|
|
@@ -362,7 +391,7 @@ onUnmounted(() => {
|
|
|
}
|
|
|
.card-title {
|
|
|
font-size: 14px;
|
|
|
- color: #414F64;
|
|
|
+ color: #414f64;
|
|
|
}
|
|
|
}
|
|
|
.icon1 {
|
|
@@ -380,8 +409,7 @@ onUnmounted(() => {
|
|
|
.icon1,
|
|
|
.icon2,
|
|
|
.icon3,
|
|
|
- .icon4
|
|
|
- {
|
|
|
+ .icon4 {
|
|
|
width: 67px;
|
|
|
height: 67px;
|
|
|
background-size: 100% 100%;
|
|
@@ -403,7 +431,7 @@ onUnmounted(() => {
|
|
|
height: 26px;
|
|
|
font-weight: bold;
|
|
|
font-size: 18px;
|
|
|
- color: #414F64;
|
|
|
+ color: #414f64;
|
|
|
letter-spacing: 0;
|
|
|
margin-bottom: 4px;
|
|
|
}
|
|
@@ -457,7 +485,6 @@ onUnmounted(() => {
|
|
|
}
|
|
|
.common-search {
|
|
|
:deep(.van-field__left-icon) {
|
|
|
-
|
|
|
.van-icon__image {
|
|
|
width: 12px;
|
|
|
height: 12px;
|
|
@@ -480,7 +507,7 @@ onUnmounted(() => {
|
|
|
top: 10px;
|
|
|
right: 6px;
|
|
|
font-size: 12px;
|
|
|
- color: #2C81FF;
|
|
|
+ color: #2c81ff;
|
|
|
}
|
|
|
.line {
|
|
|
display: flex;
|
|
@@ -490,12 +517,12 @@ onUnmounted(() => {
|
|
|
.icon-tip {
|
|
|
width: 30px;
|
|
|
height: 31px;
|
|
|
- background: url('@/assets/images/onlineRollCall/tip.png') no-repeat;
|
|
|
+ background: url("@/assets/images/onlineRollCall/tip.png") no-repeat;
|
|
|
background-size: 100% 100%;
|
|
|
}
|
|
|
.text1 {
|
|
|
font-size: 24px;
|
|
|
- color: #2C81FF;
|
|
|
+ color: #2c81ff;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -524,24 +551,24 @@ onUnmounted(() => {
|
|
|
}
|
|
|
.text1 {
|
|
|
font-size: 14px;
|
|
|
- color: #2C81FF;
|
|
|
+ color: #2c81ff;
|
|
|
line-height: 26px;
|
|
|
}
|
|
|
.text2 {
|
|
|
font-size: 12px;
|
|
|
- color: #FFAF00;
|
|
|
+ color: #ffaf00;
|
|
|
line-height: 26px;
|
|
|
}
|
|
|
.text3 {
|
|
|
font-size: 12px;
|
|
|
- color: #40C75F;
|
|
|
+ color: #40c75f;
|
|
|
line-height: 26px;
|
|
|
}
|
|
|
.btn {
|
|
|
- background: #2C81FF;
|
|
|
+ background: #2c81ff;
|
|
|
border-radius: 2px;
|
|
|
font-size: 12px;
|
|
|
- color: #FFFFFF;
|
|
|
+ color: #ffffff;
|
|
|
padding: 3px 14px;
|
|
|
}
|
|
|
}
|