|
|
@@ -1,36 +1,47 @@
|
|
|
<template>
|
|
|
<div class="weather-card">
|
|
|
- <div class="time-info">
|
|
|
- <span class="line"></span>
|
|
|
- <span class="title">今日天气</span>
|
|
|
- <span class="location">上海市</span>
|
|
|
- <span class="date">{{ currentDate }}</span>
|
|
|
- <span class="week">{{ currentWeek }}</span>
|
|
|
- <span class="time">{{ currentTime }}</span>
|
|
|
- </div>
|
|
|
- <div class="main-content">
|
|
|
- <WeatherInfo
|
|
|
- :type="weatherInfo.type"
|
|
|
- :temperature="weatherInfo.temperature"
|
|
|
- :humidity="weatherInfo.humidity"
|
|
|
- :windSpeed="weatherInfo.windSpeed"
|
|
|
- :warning="weatherInfo.warning"
|
|
|
- />
|
|
|
- <div class="info-box">
|
|
|
- <WeatherTips :title="measureTitle" :measure="measureInfo" />
|
|
|
+ <div class="cloud-bg">
|
|
|
+ <div class="basic-info">
|
|
|
+ <div>
|
|
|
+ <div class="location">上海市</div>
|
|
|
+ <div class="date-time">
|
|
|
+ <span>{{ currentDate }}</span>
|
|
|
+ <span>{{ currentWeek }}</span>
|
|
|
+ <span>{{ currentTime }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="weather-info">
|
|
|
+ <div class="temperature">{{ curTemperature || '--' }}℃</div>
|
|
|
+ <div class="wind">
|
|
|
+ <div>
|
|
|
+ 风速:
|
|
|
+ <span class="wind-value">{{ curWindVelocity || '--' }} km/h</span>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ 风力:
|
|
|
+ <span class="wind-value">{{ windSpeedLevel || '--' }}级</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="disaster-emergency-tips">
|
|
|
+ <WeatherTips :title="measureTitle" :measure="measureInfo" :disasterWarningList="todayWarningInfo" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
- import { onMounted, onUnmounted, ref } from 'vue';
|
|
|
+ import { onMounted, onUnmounted, ref, watch } from 'vue';
|
|
|
import dayjs from 'dayjs';
|
|
|
- import WeatherInfo from './weather-info/WeatherInfo.vue';
|
|
|
import WeatherTips from './weather-info/WeatherTips.vue';
|
|
|
- import { DisasterTimeSpan } from '@/views/disaster/overview/components/disaster-warning-records/constant';
|
|
|
import { SysDictDataDetail, queryDictTypeDetail } from '@/api/dict';
|
|
|
- import { getDisasterWarningRecords } from '@/api/disaster-overview';
|
|
|
+ import { getTodayDisasterWarnInfoList, getRealTimeWeatherData } from '@/api/disaster-overview';
|
|
|
+
|
|
|
+ export interface DisasterWarningListType {
|
|
|
+ disasterType: string;
|
|
|
+ disasterName: string;
|
|
|
+ }
|
|
|
|
|
|
const currentDate = ref('');
|
|
|
const currentWeek = ref('');
|
|
|
@@ -38,21 +49,47 @@
|
|
|
let timer: NodeJS.Timeout;
|
|
|
const weatherDisasterDic = ref<SysDictDataDetail[]>([]); // 气象灾害预警字典
|
|
|
const disasterMeasureDic = ref<SysDictDataDetail[]>([]); // 灾害应急措施字典
|
|
|
+ const todayWarningInfo = ref<DisasterWarningListType[]>([]); // 今日灾害预警信息TODO:
|
|
|
const measureTitle = ref<string | undefined>('');
|
|
|
const measureInfo = ref<string | undefined>('');
|
|
|
|
|
|
- const weatherInfo = ref({
|
|
|
- // type: 'storm',
|
|
|
- // temperature: 26,
|
|
|
- // humidity: 91,
|
|
|
- // windSpeed: '东北风3级',
|
|
|
- // warning: '',
|
|
|
- type: '',
|
|
|
- temperature: undefined,
|
|
|
- humidity: undefined,
|
|
|
- windSpeed: '',
|
|
|
- warning: '',
|
|
|
- });
|
|
|
+ const curTemperature = ref('0');
|
|
|
+ const curWindVelocity = ref(0);
|
|
|
+ const windSpeedLevel = ref(0);
|
|
|
+ // 风速km/h等级换算表
|
|
|
+ const windLevels = [
|
|
|
+ { max: 1, level: 0 },
|
|
|
+ { max: 5, level: 1 },
|
|
|
+ { max: 11, level: 2 },
|
|
|
+ { max: 19, level: 3 },
|
|
|
+ { max: 28, level: 4 },
|
|
|
+ { max: 38, level: 5 },
|
|
|
+ { max: 49, level: 6 },
|
|
|
+ { max: 61, level: 7 },
|
|
|
+ { max: 74, level: 8 },
|
|
|
+ { max: 88, level: 9 },
|
|
|
+ { max: 102, level: 10 },
|
|
|
+ { max: 117, level: 11 },
|
|
|
+ { max: 133, level: 12 },
|
|
|
+ { max: 149, level: 13 },
|
|
|
+ { max: 166, level: 14 },
|
|
|
+ { max: 183, level: 15 },
|
|
|
+ { max: 201, level: 16 },
|
|
|
+ { max: 220, level: 17 },
|
|
|
+ { max: Infinity, level: 18 },
|
|
|
+ ];
|
|
|
+
|
|
|
+ const getWindLevel = (windSpeedKmh: number): number => {
|
|
|
+ const matched = windLevels.find(({ max }) => windSpeedKmh <= max);
|
|
|
+ return matched ? matched.level : 18;
|
|
|
+ };
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => curWindVelocity.value,
|
|
|
+ (newVal) => {
|
|
|
+ windSpeedLevel.value = getWindLevel(newVal);
|
|
|
+ },
|
|
|
+ );
|
|
|
|
|
|
// 更新时间函数
|
|
|
const updateDateTime = () => {
|
|
|
@@ -62,42 +99,47 @@
|
|
|
currentTime.value = now.format('HH:mm:ss');
|
|
|
};
|
|
|
|
|
|
+ // 获取实时天气数据
|
|
|
+ const getRealTimeWeatherDataInfo = async () => {
|
|
|
+ const res = await getRealTimeWeatherData();
|
|
|
+ curTemperature.value = res?.temperature || '0';
|
|
|
+ curWindVelocity.value = (res?.windVelocity || 0) * 3.6;
|
|
|
+ };
|
|
|
+
|
|
|
+ function getWeatherWarningType(val: string) {
|
|
|
+ const match = val.match(/^[a-zA-Z0-9]+/);
|
|
|
+ if (!match) return;
|
|
|
+ return match[0];
|
|
|
+ }
|
|
|
+
|
|
|
// 获取今日灾害预警信息
|
|
|
const getTodayWarningInfo = async () => {
|
|
|
- const weekDisasterInfo = await getDisasterWarningRecords(DisasterTimeSpan.ONE_WEEK);
|
|
|
- const weekDisasterInfoList = weekDisasterInfo[0].warnRecord;
|
|
|
+ todayWarningInfo.value = (await getTodayDisasterWarnInfoList())?.map((item) => ({
|
|
|
+ disasterType: item.disasterType,
|
|
|
+ disasterName:
|
|
|
+ weatherDisasterDic.value.find((dic) => dic.itemCode === item.disasterType)?.itemValue || '未知预警信息',
|
|
|
+ }));
|
|
|
+
|
|
|
const normalMeasure = disasterMeasureDic.value.find((item) => item.itemCode === 'normal_measure');
|
|
|
|
|
|
- if (weekDisasterInfoList.length === 0) {
|
|
|
- weatherInfo.value.warning = '未发布灾害预警';
|
|
|
- measureInfo.value = normalMeasure?.itemValue;
|
|
|
+ if (todayWarningInfo.value.length === 0) {
|
|
|
measureTitle.value = '安全提示';
|
|
|
+ measureInfo.value = normalMeasure?.itemValue || '暂无提示';
|
|
|
} else {
|
|
|
- const today = dayjs().format('YYYY-MM-DD');
|
|
|
- const todayWarning = weekDisasterInfoList.find((item) => item.warnTime.includes(today));
|
|
|
- if (todayWarning) {
|
|
|
- weatherInfo.value.warning =
|
|
|
- weatherDisasterDic.value.find((item) => item.itemCode === todayWarning.disasterType)?.itemValue || '';
|
|
|
- const weatherWarningType = getWeatherWarningType(todayWarning.disasterType);
|
|
|
+ const todayWarningValue = todayWarningInfo.value.find(
|
|
|
+ (item) => item.disasterType === todayWarningInfo.value[0].disasterType,
|
|
|
+ )?.disasterType;
|
|
|
+ if (todayWarningValue) {
|
|
|
+ const weatherWarningType = getWeatherWarningType(todayWarningValue);
|
|
|
if (weatherWarningType) {
|
|
|
const targetMeasure = disasterMeasureDic.value.find((item) => item.itemCode.includes(weatherWarningType));
|
|
|
- measureInfo.value = targetMeasure ? targetMeasure?.itemValue : normalMeasure?.itemValue;
|
|
|
- measureTitle.value = targetMeasure ? '应急提示' : '安全提示';
|
|
|
+ measureTitle.value = targetMeasure?.itemValue ? '应急提示' : '安全提示';
|
|
|
+ measureInfo.value = targetMeasure?.itemValue || normalMeasure?.itemValue;
|
|
|
}
|
|
|
- } else {
|
|
|
- weatherInfo.value.warning = '未发布灾害预警';
|
|
|
- measureInfo.value = normalMeasure?.itemValue;
|
|
|
- measureTitle.value = '安全提示';
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- function getWeatherWarningType(val: string) {
|
|
|
- const match = val.match(/^[a-zA-Z0-9]+/);
|
|
|
- if (!match) return;
|
|
|
- return match[0];
|
|
|
- }
|
|
|
-
|
|
|
onMounted(async () => {
|
|
|
await queryDictTypeDetail('weather_warning').then((res) => {
|
|
|
weatherDisasterDic.value = res.sysDictDataList;
|
|
|
@@ -107,6 +149,7 @@
|
|
|
});
|
|
|
updateDateTime();
|
|
|
timer = setInterval(updateDateTime, 1000);
|
|
|
+ getRealTimeWeatherDataInfo();
|
|
|
getTodayWarningInfo();
|
|
|
});
|
|
|
|
|
|
@@ -119,52 +162,70 @@
|
|
|
.weather-card {
|
|
|
width: 100%;
|
|
|
height: 267px;
|
|
|
- background: linear-gradient(90deg, #7ea7fe 0%, #a4cdc9 100%);
|
|
|
+ background: linear-gradient(90deg, #b4ccff 0%, #e4fbf9 100%);
|
|
|
border-radius: 4px;
|
|
|
- position: relative;
|
|
|
+ }
|
|
|
|
|
|
- .time-info {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
+ .cloud-bg {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ padding: 16px;
|
|
|
+ background-image: url('@/assets/images/disaster-overview/cloud-bg.png');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: left top;
|
|
|
+ background-size: auto 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .basic-info {
|
|
|
+ width: 305px;
|
|
|
+ margin: 4px 35px 32px 12px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-between;
|
|
|
+
|
|
|
+ .location {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 20px;
|
|
|
+ color: #0f3d7d;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-time {
|
|
|
+ font-weight: 400;
|
|
|
font-size: 16px;
|
|
|
- color: #000;
|
|
|
- padding-top: 12px;
|
|
|
-
|
|
|
- .line {
|
|
|
- width: 3px;
|
|
|
- height: 16px;
|
|
|
- background: #1777ff;
|
|
|
- margin-right: 12px;
|
|
|
- }
|
|
|
+ color: #0f3d7d;
|
|
|
+ display: flex;
|
|
|
+ gap: 6px;
|
|
|
+ }
|
|
|
|
|
|
- .title {
|
|
|
- font-weight: 500;
|
|
|
- font-size: 16px;
|
|
|
- color: #000000;
|
|
|
- }
|
|
|
+ .weather-info {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
|
|
|
- .location {
|
|
|
- margin-left: 48px;
|
|
|
+ .temperature {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 63px;
|
|
|
+ color: #0f3d7d;
|
|
|
}
|
|
|
|
|
|
- .date {
|
|
|
- margin-left: 20px;
|
|
|
+ .wind {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 7px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #0f3d7d;
|
|
|
}
|
|
|
|
|
|
- .week,
|
|
|
- .time {
|
|
|
- margin-left: 10px;
|
|
|
+ .wind-value {
|
|
|
+ font-weight: 500;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- .main-content {
|
|
|
- height: 227px;
|
|
|
- display: flex;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
- .info-box {
|
|
|
+ .disaster-emergency-tips {
|
|
|
flex: 1;
|
|
|
- margin: 20px 20px 10px 0;
|
|
|
}
|
|
|
</style>
|