Browse Source

feat: 实时模拟

hum 1 year ago
parent
commit
8039b3c7fe

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/AchievementService.java

@@ -16,6 +16,8 @@ public interface AchievementService {
 
     Page<TaskResult> queryAchievement(AchievementQuery achievementQuery);
 
+    TaskResult queryAchievementByTaskid(String taskid);
+
     Page<WaterLevelDTO> getWaterLevelList(WaterLevelQuery waterLevelQuery);
 
     boolean downAchievement(Long result_id, HttpServletResponse response);

+ 1 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ReportDataService.java

@@ -26,5 +26,6 @@ public interface ReportDataService {
 
     BerthingPointConfig getPointConfig (Long siteId);
 
+    BerthingPointConfig getPointConfig (Long siteId, Long planid);
 
 }

+ 5 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AchievementServiceImpl.java

@@ -57,6 +57,11 @@ public class AchievementServiceImpl implements AchievementService {
         return taskResultMapper.queryAllByLimit(achievementQuery ,new Page(achievementQuery.getPage(),achievementQuery.getSize()));
     }
 
+    @Override
+    public TaskResult queryAchievementByTaskid(String taskid){
+        return taskResultMapper.queryByTaskid(taskid);
+    }
+
 
 
     @Override

+ 4 - 2
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ReportDataServiceImpl.java

@@ -177,8 +177,10 @@ public class ReportDataServiceImpl implements ReportDataService {
         }
     }
 
-
-
+    @Override
+    public BerthingPointConfig getPointConfig (Long siteId, Long planid){
+        return berthingPointConfigMapper.queryByPlanid(siteId, planid);
+    }
 
     private static LocalTime parseTime(Object timeStr) {
         return LocalTime.parse(timeStr.toString(), DateTimeFormatter.ofPattern("HH:mm"));

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SaveDataServiceImpl.java

@@ -135,6 +135,8 @@ public class SaveDataServiceImpl implements SaveDataService {
             taskNoticeMapper.insert(taskNotice);
             //新建结果报告 状态设置为测流中
             TaskResult taskResult = new TaskResult();
+            taskResult.setType(0); // 移动测流
+            taskResult.setPlanid(taskNotice.getPlanid());
             taskResult.setResultId(0L);
             taskResult.setTaskid(taskNotice.getTaskid());
             taskResult.setStatus(0);

+ 31 - 0
ruoyi-ui/src/api/analysis/achievement.js

@@ -8,6 +8,13 @@ export function listAchievements(query) {
   })
 }
 
+export function getAchievement(taskid) {
+  return request({
+    url: `/achievement/queryAchievement/${taskid}`,
+    method: 'get',
+  })
+}
+
 export function listWaterLevel(query) {
   return request({
     url: '/achievement/getWaterLevelList',
@@ -16,6 +23,14 @@ export function listWaterLevel(query) {
   })
 }
 
+export function listScatterPlot(query) {
+  return request({
+    url: '/achievement/getScatterPlot',
+    method: 'post',
+    data: query
+  })
+}
+
 export function listMeasureLine(siteId) {
   return request({
     url: '/reportData/getMeasureLine',
@@ -71,3 +86,19 @@ export function getWaterLevel(siteId) {
     params: { siteId },
   })
 }
+
+export function getPointConfig(siteId) {
+  return request({
+    url: '/reportData/getPointConfig',
+    method: 'get',
+    params: { siteId },
+  })
+}
+
+export function getPointConfigByPlanid(siteId, planid) {
+  return request({
+    url: '/reportData/getPointConfigByPlanid',
+    method: 'get',
+    params: { siteId, planid },
+  })
+}

+ 6 - 3
ruoyi-ui/src/views/analysis/task/index.vue

@@ -42,7 +42,7 @@
             <span>{{ formatDateTime(scope.row.createTime) }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="水位" prop="waterlevels" />
+        <el-table-column label="水位" prop="waterlevel" />
         <el-table-column label="过水面积" prop="acreagesum" />
         <el-table-column label="瞬时流量(总)" prop="flowsum" />
         <el-table-column label="当前状态">
@@ -89,7 +89,6 @@
 <script>
 import { listSite } from "@/api/site/site";
 import { listAchievements, taskAction } from "@/api/analysis/achievement";
-import {deletePlainWater} from "@/api/site/berthing";
 
 export default {
   data() {
@@ -152,7 +151,11 @@ export default {
       );
     },
     goRealTime(task) {
-      this.$router.push(`/analysis/task/realtime/${task.siteId}`);
+      if (task.status === 0) {
+        this.$router.push(`/analysis/task/realtime/${task.siteId}`);
+      } else {
+        this.$router.push(`/analysis/task/realtime/${task.siteId}?taskid=${task.taskid}`);
+      }
     },
     handleExport(task) {
       window.open(`${process.env.VUE_APP_BASE_API}/achievement/downAchievement?resultId=${task.resultId}`, '_blank')

+ 13 - 2
ruoyi-ui/src/views/analysis/task/realtime.vue

@@ -1,9 +1,10 @@
 <template>
-  <Realtime v-if="siteId" :siteId="siteId" />
+  <Realtime v-if="siteId" :siteId="siteId" :positions="positions" />
 </template>
 
 <script>
-import Realtime from './realtime/realtime'
+import { getAchievement, getPointConfigByPlanid, getPointConfig } from '@/api/analysis/achievement';
+import Realtime from './realtime/realtime';
 
 export default {
   components: {
@@ -12,11 +13,21 @@ export default {
   data() {
     return {
       siteId: 0,
+      task: {},
+      positions: [],
     }
   },
   mounted() {
     const { siteId } = this.$route.params;
     this.siteId = siteId;
+    const { taskid } = this.$route.query;
+    const promise = taskid ? getAchievement(taskid).then((res) => {
+      this.task = res.data;
+      return getPointConfigByPlanid(siteId, res.data.planid);
+    }) : getPointConfig(siteId);
+    promise.then((res) => {
+      this.positions = JSON.parse(res.data.positions || '[]');
+    })
   },
 }
 </script>

+ 6 - 3
ruoyi-ui/src/views/analysis/task/realtime/flow.vue

@@ -12,6 +12,9 @@ import resize from '@/utils/resize'
 
 export default {
   mixins: [resize],
+  props: {
+    positions: Array,
+  },
   mounted() {
     this.$nextTick(() => {
       this.chart = echarts.init(this.$refs.chart, 'macarons');
@@ -25,11 +28,11 @@ export default {
   },
   methods: {
     setOptions(chartData) {
-      if (!this.chart) {
+      if (!this.chart || !this.positions) {
         return;
       }
-      const xAxisData = chartData.map(({ pn }) => pn);
-      const seriesData = chartData.map(({ wspeed }) => wspeed);
+      const xAxisData = this.positions.map(({x}) => x);
+      const seriesData = this.positions.map((_,index) => chartData.find(({pn}) => pn - 1 === index)?.wspeed || 0);
       const options = {
         xAxis: {
           name: '停泊点',

+ 4 - 3
ruoyi-ui/src/views/analysis/task/realtime/realtime.vue

@@ -2,7 +2,7 @@
   <div>
     <el-row :gutter="10">
       <el-col :span="18">
-        <Simulation :siteId="siteId" />
+        <Simulation :siteId="siteId" :positions="positions" :measureLine="measureLine" />
         <el-row :gutter="20" style="margin-top: 10px">
           <el-col :span="8">
             <Site :siteRealTime="siteRealTime" />
@@ -17,7 +17,7 @@
       </el-col>
       <el-col :span="6">
         <Movie />
-        <Flow ref="flow" style="margin-top: 10px" />
+        <Flow ref="flow" :positions="positions" style="margin-top: 10px" />
         <Water ref="water" style="margin-top: 10px" />
       </el-col>
     </el-row>
@@ -34,7 +34,7 @@ import Movie from './movie'
 import Flow from './flow'
 import Water from './water'
 import Report from './report'
-import { getCarInfo, getSiteRealTime, getTaskNotice, listMeasureLine, listWaterLevel } from "@/api/analysis/achievement";
+import { getCarInfo, getSiteRealTime, getTaskNotice, listMeasureLine, listWaterLevel, getPointConfig, getPointConfigByPlanid } from "@/api/analysis/achievement";
 
 export default {
   components: {
@@ -49,6 +49,7 @@ export default {
   },
   props: {
     siteId: Number | String,
+    positions: Array,
   },
   data() {
     return {

+ 3 - 3
ruoyi-ui/src/views/analysis/task/realtime/report.vue

@@ -2,10 +2,10 @@
   <div class="realtime-container">
     <el-table border :data="measureLine">
       <el-table-column prop="pn" label="垂线编号" />
-      <el-table-column prop="x" label="起点距" />
+      <el-table-column prop="pointX" label="起点距" />
       <el-table-column prop="createTime" label="开始时间" />
-      <el-table-column prop="area" label="过水面积" />
-      <el-table-column prop="area" label="水位" />
+<!--      <el-table-column prop="area" label="过水面积" />-->
+      <el-table-column prop="waterlevel" label="水位" />
       <el-table-column prop="wspeed" label="流速" />
     </el-table>
   </div>

+ 43 - 1
ruoyi-ui/src/views/analysis/task/realtime/simulation.vue

@@ -12,12 +12,13 @@ import { getConfig } from '@/api/site/site'
 import { getSiteSection } from '@/api/site/berthing'
 import { getCarLocation, getWaterLevel } from '@/api/analysis/achievement'
 import CarSvg from '@/assets/images/car.svg'
-import BarSvg from '@/assets/images/bar.svg'
 
 export default {
   mixins: [resize],
   props: {
     siteId: Number | String,
+    positions: Array,
+    measureLine: Array,
   },
   data() {
     return {
@@ -105,6 +106,9 @@ export default {
       const barY = maxY + disY * 1.2;
       const lineY = maxY + disY * 0.8;
 
+      const stopSeries = this.positions.map(({x}) => [x, lineY]);
+      const stopLineSeries = this.measureLine.map(({pn, wspeed}) => ({xAxis: this.positions[pn - 1].x, name: `${wspeed}m³/h`}));
+
       const options = {
         grid: {
           top: 0,
@@ -164,6 +168,44 @@ export default {
               color: '#54606C',
             },
           },
+          {
+            data: stopSeries,
+            type: 'line',
+            z: 4,
+            symbol: 'circle',
+            symbolSize: (_, params) => {
+              if (params.dataIndex < this.measureLine.length) {
+                return 20
+              } else {
+                return 10
+              }
+            },
+            lineStyle: {
+              width: 0,
+            },
+            itemStyle: {
+              color: (params) => {
+                if (params.dataIndex < this.measureLine.length) {
+                  return '#55DA74'
+                } else {
+                  return '#FF8500'
+                }
+              },
+            },
+            markLine: {
+              data: stopLineSeries,
+              symbol: 'none',
+              lineStyle: {
+                color: '#FF8500'
+              },
+              label: {
+                show: true,
+                position: 'middle',
+                formatter: '{b}',
+                color: '#FF8500',
+              }
+            }
+          },
           {
             data: [[bar1X, barY],[bar2X, barY]],
             type: 'bar',

+ 1 - 0
ruoyi-ui/src/views/analysis/task/realtime/water.vue

@@ -28,6 +28,7 @@ export default {
       if (!this.chart) {
         return;
       }
+      chartData.reverse()
       const xAxisData = chartData.map(({ time }) => time);
       const seriesData = chartData.map(({ avgWaterlevel }) => avgWaterlevel);
       const options = {

+ 92 - 0
ruoyi-ui/src/views/analysis/water-flow/chart.vue

@@ -0,0 +1,92 @@
+<template>
+  <div ref="chart" class="chart" :style="{height: '400px', width: '100%'}" />
+</template>
+
+<script>
+import { listScatterPlot } from '@/api/analysis/achievement'
+import * as echarts from "echarts";
+require('echarts/theme/macarons') // echarts theme
+import resize from '@/utils/resize'
+
+export default {
+  mixins: [resize],
+  props: {
+    queryParams: Object,
+  },
+  data() {
+    return {
+      pagination: {
+        page: 1,
+        size: 10000,
+      }
+    }
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.chart = echarts.init(this.$refs.chart, 'macarons');
+      this.setOptions();
+    })
+  },
+  beforeDestroy() {
+    if (this.chart) {
+      this.chart.dispose()
+      this.chart = null
+    }
+  },
+  methods: {
+    setOptions() {
+      const { queryParams } = this;
+      if (!queryParams.siteId) return;
+      const params = {
+        ...this.queryParams,
+        ...this.pagination,
+      };
+      listScatterPlot(params).then((res) => {
+        const chartData = res.data.records || [];
+        const seriesData = chartData.map(({ flowsum, waterlevel }) => [flowsum, waterlevel]);
+        this.chart.setOption({
+          xAxis: {
+            name: '流量(m³/h)',
+            scale: true
+          },
+          yAxis: {
+            name: '水位(m)',
+            scale: true
+          },
+          grid: {
+            left: 50,
+            right: 50,
+            bottom: 40,
+            top: 40,
+            containLabel: true
+          },
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+              type: 'cross'
+            },
+            padding: [5, 10]
+          },
+          series: [{
+            name: '水位',
+            type: 'scatter',
+            data: seriesData,
+          }]
+        })
+      })
+    }
+  },
+  watch: {
+    queryParams: {
+      handler() {
+        this.setOptions();
+      },
+      deep: true,
+    },
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 134 - 2
ruoyi-ui/src/views/analysis/water-flow/index.vue

@@ -1,12 +1,144 @@
 <template>
-  <div>1</div>
+  <div class="hum-page-container">
+    <div class="hum-page-title">水位时间</div>
+    <div class="hum-page-section hum-page-section-search">
+      <div class="hum-page-search">
+        <el-form :model="queryParams" size="large" ref="queryForm" label-position="top">
+          <el-row :gutter="30">
+            <el-col :span="6">
+              <el-form-item label="选择站点">
+                <el-select v-model="queryParams.siteId" placeholder="请选择站点">
+                  <el-option
+                    v-for="item in siteList"
+                    :key="item.siteId"
+                    :label="item.siteName"
+                    :value="item.siteId">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="设站日期">
+                <el-date-picker
+                  v-model="dateRange"
+                  @change="dateRangeChangeHandler"
+                  value-format="yyyy-MM-dd hh:mm:ss"
+                  type="datetimerange"
+                  range-separator="-"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
+                  :clearable="false"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item class="hum-page-search-action">
+                <el-button type="primary" @click="handleQuery">查询</el-button>
+                <el-button @click="resetQuery">重置</el-button>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+    </div>
+    <div class="hum-page-title" style="margin-top: 30px">
+      <span>数据图</span>
+      <div class="data-actions">
+        <el-radio-group v-model="mode" size="mini" class="data-actions-radio">
+          <el-radio-button label="chart">图标</el-radio-button>
+          <el-radio-button label="table">表格</el-radio-button>
+        </el-radio-group>
+        <el-button type="primary" size="mini" @click="handleExport">导出</el-button>
+      </div>
+    </div>
+    <div class="hum-page-section">
+      <Chart v-if="mode === 'chart'" :queryParams="queryParams" />
+      <Table v-if="mode === 'table'" :queryParams="queryParams" />
+    </div>
+  </div>
 </template>
 
 <script>
+import { listSite } from "@/api/site/site";
+import { parseTime } from '@/utils/ruoyi'
+import Chart from './chart'
+import Table from './table'
+
+const initDateRange = () => {
+  const start = new Date();
+  const end = new Date();
+  start.setHours(start.getHours() - 3);
+  return [parseTime(start), parseTime(end)];
+}
+
 export default {
+  components: {
+    Chart,
+    Table,
+  },
+  data() {
+    const dateRange = initDateRange(1);
+    return {
+      siteList: [],
+      dateRange: dateRange,
+      queryParams: {
+        siteId: 0,
+        startTime: dateRange[0],
+        endTime: dateRange[1],
+      },
+      mode: 'chart',
+      loading: true,
+    }
+  },
+  created() {
+    this.init();
+  },
+  methods: {
+    handleQuery() {
+      this.getList()
+    },
+    resetQuery() {},
+    init() {
+      this.loading = true;
+      listSite({ page: 1, size: 1000 }).then(response => {
+          this.siteList = response.data.records || [];
+          if (this.siteList.length > 0) {
+            this.queryParams.siteId = this.siteList[0].siteId;
+          }
+        }
+      ).finally(() => {
+        this.loading = false;
+      });
+    },
+    dateRangeChangeHandler(dateRange) {
+      this.queryParams.startTime = dateRange[0];
+      this.queryParams.endTime = dateRange[1];
+    },
+    handleExport() {
+      window.open(`${process.env.VUE_APP_BASE_API}/achievement/downScatterPlot?siteId=${this.queryParams.siteId}&startTime=${this.queryParams.startTime}&endTime=${this.queryParams.endTime}`, '_blank')
+    }
+  }
 }
 </script>
 
 <style scoped>
-
+.hum-page-section-search {
+  padding-bottom: 0;
+}
+.hum-page-search {
+  border-bottom: 0;
+}
+.data-actions {
+  display: flex;
+  align-items: center;
+}
+.data-actions-radio {
+  margin-right: 20px;
+}
+.data-actions-radio /deep/ .el-radio-button__orig-radio:checked + .el-radio-button__inner {
+  color: #06A3B5;
+  background: #FFFFFF;
+  border: 1px solid #DCDFE6;
+  box-shadow: none;
+}
 </style>

+ 69 - 0
ruoyi-ui/src/views/analysis/water-flow/table.vue

@@ -0,0 +1,69 @@
+<template>
+  <div>
+    <el-table v-loading="loading" :data="list" border>
+      <el-table-column label="瞬时总流量" prop="flowsum" />
+      <el-table-column label="水位" prop="waterlevel" />
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="pagination.page"
+      :limit.sync="pagination.size"
+      @pagination="getList"
+    />
+  </div>
+</template>
+
+<script>
+import { listScatterPlot } from '@/api/analysis/achievement'
+
+export default {
+  props: {
+    queryParams: Object,
+  },
+  data() {
+    return {
+      total: 0,
+      list: [],
+      loading: false,
+      pagination: {
+        page: 1,
+        size: 10,
+      },
+    }
+  },
+  mounted() {
+    this.getList();
+  },
+  watch: {
+    queryParams: {
+      handler() {
+        this.getList();
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    getList() {
+      const { queryParams } = this;
+      if (!queryParams.siteId) return;
+      const params = {
+        ...this.queryParams,
+        ...this.pagination,
+      };
+      this.loading = true;
+      listScatterPlot(params).then(response => {
+          this.list = response.data.records;
+          this.total = response.data.total;
+          this.loading = false;
+        }
+      );
+    },
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 5 - 1
ruoyi-ui/src/views/analysis/water-time/index.vue

@@ -39,6 +39,7 @@
                   range-separator="-"
                   start-placeholder="开始日期"
                   end-placeholder="结束日期"
+                  :clearable="false"
                 />
               </el-form-item>
             </el-col>
@@ -59,7 +60,7 @@
           <el-radio-button label="chart">图标</el-radio-button>
           <el-radio-button label="table">表格</el-radio-button>
         </el-radio-group>
-        <el-button type="primary" size="mini">导出</el-button>
+        <el-button type="primary" size="mini" @click="handleExport">导出</el-button>
       </div>
     </div>
     <div class="hum-page-section">
@@ -162,6 +163,9 @@ export default {
       this.queryParams.type = type;
       this.queryParams.startTime = dateRange[0];
       this.queryParams.endTime = dateRange[1];
+    },
+    handleExport() {
+      window.open(`${process.env.VUE_APP_BASE_API}/achievement/downWaterLevel?siteId=${this.queryParams.siteId}&type=${this.queryParams.type}&startTime=${this.queryParams.startTime}&endTime=${this.queryParams.endTime}`, '_blank')
     }
   }
 }

+ 6 - 0
waterAffairs-admin/src/main/java/com/ruoyi/web/controller/tool/AchievementController.java

@@ -44,6 +44,12 @@ public class AchievementController {
         return R.ok(achievementService.queryAchievement(achievementQuery));
     }
 
+    @GetMapping(value = "/queryAchievement/{taskid}")
+    @ApiOperation("查询成果报告")
+    public R<TaskResult> queryAchievementByTaskid(@PathVariable String taskid) {
+        return R.ok(achievementService.queryAchievementByTaskid(taskid));
+    }
+
     @GetMapping(value = "/downAchievement")
     @ApiOperation(value = "导出成果报告")
     public void downAchievement(Long resultId, HttpServletResponse response) {

+ 7 - 0
waterAffairs-admin/src/main/java/com/ruoyi/web/controller/tool/ReportDataController.java

@@ -80,4 +80,11 @@ public class ReportDataController {
         return R.ok(reportDataService.getPointConfig(siteId));
     }
 
+    //垂线点对应流量图
+    @GetMapping(value = "/getPointConfigByPlanid")
+    @ApiOperation("通过策略编号获取停泊点信息")
+    public R<BerthingPointConfig> getPointConfig(Long siteId, Long planid)  {
+        return R.ok(reportDataService.getPointConfig(siteId, planid));
+    }
+
 }