浏览代码

Merge remote-tracking branch 'origin/dev' into dev

Hwf 2 月之前
父节点
当前提交
3359a2a2c0

+ 7 - 0
src/views/globalMap/RightMenu/WindMonitor/index.vue

@@ -156,6 +156,7 @@
       </div>
     </div>
   </div>
+  <WindSpeedRank v-if="showMore" v-model="showMore" />
 </template>
 
 <script setup lang="ts">
@@ -163,6 +164,7 @@ import { onMounted, reactive } from 'vue';
 import { getHelicopterList } from '@/api/globalMap/Helicopter';
 import switchOff from '@/assets/images/map/rightMenu/windMonitor/switch-off.png';
 import switchOn from '@/assets/images/map/rightMenu/windMonitor/switch-on.png';
+import WindSpeedRank from '@/views/globalMap/RightMenu/WindMonitor/windSpeedRank.vue';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { wind_time } = toRefs<any>(proxy?.useDict('wind_time'));
@@ -172,6 +174,7 @@ const startLeft = ref(0);
 const endLeft = ref(1000);
 const lineRef = ref();
 const containerScale = inject('containerScale');
+let showMore = ref(false);
 const mouseStatus = reactive({
   move: false,
   type: '',
@@ -269,6 +272,10 @@ const handleMouseUp = (event) => {
   mouseStatus.left = 0;
 };
 
+const handleShowMore = () => {
+  showMore.value = true;
+};
+
 // 数据列表,直接定义为数组
 const dataList = ref([]);
 //入参

+ 226 - 0
src/views/globalMap/RightMenu/WindMonitor/windSpeedChart.vue

@@ -0,0 +1,226 @@
+<template>
+  <Dialog custom-show type="md" title="点位风速折线图" hide-footer @close="handleClose">
+    <div class="line">
+      <div class="title-box">
+        <div class="gradient-text">{{ rainData.address }}</div>
+      </div>
+      <div class="time-box">
+        <div class="text1">更新时间</div>
+        <div class="text2" style="margin-left: 30px">{{ parseTime(updateTime, '{m}-{d}') }}</div>
+        <div class="text2" style="margin-left: 10px">{{ parseTime(updateTime, '{h}:{i}') }}</div>
+      </div>
+    </div>
+    <Chart :option="chartOption" style="height: 1200px" />
+  </Dialog>
+</template>
+
+<script lang="ts" setup>
+import { getRainfallInfo } from '@/api/globalMap/rainMonitor';
+import { option7 } from '@/views/globalMap/RightMenu/echartOptions';
+import { graphic } from 'echarts';
+import { parseTime } from '@/utils/ruoyi';
+
+interface Props {
+  show: boolean;
+  rainData: {};
+}
+const props = withDefaults(defineProps<Props>(), {});
+const emits = defineEmits(['update:show']);
+const updateTime = ref('');
+const chartOption = ref(option7);
+const initData = () => {
+  getRainfallInfo(props.rainData.code).then((res) => {
+    updateTime.value = res.data.updateTime;
+    const data = [...res.data.rainfallHistory, ...res.data.rainfallFuture];
+    const cumulativeRainfall = res.data.cumulativeRainfall;
+    const filterData1 = [];
+    const filterData2 = [];
+    const filterData3 = [];
+    const filterData4 = [];
+    const filterData5 = [];
+    const xAxis = [];
+    const blue = [
+      '#98c3ff',
+      '#0c387b',
+      new graphic.LinearGradient(0, 0, 0, 1, [
+        {
+          offset: 0,
+          color: '#5c99f0'
+        },
+        {
+          offset: 0.25,
+          color: '#3b7ede'
+        },
+        {
+          offset: 0.5,
+          color: '#175cbc'
+        },
+        {
+          offset: 0.75,
+          color: '#064194'
+        },
+        {
+          offset: 1,
+          color: '#053171'
+        }
+      ])
+    ];
+    const green = [
+      '#60c597',
+      '#124850',
+      new graphic.LinearGradient(0, 0, 0, 1, [
+        {
+          offset: 0,
+          color: '#45c893'
+        },
+        {
+          offset: 0.25,
+          color: '#34a67b'
+        },
+        {
+          offset: 0.5,
+          color: '#1a765f'
+        },
+        {
+          offset: 0.75,
+          color: '#0f5650'
+        },
+        {
+          offset: 1,
+          color: '#10434c'
+        }
+      ])
+    ];
+    data.forEach((item, index) => {
+      const color = index < 12 ? blue : green;
+      xAxis.push(item.hour);
+      filterData1.push({
+        value: item.value !== 0 ? item.value : '',
+        itemStyle: {
+          color: color[0]
+        }
+      });
+      filterData2.push({
+        value: item.value !== 0 ? item.value : '',
+        itemStyle: {
+          color: color[1]
+        }
+      });
+      filterData3.push({
+        value: item.value !== 0 && index < 12 ? item.value : '',
+        itemStyle: {
+          color: color[2]
+        }
+      });
+      filterData4.push({
+        value: item.value !== 0 && index >= 12 ? item.value : '',
+        itemStyle: {
+          color: color[2]
+        }
+      });
+    });
+    cumulativeRainfall.forEach((item) => {
+      filterData5.push(item.value);
+    });
+    chartOption.value.xAxis[0].data = xAxis;
+    chartOption.value.series[0].data = filterData1;
+    chartOption.value.series[1].data = filterData2;
+    chartOption.value.series[2].data = filterData3;
+    chartOption.value.series[3].data = filterData4;
+    chartOption.value.series[4].data = filterData5;
+  });
+};
+initData();
+const handleClose = () => {
+  emits('update:show', false);
+};
+</script>
+
+<style lang="scss" scoped>
+.rain-chart-dialog {
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  z-index: 10;
+  width: 2001px;
+  height: 1000px;
+  background: url('@/assets/images/map/rightMenu/rainMonitor/dialog3.png') no-repeat;
+  padding: 150px 30px 20px 40px;
+  display: flex;
+  flex-direction: column;
+  align-items: flex-end;
+  .line {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+  .title-box {
+    background-image: url('@/assets/images/map/rightMenu/rainMonitor/titleBox.png');
+    background-repeat: no-repeat;
+    background-size: 370px 35px;
+    background-position: bottom left;
+    padding-left: 50px;
+    display: flex;
+    align-items: center;
+    flex: 1;
+    overflow: hidden;
+    margin-right: 50px;
+    .gradient-text {
+      font-size: 64px;
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+    }
+  }
+}
+.time-box {
+  width: 482px;
+  min-width: 482px;
+  height: 83px;
+  background: url('@/assets/images/map/rightMenu/rainMonitor/dateBox.png') no-repeat;
+  display: flex;
+  align-items: center;
+  margin: 20px 0;
+  .text1 {
+    font-size: 32px;
+    color: #fff;
+    display: flex;
+    line-height: 75px;
+    padding-left: 108px;
+  }
+  .text2 {
+    font-size: 32px;
+    font-family: BEBAS-1;
+    /* 设置字体透明 */
+    color: transparent;
+    /* 设置线性渐变,从红色渐变到蓝色 */
+    background-image: linear-gradient(to bottom, #ffffff 25%, #2b72d6 100%);
+    /* 使用 -webkit-background-clip 属性将背景剪裁至文本形状 */
+    -webkit-background-clip: text;
+    /* 非Webkit内核浏览器需要使用标准前缀 */
+    background-clip: text;
+    /* 把当前元素设置为行内块,以便能够应用背景 */
+    display: inline-block;
+  }
+}
+.title {
+  position: absolute;
+  top: 25px;
+  left: 70px;
+  font-size: 84px;
+  margin-right: 20px;
+}
+
+.close-btn {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  width: 75px;
+  height: 70px;
+  background: url('@/assets/images/map/rightMenu/close.png') no-repeat;
+  background-size: 100% 100%;
+  cursor: pointer;
+}
+</style>

+ 358 - 0
src/views/globalMap/RightMenu/WindMonitor/windSpeedRank.vue

@@ -0,0 +1,358 @@
+<template>
+  <Dialog custom-show type="md" title="风速排行" hide-footer @close="handleClose">
+    <div>(过去24小时)</div>
+    <div class="title-box">
+      <el-select
+        v-model="timeOption"
+        class="custom-select"
+        popper-class="custom-select-popper"
+        :teleported="false"
+        style="width: 236px"
+        @change="initData"
+      >
+        <el-option v-for="item in timeOptions" :key="item.value" :label="item.name" :value="item.value" />
+      </el-select>
+    </div>
+    <div class="table">
+      <div class="table-header">
+        <div class="td">序号</div>
+        <div class="td">
+          <el-select
+            v-model="queryParams.area"
+            placeholder="地市"
+            size="large"
+            class="custom-select2"
+            popper-class="custom-select-popper2"
+            :teleported="false"
+          >
+            <el-option label="区县" value="" />
+            <el-option v-for="item in district_type" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </div>
+        <div class="td">区县</div>
+        <div class="td">站址</div>
+        <div class="td td-cursor">
+          <span>风速(m/s)</span>
+          <i :class="queryParams.sort === 'desc' ? 'desc-icon' : 'asc-icon'" @click="handleSort" />
+        </div>
+      </div>
+      <div v-for="(item, index) in rangeData" :key="index" class="tr">
+        <div class="td">
+          <div :class="getRankClass(item.rn)">{{ item.rn }}</div>
+        </div>
+        <div class="td">{{ item.area }}</div>
+        <div class="td">{{ item.township }}</div>
+        <div class="td btn3" @click="handleClick(item)">
+          <div class="chart-icon"></div>
+          {{ item.address }}
+        </div>
+        <div class="gradient-text2 td">{{ item.rainfall }}</div>
+      </div>
+    </div>
+    <div class="footer">
+      <el-pagination
+        background
+        :hide-on-single-page="true"
+        layout="total, prev, pager, next"
+        :total="total"
+        :page-size="queryParams.size"
+        :current-page="queryParams.current"
+        @current-change="handleChangePage"
+      />
+    </div>
+  </Dialog>
+  <WindSpeedChart v-if="showDialog" v-model:show="showDialog" :rainData="rainData" />
+</template>
+
+<script lang="ts" setup name="RainRank">
+import { getRainfallRange2 } from '@/api/globalMap/rainMonitor';
+import { getNextAreaInfo } from '@/api/common';
+import WindSpeedChart from '@/views/globalMap/RightMenu/WindMonitor/windSpeedChart.vue';
+
+interface Props {
+  modelValue: boolean;
+  location: string | number[];
+}
+withDefaults(defineProps<Props>(), {});
+const emits = defineEmits(['update:modelValue']);
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { district_type } = toRefs<any>(proxy?.useDict('district_type'));
+const timeOption = ref('24');
+const timeOptions = reactive([
+  { name: '1小时', value: '1' },
+  { name: '3小时', value: '3' },
+  { name: '6小时', value: '6' },
+  { name: '12小时', value: '12' },
+  { name: '24小时', value: '24' }
+]);
+const rangeData = ref([]);
+const queryParams = reactive({
+  current: 1,
+  size: 10,
+  area: '',
+  township: '',
+  sort: 'desc'
+});
+const townshipList = ref([]);
+const total = ref(0);
+const showDialog = ref(false);
+const rainData = ref({});
+const getRankClass = (rank) => {
+  let res = 'rank-other';
+  if (rank === 1) {
+    res = 'rank1';
+  } else if (rank === 2) {
+    res = 'rank2';
+  } else if (rank === 3) {
+    res = 'rank3';
+  }
+  return res;
+};
+const handleSort = () => {
+  if (queryParams.sort === 'desc') {
+    queryParams.sort = 'asc';
+  } else {
+    queryParams.sort = 'desc';
+  }
+  initData();
+};
+function handleChangePage(newNum) {
+  queryParams.current = newNum;
+  initData();
+}
+const initData = () => {
+  let area = '';
+  for (let i = 0; i < district_type.value.length; i++) {
+    if (district_type.value[i].value === queryParams.area) {
+      area = district_type.value[i].label;
+    }
+  }
+  const params = {
+    current: queryParams.current,
+    size: queryParams.size,
+    query: {
+      area: area,
+      township: queryParams.township,
+      sort: queryParams.sort,
+      timeOption: timeOption.value
+    }
+  };
+  getRainfallRange2(params).then((res) => {
+    total.value = res.total;
+    rangeData.value = res.rows;
+  });
+};
+watch(
+  () => queryParams.area,
+  () => {
+    queryParams.township = '';
+    townshipList.value = [];
+    if (queryParams.area) {
+      getNextAreaInfo(queryParams.area).then((res) => {
+        townshipList.value = res.data.list;
+      });
+    }
+    initData();
+  },
+  { immediate: true }
+);
+const handleClose = () => {
+  emits('update:modelValue', false);
+};
+const handleClick = (item) => {
+  rainData.value = item;
+  showDialog.value = true;
+};
+</script>
+
+<style lang="scss" scoped>
+.dialog-container {
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  z-index: 9;
+  width: 2001px;
+  height: 1562px;
+  background: url('@/assets/images/map/rightMenu/rainMonitor/dialog2.png') no-repeat;
+  padding: 170px 30px 20px 40px;
+  font-size: 36px;
+  color: #ffffff;
+}
+.title-box {
+  position: absolute;
+  top: 25px;
+  left: 70px;
+  display: flex;
+  align-items: center;
+  .title {
+    font-size: 84px;
+    margin-right: 20px;
+  }
+}
+
+.close-btn {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  width: 75px;
+  height: 70px;
+  background: url('@/assets/images/map/rightMenu/close.png') no-repeat;
+  background-size: 100% 100%;
+  cursor: pointer;
+}
+.table {
+  margin-left: 28px;
+  .table-header {
+    width: 1864px;
+    height: 96px;
+    background: url('@/assets/images/common/header.png') no-repeat;
+    background-size: 100% 100%;
+    display: flex;
+    align-items: center;
+    .td-cursor {
+      cursor: pointer;
+    }
+  }
+  .tr {
+    width: 1864px;
+    height: 96px;
+    background: url('@/assets/images/common/tr.png') no-repeat;
+    background-size: 100% 100%;
+    display: flex;
+    align-items: center;
+    margin-top: 10px;
+    .td {
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+    .btn3 {
+      cursor: pointer;
+      color: #00d0ee;
+      display: flex;
+      .chart-icon {
+        width: 52px;
+        height: 51px;
+        background: url('@/assets/images/map/rightMenu/rainMonitor/icon5.png') no-repeat;
+        margin-right: 5px;
+      }
+    }
+  }
+  .gradient-text2 {
+    color: transparent !important;
+  }
+  .td {
+    font-size: 38px;
+    color: #edfaff;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    &:nth-child(1) {
+      width: 140px;
+    }
+    &:nth-child(2) {
+      width: 220px;
+    }
+    &:nth-child(3) {
+      width: 280px;
+    }
+    &:nth-child(4) {
+      flex: 1;
+    }
+    &:nth-child(5) {
+      width: 230px;
+    }
+  }
+  .down-icon {
+    display: inline-block;
+    width: 33px;
+    height: 15px;
+    background: url('@/assets/images/map/rightMenu/rainMonitor/down.png') no-repeat;
+    cursor: pointer;
+    margin-left: 8px;
+  }
+  .asc-icon {
+    display: inline-block;
+    width: 33px;
+    height: 33px;
+    background: url('@/assets/images/common/asc.png') no-repeat;
+    cursor: pointer;
+    margin-left: 8px;
+  }
+  .desc-icon {
+    display: inline-block;
+    width: 33px;
+    height: 33px;
+    background: url('@/assets/images/common/desc.png') no-repeat;
+    cursor: pointer;
+    margin-left: 8px;
+  }
+  .rank1,
+  .rank2,
+  .rank3,
+  .rank-other {
+    width: 50px;
+    height: 48px;
+    color: #ecfaff;
+    font-family: BEBAS-1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .rank1 {
+    height: 47px;
+    background: url('@/assets/images/map/rightMenu/rainMonitor/first.png') no-repeat;
+  }
+  .rank2 {
+    background: url('@/assets/images/map/rightMenu/rainMonitor/second.png') no-repeat;
+  }
+  .rank3 {
+    background: url('@/assets/images/map/rightMenu/rainMonitor/third.png') no-repeat;
+  }
+  .rank-other {
+    background: url('@/assets/images/map/rightMenu/rainMonitor/other.png') no-repeat;
+  }
+}
+.footer {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 30px;
+  padding-right: 40px;
+  :deep(.el-pagination__total) {
+    color: #a7ccdf;
+    font-size: 32px;
+  }
+
+  :deep(.el-pagination) {
+    .btn-next,
+    .btn-prev {
+      background-color: transparent;
+      border: none;
+      .el-icon {
+        font-size: 22px;
+        color: #a7ccdf;
+      }
+    }
+    .el-pager li {
+      width: 64px;
+      height: 64px;
+      line-height: 64px;
+      text-align: center;
+      font-size: 32px;
+      color: #a7ccdf;
+      background-color: #0e3064;
+      border: 1px solid #0c57a7;
+      margin: 0 6px;
+      &:hover {
+        background-color: #038dff;
+        border: 1px solid #038dff;
+      }
+    }
+    .el-pager li.is-active {
+      background-color: #038dff;
+      border: 1px solid #038dff;
+    }
+  }
+}
+</style>