123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571 |
- <template>
- <div class="menu-content">
- <div class="warning-info">
- <div class="gradient-text common-dialog-title2">预警信号</div>
- <!-- 当前时间显示 -->
- <div class="current-time">
- <div>日期</div>
- <div class="line" />
- <div class="gradient-text3 text1">{{ formattedTime.month }}</div>
- <div>月</div>
- <div class="gradient-text3 text1">{{ formattedTime.day }}</div>
- <div>日</div>
- <div class="gradient-text3 text2" style="margin-left: 12px">{{ formattedTime.hour }}</div>
- <div class="gradient-text3 text2">:</div>
- <div class="gradient-text3 text2">{{ formattedTime.minute }}</div>
- </div>
- <!-- 生效预警列表 -->
- <div class="alert-boxes">
- <div class="common-title-box">生效预警</div>
- <div class="alert-items">
- <div v-for="(item, index) in activeAlerts" :key="index" class="data-box1" @click="handleSelect(item)">
- <img v-if="item.type === '台风'" src="@/assets/images/map/warningInfo/by_1.png" class="alert-icon" />
- <img v-else-if="item.type === '暴雨预警'" src="@/assets/images/map/warningInfo/by_2.png" class="alert-icon" />
- <img v-else-if="item.type === '雷雨大风'" src="@/assets/images/map/warningInfo/by_3.png" class="alert-icon" />
- <img v-else-if="item.type === '高温'" src="@/assets/images/map/warningInfo/by_4.png" class="alert-icon" />
- <div class="box-text1">{{ item.type }}</div>
- <div :class="item.type === selectedType ? 'checked1' : 'checked2'" />
- </div>
- </div>
- </div>
- <!-- 发布数量统计 -->
- <div class="alert-count">
- <h3 class="common-title-box">发布数量统计</h3>
- <div class="alert-count-items">
- <img src="../../../assets/images/map/warningInfo/ic_number_releases.png" alt="发布数量统计" class="count-icon" />
- <div v-for="(count, index) in alertCounts" :key="index" class="count-item">
- <span :class="getTextClass(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">
- <div class="common-table">
- <div class="table-header">
- <div class="td">
- <el-select
- v-model="selectedType"
- placeholder="类型"
- class="custom-select2"
- popper-class="custom-select-popper2"
- :teleported="false"
- style="width: 100px"
- @change="fetchAlertDetails"
- >
- <el-option label="全部" value="" />
- <el-option v-for="(item, index) in activeAlerts" :key="index" :label="item.type" :value="item.type" />
- </el-select>
- </div>
- <div class="td">
- <el-select
- v-model="selectedLevel"
- placeholder="等级"
- size="large"
- class="custom-select2"
- popper-class="custom-select-popper2"
- :teleported="false"
- style="width: 80px"
- @change="fetchAlertDetails"
- >
- <el-option label="全部" value="" />
- <el-option v-for="item in alertLevels" :key="item.value" :label="item.name" :value="item.value" />
- </el-select>
- </div>
- <div class="td">区域</div>
- <div class="td">发布时间</div>
- </div>
- <div v-for="(item, index) in alertDetails" :key="index">
- <div class="tr">
- <div class="td">{{ item.type }}</div>
- <div :class="['level-icon', 'td', item.level.toLowerCase()]">
- <img :src="getWarningImage(item.type, item.level)" style="height: 60px"/>
- </div>
- <div class="td">{{ item.area }}</div>
- <div class="td">{{ item.release_time }}</div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script lang="ts" setup name="WarningInfo">
- import { getWarningInfoList, getWarningInfoCount, getWarningInfoDetail } from '@/api/globalMap/warningInfo';
- import redWarningImg from '@/assets/images/map/warningInfo/bg_1_warning.png';
- import orangeWarningImg from '@/assets/images/map/warningInfo/bg_2_warning.png';
- import yellowWarningImg from '@/assets/images/map/warningInfo/bg_3_warning.png';
- import blueWarningImg from '@/assets/images/map/warningInfo/bg_4_warning.png';
- import whiteWarningImg from '@/assets/images/map/warningInfo/bg_5_warning.png';
- import rainstormYellowImg from '@/assets/images/map/warningInfo/ic_rainstorm_yellow.png';
- import rainstormWhiteImg from '@/assets/images/map/warningInfo/ic_rainstorm_white.png';
- import rainstormRedImg from '@/assets/images/map/warningInfo/ic_rainstorm_red.png';
- import rainstormOrangeImg from '@/assets/images/map/warningInfo/ic_rainstorm_orange.png';
- import rainstormBlueImg from '@/assets/images/map/warningInfo/ic_rainstorm_blue.png';
- import temperatureBlue from '@/assets/images/map/warningInfo/ic_temperature_blue.png';
- import temperatureOrange from '@/assets/images/map/warningInfo/ic_temperature_orange.png';
- import temperatureRed from '@/assets/images/map/warningInfo/ic_temperature_red.png';
- import temperatureWhite from '@/assets/images/map/warningInfo/ic_temperature_white.png';
- import temperatureYellow from '@/assets/images/map/warningInfo/ic_temperature_yellow.png';
- import thunderStormBlue from '@/assets/images/map/warningInfo/ic_thunderstorm_blue.png';
- import thunderStormOrange from '@/assets/images/map/warningInfo/ic_thunderstorm_orange.png';
- import thunderStormRed from '@/assets/images/map/warningInfo/ic_thunderstorm_red.png';
- import thunderStormWhite from '@/assets/images/map/warningInfo/ic_thunderstorm_white.png';
- import thunderStormYellow from '@/assets/images/map/warningInfo/ic_thunderstorm_yellow.png';
- import typhoonBlue from '@/assets/images/map/warningInfo/ic_typhoon_blue.png';
- import typhoonOrange from '@/assets/images/map/warningInfo/ic_typhoon_orange.png';
- import typhoonRed from '@/assets/images/map/warningInfo/ic_typhoon_red.png';
- import typhoonWhite from '@/assets/images/map/warningInfo/ic_typhoon_white.png';
- import typhoonYellow from '@/assets/images/map/warningInfo/ic_typhoon_yellow.png';
- const alertCounts = ref<any[]>([]);
- const activeAlerts = ref<any[]>([]);
- const alertDetails = ref<any[]>([]);
- const alertLevels = ref([
- { name: '红色', value: '5' },
- { name: '橙色', value: '4' },
- { name: '黄色', value: '3' },
- { name: '蓝色', value: '2' },
- { name: '白色', value: '1' },
- ]);
- 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 } = {
- '5': redWarningImg,
- '4': orangeWarningImg,
- '3': yellowWarningImg,
- '2': blueWarningImg,
- '1': whiteWarningImg
- };
- // 预警等级与中文名称的映射
- const levelNames: { [key: string]: string } = {
- '5': '红色',
- '4': '橙色',
- '3': '黄色',
- '2': '蓝色',
- '1': '白色'
- };
- const getTextClass = (value) => {
- if (value === '5') {
- return 'count-num text-red';
- } else if (value === '4') {
- return 'count-num text-orange';
- } else if (value === '3') {
- return 'count-num text-yellow';
- } else if (value === '2') {
- return 'count-num text-blue';
- } else {
- return 'count-num';
- }
- };
- const getLevelImage = (level: string) => {
- return levelImages[level] || '';
- };
- const levelImages2 = {
- '暴雨预警': {
- '5': rainstormRedImg,
- '4': rainstormOrangeImg,
- '3': rainstormYellowImg,
- '2': rainstormBlueImg,
- '1': rainstormWhiteImg
- },
- '高温': {
- '5': temperatureRed,
- '4': temperatureOrange,
- '3': temperatureYellow,
- '2': temperatureBlue,
- '1': temperatureWhite
- },
- '雷雨大风': {
- '5': thunderStormRed,
- '4': thunderStormOrange,
- '3': thunderStormYellow,
- '2': thunderStormBlue,
- '1': thunderStormWhite
- },
- '台风': {
- '5': typhoonRed,
- '4': typhoonOrange,
- '3': typhoonYellow,
- '2': typhoonBlue,
- '1': typhoonWhite
- }
- };
- const getWarningImage = (type, level) => {
- const warningImage = levelImages2[type];
- return warningImage ? warningImage[level] : null;
- };
- // 获取预警等级的中文名称
- const getLevelName = (level: string) => {
- return levelNames[level] || '未知';
- };
- // 获取发布数量统计
- const fetchAlertCounts = async () => {
- try {
- const response = await getWarningInfoCount();
- alertCounts.value = response.rows.reverse() || [];
- console.log('alertCounts:', alertCounts.value);
- } catch (error) {
- console.error('获取发布数量统计失败:', error);
- errorMessage.value = '获取发布数量统计失败';
- }
- };
- // 获取生效预警列表
- const fetchActiveAlerts = async () => {
- getWarningInfoList().then((res) => {
- activeAlerts.value = res.rows;
- });
- };
- const handleSelect = (item) => {
- if (selectedType.value == item.type) {
- selectedType.value = '';
- } else {
- selectedType.value = item.type;
- }
- };
- // 获取预警明细列表
- const fetchAlertDetails = async () => {
- const query = {
- type: selectedType.value,
- level: selectedLevel.value
- };
- getWarningInfoDetail({ query }).then((response) => {
- alertDetails.value = response.rows || [];
- });
- };
- // 控制类型下拉菜单的显示
- 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 formattedTime = ref({
- month: '-',
- day: '-',
- hour: '-',
- minute: '-'
- });
- const getFormattedTime = () => {
- const date = new Date();
- formattedTime.value = {
- month: (date.getMonth() + 1).toString(),
- day: date.getDate().toString(),
- hour: date.getHours().toString().padStart(2, '0'),
- minute: date.getMinutes().toString().padStart(2, '0'),
- };
- };
- onMounted(() => {
- getFormattedTime();
- });
- </script>
- <style lang="scss" scoped>
- .menu-content {
- width: 574px;
- height: 581px;
- background: url('@/assets/images/map/rightMenu/content.png') no-repeat;
- background-size: 100% 100%;
- padding: 30px 10px 10px 15px;
- font-size: 14px;
- position: relative;
- color: #ffffff;
- }
- .warning-info {
- padding: 20px 10px;
- display: flex;
- flex-direction: column;
- height: 540px;
- overflow: auto;
- }
- .current-time {
- width: 254px;
- height: 65px;
- background: url('@/assets/images/map/warningInfo/timeBox.png') no-repeat;
- background-size: 100% 100%;
- color: #fff;
- font-size: 16px;
- display: flex;
- align-items: center;
- padding-left: 75px;
- padding-bottom: 9px;
- margin-bottom: -10px;
- margin-left: -10px;
- flex-shrink: 0;
- .line {
- margin: 0 3px 0 6px;
- }
- .text1 {
- font-weight: bold;
- background-image: linear-gradient(to bottom, #ffffff 30%, #aec9f3 50%, #2b72d6 100%);
- margin: 3px;
- }
- .text2 {
- background-image: linear-gradient(to bottom, #ffffff 30%, #aec9f3 50%, #2b72d6 100%);
- }
- }
- .level-white {
- color: blue;
- }
- .alert-items {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- flex-wrap: wrap;
- margin-top: 11px;
- cursor: pointer;
- .checked1 {
- background: url('@/assets/images/map/warningInfo/checked1.png') no-repeat;
- }
- .checked2 {
- background: url('@/assets/images/map/warningInfo/checked2.png') no-repeat;
- }
- .checked1,
- .checked2 {
- width: 16px;
- height: 16px;
- background-size: 100% 100%;
- position: absolute;
- bottom: 15px;
- right: 10px;
- }
- }
- .data-box1 {
- width: 122px;
- height: 91px;
- background: url('@/assets/images/map/warningInfo/bgBox.png') no-repeat;
- background-size: 100% 100%;
- padding-left: 40px;
- display: flex;
- flex-direction: column;
- align-items: center;
- position: relative;
- cursor: pointer;
- &:hover {
- background: url('@/assets/images/map/warningInfo/bgBox2.png') no-repeat;
- background-size: 100% 100%;
- }
- }
- .alert-icon {
- height: 42px;
- // 向左偏移 50% 的宽度,使图标居中
- margin-left: -50px;
- margin-top: 15px; /* 根据需要调整位置 */
- }
- .box-text1 {
- color: #fff;
- font-size: 14px;
- // 向左偏移 50% 的宽度,使文字居中
- margin-left: -50px;
- margin-top: auto; /* 将文字推到图片下方 */
- margin-bottom: 50px; /* 根据需要调整文字与底部的间距 */
- }
- .alert-count-items {
- width: 552px;
- height: 80px;
- background: url('@/assets/images/map/warningInfo/bg_base.png') no-repeat;
- background-size: 552px 45px;
- background-position: bottom center;
- gap: 0; /* 可选:添加间距 */
- padding: 7px; /* 根据需要调整内边距 */
- display: flex; /* 水平排列发布数量统计 */
- position: relative; /* 用于设置子元素的位置 */
- }
- .count-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- margin-left: 10px;
- }
- .count-icon {
- height: 52px;
- margin: 0; /* 移除外边距 */
- padding: 0; /* 移除内边距 */
- display: block; /* 确保图片以块级元素显示,避免因行内元素的空白字符产生间隔 */
- }
- .count-num {
- position: absolute;
- font-size: 16px;
- font-weight: bold;
- color: transparent;
- background-image: linear-gradient(to bottom, #ffffff 25%, #ffffff 100%);
- -webkit-background-clip: text;
- background-clip: text;
- display: inline-block;
- top: 10px;
- font-family: BEBAS-1;
- }
- .text-red {
- background-image: linear-gradient(to bottom, #ffffff 25%, #ff2b34 100%);
- }
- .text-orange {
- background-image: linear-gradient(to bottom, #ffffff 25%, #ff8400 100%);
- }
- .text-yellow {
- background-image: linear-gradient(to bottom, #ffffff 25%, #ffda00 100%);
- }
- .text-blue {
- background-image: linear-gradient(to bottom, #ffffff 25%, #2b72d6 100%);
- }
- .count-level {
- font-size: 14px;
- top: 38px;
- color: #fdfcfc;
- position: absolute;
- }
- .alert-details {
- margin-top: 10px;
- position: relative;
- }
- .alert-table {
- width: 100%;
- border-collapse: collapse;
- }
- .alert-table th {
- color: #fff; /* 确保表头文字颜色 */
- background: url('@/assets/images/map/warningInfo/bg_head.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_arrange.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_arrange_selected.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;
- }
- </style>
|