123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- <template>
- <div class="menu-content">
- <div class="warning-info">
- <div class="gradient-text title">预警信号</div>
- <!-- 当前时间显示 -->
- <div class="current-time" :style="{ backgroundImage: `url(${dateTimeBg})` }">日期 {{ formattedTime }}</div>
- <!-- 生效预警列表 -->
- <div class="alert-boxes">
- <div class="section-title">生效预警</div>
- <div class="alert-items">
- <div v-if="activeAlerts.some((alert) => alert.type === '台风')" class="data-box1">
- <img src="@/assets/images/map/warningInfo/by_1.png" alt="台风图标" class="alert-icon" />
- <div class="box-text1">台风</div>
- </div>
- <div v-if="activeAlerts.some((alert) => alert.type === '暴雨预警')" class="data-box2">
- <img src="@/assets/images/map/warningInfo/by_2.png" alt="暴雨图标" class="alert-icon" />
- <div class="box-text1">暴雨</div>
- </div>
- <div v-if="activeAlerts.some((alert) => alert.type === '雷雨大风')" class="data-box3">
- <img src="@/assets/images/map/warningInfo/by_3.png" alt="雷雨大风图标" class="alert-icon" />
- <div class="box-text1">雷雨大风</div>
- </div>
- <div v-if="activeAlerts.some((alert) => alert.type === '高温')" class="data-box4">
- <img src="@/assets/images/map/warningInfo/by_4.png" alt="高温图标" class="alert-icon" />
- <div class="box-text1">高温</div>
- </div>
- </div>
- </div>
- <!-- 发布数量统计 -->
- <div class="alert-count">
- <h3 class="section-title">发布数量统计</h3>
- <div class="alert-count-items">
- <img src="@/assets/images/map/warningInfo/ic_发布数量统计.png" alt="发布数量统计" class="count-icon" />
- <div v-for="(count, index) in alertCounts" :key="index" class="count-item">
- <span class="count-num">{{ count.num }}</span>
- <img :src="getLevelImage(count.level)" :alt="`${getLevelName(count.level)}预警图标`" class="count-icon" />
- <span
- :class="['count-level', `level-${getLevelName(count.level).toLowerCase()}`]"
- :style="{ color: index === alertCounts.length - 1 ? 'blue' : '#fdfcfc' }"
- >
- {{ getLevelName(count.level) }}预警
- </span>
- </div>
- </div>
- </div>
- <!-- 预警明细列表 -->
- <div class="alert-details">
- <table class="alert-table">
- <thead>
- <tr>
- <th class="dropdown-trigger">
- <el-select
- v-model="selectedType"
- placeholder="类型"
- size="large"
- class="custom-select2"
- popper-class="custom-select-popper2"
- :teleported="false"
- >
- <el-option label="全部" value="" />
- <el-option v-for="type in alertTypes" :key="type" :label="type" :value="type" />
- </el-select>
- </th>
- <th>
- <el-select
- v-model="selectedLevel"
- placeholder="等级"
- size="large"
- class="custom-select2"
- popper-class="custom-select-popper2"
- :teleported="false"
- >
- <el-option label="全部" value="" />
- <el-option v-for="level in alertLevels" :key="level" :label="level" :value="level" />
- </el-select>
- </th>
- <th>区域</th>
- <th>发布时间</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(alert, index) in alertDetails" :key="index" class="alert-row">
- <td>{{ alert.type }}</td>
- <td>
- <div :class="['level-icon', alert.level.toLowerCase()]">{{ alert.level }}</div>
- </td>
- <td>{{ alert.area }}</td>
- <td>{{ alert.release_time }}</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </template>
- <script lang="ts">
- import { defineComponent, ref, onMounted } from 'vue';
- import { getWarningInfoList, getWarningInfoCount, getWarningInfoDetail } from '@/api/globalMap/warningInfo';
- import redWarningImg from '@/assets/images/map/warningInfo/bg_1预警.png';
- import orangeWarningImg from '@/assets/images/map/warningInfo/bg_2预警.png';
- import yellowWarningImg from '@/assets/images/map/warningInfo/bg_3预警.png';
- import blueWarningImg from '@/assets/images/map/warningInfo/bg_4预警.png';
- import whiteWarningImg from '@/assets/images/map/warningInfo/bg_5预警.png';
- import dateTimeBg from '@/assets/images/map/warningInfo/bg_日期时间.png';
- export default defineComponent({
- name: 'WarningInfo',
- setup() {
- const alertCounts = ref<any[]>([]);
- const activeAlerts = ref<any[]>([]);
- const alertDetails = ref<any[]>([]);
- const alertTypes = ref(['台风', '暴雨预警', '雷雨大风', '高温']);
- const alertLevels = ref(['红色', '橙色', '黄色', '蓝色', '白色']);
- const selectedType = ref<string>(''); // 用户选择的预警类型
- const selectedLevel = ref<string>(''); // 用户选择的预警等级
- const showTypeDropdown = ref<boolean>(false); // 控制类型下拉菜单的显示
- const showLevelDropdown = ref<boolean>(false); // 控制等级下拉菜单的显示
- const loading = ref(false);
- const errorMessage = ref('');
- // 预警等级与图片的映射
- const levelImages: { [key: string]: string } = {
- '1': redWarningImg,
- '2': orangeWarningImg,
- '3': yellowWarningImg,
- '4': blueWarningImg,
- '5': whiteWarningImg
- };
- // 预警等级与中文名称的映射
- const levelNames: { [key: string]: string } = {
- '1': '红色',
- '2': '橙色',
- '3': '黄色',
- '4': '蓝色',
- '5': '白色'
- };
- const getLevelImage = (level: string) => {
- return levelImages[level] || '';
- };
- // 获取预警等级的中文名称
- const getLevelName = (level: string) => {
- return levelNames[level] || '未知';
- };
- // 获取发布数量统计
- const fetchAlertCounts = async () => {
- try {
- const response = await getWarningInfoCount();
- alertCounts.value = response.rows || [];
- console.log('alertCounts:', alertCounts.value);
- } catch (error) {
- console.error('获取发布数量统计失败:', error);
- errorMessage.value = '获取发布数量统计失败';
- }
- };
- // 获取生效预警列表
- const fetchActiveAlerts = async () => {
- try {
- const response = await getWarningInfoList();
- activeAlerts.value = response.rows || [];
- } catch (error) {
- console.error('获取生效预警列表失败:', error);
- errorMessage.value = '获取生效预警列表失败';
- }
- };
- // 获取预警明细列表
- const fetchAlertDetails = async () => {
- try {
- const query = {
- type: selectedType.value,
- level: selectedLevel.value
- };
- const response = await getWarningInfoDetail({ query });
- alertDetails.value = response.rows || [];
- } catch (error) {
- console.error('获取预警明细列表失败:', error);
- errorMessage.value = '获取预警明细列表失败';
- }
- };
- // 控制类型下拉菜单的显示
- const toggleTypeDropdown = () => {
- showTypeDropdown.value = !showTypeDropdown.value;
- showLevelDropdown.value = false; // 关闭等级下拉菜单
- };
- // 控制等级下拉菜单的显示
- const toggleLevelDropdown = () => {
- showLevelDropdown.value = !showLevelDropdown.value;
- showTypeDropdown.value = false; // 关闭类型下拉菜单
- };
- // 选择类型
- const selectType = (type: string) => {
- selectedType.value = type;
- showTypeDropdown.value = false;
- fetchAlertDetails();
- };
- // 选择等级
- const selectLevel = (level: string) => {
- selectedLevel.value = level;
- showLevelDropdown.value = false;
- fetchAlertDetails();
- };
- // 点击外部区域时关闭下拉菜单
- const wrapper = ref<HTMLElement | null>(null);
- onMounted(async () => {
- loading.value = true;
- await Promise.all([fetchAlertCounts(), fetchActiveAlerts(), fetchAlertDetails()]);
- loading.value = false;
- });
- // 监听点击事件以关闭下拉菜单
- const handleClickOutside = (event: MouseEvent) => {
- const target = event.target as HTMLElement;
- if (wrapper.value && !wrapper.value.contains(target)) {
- showTypeDropdown.value = false;
- showLevelDropdown.value = false;
- }
- };
- window.addEventListener('click', handleClickOutside);
- // 清理事件监听器
- onUnmounted(() => {
- window.removeEventListener('click', handleClickOutside);
- });
- // 当前时间相关逻辑
- const currentTime = ref(new Date());
- const formattedTime = computed(() => {
- const date = currentTime.value;
- const month = date.getMonth() + 1;
- const day = date.getDate();
- const hour = date.getHours();
- const minute = date.getMinutes();
- // 格式化为 "MM月DD日 HH时MM分"
- return `${month}月${day}日 ${hour.toString().padStart(2, '0')}时${minute.toString().padStart(2, '0')}分`;
- });
- onMounted(() => {
- // 每分钟更新一次时间
- const interval = setInterval(() => {
- currentTime.value = new Date();
- }, 60000); // 60000 毫秒 = 1 分钟
- // 清除定时器
- onUnmounted(() => {
- clearInterval(interval);
- });
- });
- return {
- alertCounts,
- activeAlerts,
- alertDetails,
- alertTypes,
- alertLevels,
- selectedType,
- selectedLevel,
- loading,
- errorMessage,
- fetchAlertDetails,
- getLevelImage,
- getLevelName,
- toggleTypeDropdown,
- toggleLevelDropdown,
- selectType,
- selectLevel,
- showTypeDropdown,
- showLevelDropdown,
- wrapper,
- formattedTime,
- dateTimeBg
- };
- }
- });
- </script>
- <style lang="scss" scoped>
- .menu-content {
- width: 1579px;
- height: 1394px;
- background: url('@/assets/images/map/rightMenu/content.png') no-repeat;
- padding: 130px 20px 20px 20px;
- font-size: 36px;
- position: relative;
- color: #000000;
- }
- .title {
- font-size: 60px;
- position: absolute;
- top: 30px;
- left: 160px;
- }
- .warning-info {
- padding: 20px;
- display: flex;
- flex-direction: column; /* 垂直排列标题和预警图标 */
- }
- .current-time {
- width: 800px; /* 根据背景图的宽度调整 */
- height: 150px; /* 根据背景图的高度调整 */
- background-size: cover; /* 背景图覆盖整个盒子 */
- background-repeat: no-repeat; /* 禁止背景图重复 */
- background-position: center; /* 背景图居中 */
- color: #fff;
- font-size: 38px; /* 根据需要调整字体大小 */
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 20px; /* 与下方内容的间距 */
- }
- .alert-boxes {
- display: flex;
- flex-direction: column; /* 纵向排列子元素 */
- }
- .section-title {
- font-size: 44px;
- color: #f4f7fa;
- background: url('@/assets/images/map/warningInfo/bg_2level_title.png') no-repeat;
- padding-left: 65px;
- height: 54px;
- display: flex;
- align-items: center; /* 垂直居中内容 */
- margin-bottom: 20px; /* 标题与图标之间的间距 */
- }
- .level-white {
- color: blue;
- }
- .alert-items {
- display: flex;
- justify-content: space-between; /* 水平排列 */
- align-items: flex-start; /* 图标与格子对齐顶部 */
- flex-wrap: wrap; /* 如果内容超出宽度,则换行 */
- margin-top: 20px;
- }
- .data-box1,
- .data-box2,
- .data-box3,
- .data-box4 {
- width: 350px; /* 每个盒子的宽度 */
- height: 260px; /* 每个盒子的高度 */
- background:
- url('@/assets/images/map/warningInfo/bg_未选中.png') no-repeat,
- url('@/assets/images/map/warningInfo/ic_未选中.png') no-repeat;
- /* 第一个背景自适应,第二个背景设置为特定大小 */
- background-size:
- contain,
- 40px 40px; /* 第一个背景自适应,第二个为40x40像素 */
- background-position:
- center,
- calc(100% - 20px) calc(100% - 20px); /* 第一个背景居中,第二个背景向左下偏移10px */
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: flex-start; /* 图标与文字对齐顶部 */
- margin-right: 10px; /* 添加间距 */
- position: relative; /* 为内部定位做准备 */
- }
- .alert-icon {
- // 向左偏移 50% 的宽度,使图标居中
- margin-left: -50px;
- margin-top: 30px; /* 根据需要调整位置 */
- }
- .box-text1 {
- color: #fff;
- font-size: 36px;
- // 向左偏移 50% 的宽度,使文字居中
- margin-left: -50px;
- margin-top: auto; /* 将文字推到图片下方 */
- margin-bottom: 50px; /* 根据需要调整文字与底部的间距 */
- }
- .alert-count {
- margin-top: 20px;
- }
- .alert-count-items {
- background: url('@/assets/images/map/warningInfo/bg_底座.png') no-repeat;
- background-size: cover;
- gap: 0; /* 可选:添加间距 */
- padding: 20px; /* 根据需要调整内边距 */
- display: flex; /* 水平排列发布数量统计 */
- position: relative; /* 用于设置子元素的位置 */
- }
- .count-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 120px; /* 根据需要调整宽度 */
- margin: 0; /* 移除外边距 */
- padding: 0; /* 移除内边距 */
- }
- .count-icon {
- width: 120px;
- height: 120px;
- margin: 0; /* 移除外边距 */
- padding: 0; /* 移除内边距 */
- display: block; /* 确保图片以块级元素显示,避免因行内元素的空白字符产生间隔 */
- }
- .count-num {
- font-size: 40px; /* 根据需要调整字体大小 */
- color: #fdfcfc;
- position: absolute; /* 相对于父元素定位 */
- }
- .count-level {
- font-size: 26px; /* 根据需要调整字体大小 */
- top: 100px; /* 根据需要调整位置 */
- color: #fdfcfc;
- position: absolute;
- }
- .alert-details {
- margin-top: 20px;
- position: relative; /* 为了下拉菜单的绝对定位 */
- }
- .alert-table {
- width: 100%;
- border-collapse: collapse;
- }
- .alert-table th {
- color: #fff; /* 确保表头文字颜色 */
- background: url('@/assets/images/map/warningInfo/bg_表头.png') no-repeat center center; /* 表头背景图 */
- background-size: cover; /* 背景图覆盖整行 */
- padding: 16px; /* 根据需要调整内边距 */
- position: relative; /* 为下拉菜单的绝对定位做准备 */
- }
- .alert-table th,
- .alert-table td {
- padding: 8px;
- text-align: left;
- }
- .alert-table .alert-row {
- background: url('@/assets/images/map/warningInfo/bg_列.png') no-repeat center center; /* 行的背景图 */
- background-size: cover; /* 背景图覆盖整行 */
- transition: background 0.3s ease; /* 添加过渡效果 */
- }
- /* 悬停效果 */
- .alert-table .alert-row:hover {
- background: url('@/assets/images/map/warningInfo/bg_列_选中.png') no-repeat center center; /* 悬停效果 */
- background-size: cover; /* 背景图覆盖整行 */
- }
- /* 确保文字可读性 */
- .alert-table td {
- color: #fff; /* 确保文字颜色与背景图对比明显 */
- }
- .dropdown-icon {
- width: 12px; /* 根据需要调整图标大小 */
- height: 12px; /* 根据需要调整图标大小 */
- margin-left: 5px; /* 图标与文字之间的间距 */
- }
- .dropdown-trigger {
- cursor: pointer;
- position: relative;
- }
- .dropdown-menu {
- position: absolute;
- top: 100%; /* 下拉菜单显示在触发器下方 */
- left: 0;
- background-color: #0c0000; /* 背景颜色 */
- border: 1px solid #ccc; /* 边框 */
- border-radius: 4px;
- z-index: 20;
- width: 150px; /* 根据需要调整宽度 */
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); /* 添加阴影 */
- }
- .dropdown-item {
- padding: 8px 12px;
- cursor: pointer;
- }
- .dropdown-item:hover,
- .dropdown-item.selected {
- background-color: #f0f0f0;
- }
- @media (max-width: 768px) {
- .alert-items {
- flex-direction: column;
- }
- .data-box1,
- .data-box2,
- .data-box3,
- .data-box4 {
- flex: none;
- width: 100%;
- margin-bottom: 10px;
- }
- .title {
- position: relative;
- left: 0;
- text-align: center;
- }
- .count-item {
- width: 100%;
- max-width: 200px;
- }
- .alert-table th,
- .alert-table td {
- background: none; /* 移除背景图以适应移动设备 */
- }
- .alert-table td:hover {
- background: none;
- }
- }
- </style>
|