WeatherCard.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <div class="weather-card">
  3. <div class="time-info">
  4. <span class="line"></span>
  5. <span class="title">今日天气</span>
  6. <span class="location">上海市</span>
  7. <span class="date">{{ currentDate }}</span>
  8. <span class="week">{{ currentWeek }}</span>
  9. <span class="time">{{ currentTime }}</span>
  10. </div>
  11. <div class="main-content">
  12. <WeatherInfo
  13. :type="weatherInfo.type"
  14. :temperature="weatherInfo.temperature"
  15. :humidity="weatherInfo.humidity"
  16. :windSpeed="weatherInfo.windSpeed"
  17. :warning="weatherInfo.warning"
  18. />
  19. <div class="info-box">
  20. <WeatherTips :title="measureTitle" :measure="measureInfo" />
  21. </div>
  22. </div>
  23. </div>
  24. </template>
  25. <script setup lang="ts">
  26. import { onMounted, onUnmounted, ref } from 'vue';
  27. import dayjs from 'dayjs';
  28. import WeatherInfo from './weather-info/WeatherInfo.vue';
  29. import WeatherTips from './weather-info/WeatherTips.vue';
  30. import { DisasterTimeSpan } from '@/views/disaster/overview/components/disaster-warning-records/constant';
  31. import { SysDictDataDetail, queryDictTypeDetail } from '@/api/dict';
  32. import { getDisasterWarningRecords } from '@/api/disaster-overview';
  33. const currentDate = ref('');
  34. const currentWeek = ref('');
  35. const currentTime = ref('');
  36. let timer: NodeJS.Timeout;
  37. const weatherDisasterDic = ref<SysDictDataDetail[]>([]); // 气象灾害预警字典
  38. const disasterMeasureDic = ref<SysDictDataDetail[]>([]); // 灾害应急措施字典
  39. const measureTitle = ref<string | undefined>('');
  40. const measureInfo = ref<string | undefined>('');
  41. const weatherInfo = ref({
  42. type: 'sunny',
  43. temperature: 30,
  44. humidity: 56,
  45. windSpeed: '西南风2级',
  46. warning: '',
  47. });
  48. // 更新时间函数
  49. const updateDateTime = () => {
  50. const now = dayjs();
  51. currentDate.value = now.format('MM月DD日');
  52. currentWeek.value = `星期${now.format('dd').slice(-1)}`;
  53. currentTime.value = now.format('HH:mm:ss');
  54. };
  55. // 获取今日灾害预警信息
  56. const getTodayWarningInfo = async () => {
  57. const weekDisasterInfo = await getDisasterWarningRecords(DisasterTimeSpan.ONE_WEEK);
  58. const weekDisasterInfoList = weekDisasterInfo[0].warnRecord;
  59. const normalMeasure = disasterMeasureDic.value.find((item) => item.itemCode === 'normal_measure');
  60. if (weekDisasterInfoList.length === 0) {
  61. weatherInfo.value.warning = '';
  62. measureInfo.value = normalMeasure?.itemValue;
  63. measureTitle.value = '安全提示';
  64. } else {
  65. const today = dayjs().format('YYYY-MM-DD');
  66. const todayWarning = weekDisasterInfoList.find((item) => item.warnTime.includes(today));
  67. if (todayWarning) {
  68. weatherInfo.value.warning =
  69. weatherDisasterDic.value.find((item) => item.itemCode === todayWarning.disasterType)?.itemValue || '';
  70. const weatherWarningType = getWeatherWarningType(todayWarning.disasterType);
  71. if (weatherWarningType) {
  72. const targetMeasure = disasterMeasureDic.value.find((item) => item.itemCode.includes(weatherWarningType));
  73. measureInfo.value = targetMeasure ? targetMeasure?.itemValue : normalMeasure?.itemValue;
  74. measureTitle.value = targetMeasure ? '应急提示' : '安全提示';
  75. }
  76. } else {
  77. weatherInfo.value.warning = '';
  78. measureInfo.value = normalMeasure?.itemValue;
  79. measureTitle.value = '安全提示';
  80. }
  81. }
  82. };
  83. function getWeatherWarningType(val: string) {
  84. const match = val.match(/^[a-zA-Z0-9]+/);
  85. if (!match) return;
  86. return match[0];
  87. }
  88. onMounted(async () => {
  89. await queryDictTypeDetail('weather_warning').then((res) => {
  90. weatherDisasterDic.value = res.sysDictDataList;
  91. });
  92. await queryDictTypeDetail('disaster_emergency_measure').then((res) => {
  93. disasterMeasureDic.value = res.sysDictDataList;
  94. });
  95. updateDateTime();
  96. timer = setInterval(updateDateTime, 1000);
  97. getTodayWarningInfo();
  98. });
  99. onUnmounted(() => {
  100. clearInterval(timer);
  101. });
  102. </script>
  103. <style scoped>
  104. .weather-card {
  105. width: 100%;
  106. height: 267px;
  107. background: linear-gradient(90deg, #7ea7fe 0%, #a4cdc9 100%);
  108. border-radius: 4px;
  109. position: relative;
  110. .time-info {
  111. display: flex;
  112. align-items: center;
  113. font-size: 16px;
  114. color: #000;
  115. padding-top: 12px;
  116. .line {
  117. width: 3px;
  118. height: 16px;
  119. background: #1777ff;
  120. margin-right: 12px;
  121. }
  122. .title {
  123. font-weight: 500;
  124. font-size: 16px;
  125. color: #000000;
  126. }
  127. .location {
  128. margin-left: 48px;
  129. }
  130. .date {
  131. margin-left: 20px;
  132. }
  133. .week,
  134. .time {
  135. margin-left: 10px;
  136. }
  137. }
  138. .main-content {
  139. height: 227px;
  140. display: flex;
  141. }
  142. }
  143. .info-box {
  144. flex: 1;
  145. margin: 20px 20px 10px 0;
  146. }
  147. </style>