LR 3 éve
szülő
commit
3e4e4c51ee

+ 1 - 1
src/styles/base.scss

@@ -3,7 +3,7 @@ body {
   -moz-osx-font-smoothing: grayscale;
   -webkit-font-smoothing: antialiased;
   text-rendering: optimizeLegibility;
-  // font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+  font-family: PingFang SC, Source Han Sans CN, Microsoft YaHei, Arial, sans-serif;
 }
 
 .planMakeLoading {

+ 9 - 0
src/utils/constant.ts

@@ -70,3 +70,12 @@ export const getDefaultDateTimePickerProp = () => ({
     }
   ]
 })
+
+export const rgb2Hex = (color: string) => {
+  const [r, g, b] = (color || '').replace(/rgba?|\(|\)/g, '').split(',')
+  const toHex = (num: number | string) => {
+    const hex = Number(num).toString(16)
+    return `${hex.length === 1 ? '0' : ''}${hex}`
+  }
+  return `#${toHex(r)}${toHex(g)}${toHex(b)}`
+}

+ 32 - 0
src/views/spectrum/reform/api/assessment.ts

@@ -0,0 +1,32 @@
+import { IQueryCommon, IRes, IResult } from '@/api/common'
+import axios from '@/utils/request'
+import { base, IAssessmentBase, IAssessmentFlaw, IAssessmentHealth, IAssessmentAssessment, IAssessment } from './common'
+export interface IQueryParam {
+  checkCode: string
+  siteId: number
+  beginDate: string
+  endDate: string
+}
+
+const uris = {
+  base: `${base}/assessmentReport/getAssessConclusion`,
+  flaw: `${base}/assessmentReport/getDataByFlawTypeCount`,
+  health: `${base}/assessmentReport/getHealthLevel`,
+  assessment: `${base}/assessmentReport/getReportCondision`,
+  page: `${base}/assessmentReport/page`,
+  download: `${base}/assessmentReport/exportExcel`
+}
+
+export const fetchBaseReport = () => axios.request<IResult<IAssessmentBase>>({ url: uris.base, method: 'get' })
+
+export const fetchFlawReport = () => axios.request<IResult<IAssessmentFlaw>>({ url: uris.flaw, method: 'get' })
+
+export const fetchHealthReport = () => axios.request<IResult<IAssessmentHealth[]>>({ url: uris.health, method: 'get' })
+
+export const fetchAssessmentReport = () =>
+  axios.request<IResult<IAssessmentAssessment[]>>({ url: uris.assessment, method: 'get' })
+
+export const fetchReportPage = (params: Partial<IQueryCommon>) =>
+  axios.request<IRes<IAssessment[]>>({ url: uris.page, method: 'get', params })
+
+export const downloadAssessment = () => axios.request<IResult<any>>({ url: uris.download, method: 'get' })

+ 48 - 0
src/views/spectrum/reform/api/common.ts

@@ -75,3 +75,51 @@ export interface IStatisticsBase {
   siteName: string
   siteNote: string
 }
+
+export interface IAssessmentBase {
+  contentGauge: number
+  coverPipe: number
+  fourPipe: number
+  fourPipePerCent: string
+  monitoringPoint: number
+  onePipe: number
+  onePipePerCent: string
+  pipeLength: number
+  pipeMonitor: number
+  threePipe: number
+  threePipePerCent: string
+  twoPipe: number
+  twoPipePerCent: string
+  waterMonitor: number
+}
+export interface IAssessmentFlaw {
+  legendData: string[]
+  seriesDatas: {
+    name: string
+    seriesData: number[]
+  }[]
+  xaxis: string[]
+}
+export interface IAssessmentHealth {
+  value: number
+  name: string
+}
+export interface IAssessmentAssessment {
+  value: number
+  name: string
+}
+export interface IAssessment {
+  drainageType: string
+  groundwaterIntrusion: number
+  healthLever: string
+  id: number
+  length: number
+  networkBroken: number
+  pipeDiameter: number
+  pipeNo: string
+  pipelineLevel: string
+  rainSewageHybrid: number
+  roadName: string
+  sewageStraightLine: number
+  texture: string
+}

+ 2 - 2
src/views/spectrum/reform/api/statistics.ts

@@ -1,4 +1,4 @@
-import { IQueryCommon, IRes, IResult } from '@/api/common'
+import { IRes, IResult } from '@/api/common'
 import axios from '@/utils/request'
 import { base, IStatisticsBase, IStatisticsData, IStatisticsDayNHour } from './common'
 export interface IQueryParam {
@@ -17,7 +17,7 @@ const uris = {
 }
 
 export const fetchData = (params: Partial<IQueryParam>) =>
-  axios.request<IResult<IStatisticsData>>({ url: uris.data, method: 'get', params })
+  axios.request<IResult<IStatisticsData[]>>({ url: uris.data, method: 'get', params })
 
 export const fetchDayData = (params: Partial<IQueryParam>) =>
   axios.request<IResult<IStatisticsDayNHour>>({ url: uris.day, method: 'get', params })

+ 61 - 0
src/views/spectrum/reform/assessmentReport/Chart.vue

@@ -0,0 +1,61 @@
+<template>
+  <div class="chart" ref="chart">
+    <v-chart
+      :options="option"
+      autoresize
+      style="width: 100%; height: 100%"
+      v-if="option.series.some((item) => item.data.length > 0)"
+    />
+    <el-empty :image="emptyImg" v-else>
+      <template v-slot:description>&nbsp;</template>
+    </el-empty>
+  </div>
+</template>
+
+<script lang="ts">
+  import { Vue, Component, Prop } from 'vue-property-decorator'
+  import { IAssessmentFlaw } from '../api/common'
+  import emptyImg from '@/assets/icon/null.png'
+  import { rgb2Hex } from '@/utils/constant'
+
+  @Component({})
+  export default class Chart extends Vue {
+    @Prop({ type: Object, default: () => ({ seriesDatas: [], xaxis: [] }) }) flaw!: IAssessmentFlaw
+    emptyImg = emptyImg
+    get option() {
+      const { seriesDatas: series = [], xaxis: xAxis = [] } = this.flaw || {}
+      const style = (() => {
+        try {
+          const { color, fontFamily } = window.getComputedStyle(this.$refs.chart as any, null)
+          return { color, fontFamily }
+        } catch (error) {
+          console.log(error)
+        }
+        return {}
+      })()
+      return {
+        tooltip: { trigger: 'axis' },
+        calculable: true,
+        xAxis: { type: 'category', data: xAxis },
+        yAxis: [{ type: 'value', name: '单位: m' }],
+        legend: { show: true, type: 'scroll', right: 0, itemWidth: 14, itemHeight: 14 },
+        grid: { top: 45, left: 30, right: 30, bottom: 30, containLabel: true },
+        series: series.map(({ name, seriesData: data }) => ({ name, data, type: 'bar' })),
+        title: {
+          text: '按缺陷类型统计',
+          bottom: 0,
+          left: 'center',
+          textStyle: { fontSize: 13, ...style }
+        }
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .chart {
+    height: 100%;
+    padding-top: $gutter;
+    color: $--color-primary;
+  }
+</style>

+ 167 - 0
src/views/spectrum/reform/assessmentReport/Summary.vue

@@ -0,0 +1,167 @@
+<template>
+  <div class="summary">
+    <tf-title>评估结论</tf-title>
+    <div class="text">
+      系统已入库存量排水管网
+      <span ref="color">{{ base.pipeLength }} </span>公里,共布设监测点位
+      <span>{{ base.monitoringPoint }} </span>个,其中管网水质监测仪 <span>{{ base.pipeMonitor }} </span>台,液位计
+      <span>{{ base.contentGauge }} </span>台,地表水水质监测仪 <span>{{ base.waterMonitor }} </span>台, 覆盖排水管线
+      <span>{{ base.coverPipe }} </span>公里,通过系统大数据分析,管网健康等级评估结果如下:
+    </div>
+    <div class="levels">
+      <el-row type="flex">
+        <el-col :span="12">
+          1级管线
+          <span>{{ base.onePipe }}</span>
+          公里:占参与评估管网的
+          <span>{{ base.onePipePerCent }}</span>
+        </el-col>
+        <el-col :span="12">
+          2级管线
+          <span>{{ base.twoPipe }}</span>
+          公里:占参与评估管网的
+          <span>{{ base.twoPipePerCent }}</span>
+        </el-col>
+        <el-col :span="12">
+          3级管线
+          <span>{{ base.threePipe }}</span>
+          公里:占参与评估管网的
+          <span>{{ base.threePipePerCent }}</span>
+        </el-col>
+        <el-col :span="12">
+          4级管线
+          <span>{{ base.fourPipe }}</span>
+          公里:占参与评估管网的
+          <span>{{ base.fourPipePerCent }}</span>
+        </el-col>
+      </el-row>
+    </div>
+    <el-row class="chart" type="flex">
+      <el-col :span="12">
+        <v-chart :options="healthOption" autoresize style="width: 100%" v-if="healthOption.dataset.source.length > 0" />
+        <el-empty :image="emptyImg" v-else>
+          <template v-slot:description>&nbsp;</template>
+        </el-empty>
+      </el-col>
+      <el-col :span="12">
+        <v-chart
+          :options="assessmentOption"
+          autoresize
+          style="width: 100%"
+          v-if="assessmentOption.dataset.source.length > 0"
+        />
+        <el-empty :image="emptyImg" v-else>
+          <template v-slot:description>&nbsp;</template>
+        </el-empty>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+  import { Vue, Component, Prop } from 'vue-property-decorator'
+  import { IAssessmentAssessment, IAssessmentBase, IAssessmentHealth } from '../api/common'
+  import emptyImg from '@/assets/icon/null.png'
+
+  @Component({ name: 'AssessmentSummary' })
+  export default class Summary extends Vue {
+    @Prop({ type: Object, default: () => ({}) }) base!: IAssessmentBase
+    @Prop({ type: Array, default: () => [] }) health!: IAssessmentHealth[]
+    @Prop({ type: Array, default: () => [] }) assessment!: IAssessmentAssessment[]
+    emptyImg = emptyImg
+
+    getStyle() {
+      try {
+        const { color, fontFamily } = window.getComputedStyle(this.$refs.color as any, null)
+        return { color, fontFamily }
+      } catch (error) {
+        console.log(error)
+      }
+      return {}
+    }
+
+    get healthOption() {
+      return {
+        title: {
+          text: '按管网评估情况统计',
+          bottom: 0,
+          left: 'center',
+          textStyle: { fontSize: 13, ...this.getStyle() }
+        },
+        tooltip: { trigger: 'item' },
+        dataset: { source: this.health || [] },
+        series: [
+          {
+            name: '按管网评估情况统计',
+            type: 'pie',
+            radius: '50%',
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      }
+    }
+    get assessmentOption() {
+      return {
+        title: {
+          text: '按管网健康等级统计',
+          bottom: 0,
+          left: 'center',
+          textStyle: { fontSize: 13, ...this.getStyle() }
+        },
+        tooltip: { trigger: 'item' },
+        dataset: { source: this.assessment || [] },
+        series: [
+          {
+            name: '按管网健康等级统计',
+            type: 'pie',
+            radius: '50%',
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .summary {
+    font-size: $--font-size-base;
+    .text {
+      line-height: 1.6;
+    }
+    .text,
+    .levels {
+      span {
+        color: $--color-primary;
+        font-weight: bold;
+        display: inline-block;
+        padding: 0 2px;
+      }
+    }
+    .levels {
+      background-color: $--background-color-base;
+      padding: $gutter $gutter * 3;
+      margin-top: $gutter;
+      text-align: center;
+      span {
+        font-size: 130%;
+      }
+      > div {
+        flex-wrap: wrap;
+        line-height: 1.8;
+      }
+    }
+  }
+</style>

+ 148 - 0
src/views/spectrum/reform/assessmentReport/widget.vue

@@ -0,0 +1,148 @@
+<template>
+  <tf-page :isActive="isActive">
+    <div class="content">
+      <div class="title">管网健康情况评估报告</div>
+      <el-row type="flex" :gutter="15">
+        <el-col :span="12">
+          <Summary :base="baseData" :health="healthData" :assessment="assessmentData" />
+        </el-col>
+        <el-col :span="12">
+          <Chart :flaw="flawData" />
+        </el-col>
+      </el-row>
+    </div>
+  </tf-page>
+</template>
+
+<script lang="ts">
+  import { Vue, Component, Prop } from 'vue-property-decorator'
+  import { IPagination } from '@/api/common'
+  import { getDefaultPagination } from '@/utils/constant'
+  import Summary from './Summary.vue'
+  import Chart from './Chart.vue'
+  import {
+    IAssessment,
+    IAssessmentAssessment,
+    IAssessmentBase,
+    IAssessmentFlaw,
+    IAssessmentHealth
+  } from '../api/common'
+
+  import {
+    fetchBaseReport,
+    fetchFlawReport,
+    fetchHealthReport,
+    fetchAssessmentReport,
+    fetchReportPage
+  } from '../api/assessment'
+
+  @Component({ name: 'Statistics', components: { Summary, Chart } })
+  export default class Statistics extends Vue {
+    @Prop({ type: Boolean, default: false }) isActive!: boolean
+
+    visible = false
+
+    loading = { query: false, export: false, base: false, flaw: false, health: false, assessment: false, page: false }
+
+    pagination: IPagination = getDefaultPagination()
+
+    baseData: Partial<IAssessmentBase> = {}
+    flawData: Partial<IAssessmentFlaw> = {}
+    healthData: Partial<IAssessmentHealth>[] = []
+    assessmentData: Partial<IAssessmentAssessment>[] = []
+    pipes: Partial<IAssessment>[] = []
+
+    async fetchBaseReport() {
+      this.loading.base = true
+      try {
+        const { result } = await fetchBaseReport()
+        this.baseData = result
+      } catch (error) {
+        console.log(error)
+      }
+      this.loading.base = false
+    }
+    async fetchFlawReport() {
+      this.loading.flaw = true
+      try {
+        const { result } = await fetchFlawReport()
+        this.flawData = result
+      } catch (error) {
+        console.log(error)
+      }
+      this.loading.flaw = false
+    }
+    async fetchHealthReport() {
+      this.loading.health = true
+      try {
+        const { result } = await fetchHealthReport()
+        this.healthData = result
+      } catch (error) {
+        console.log(error)
+      }
+      this.loading.health = false
+    }
+    async fetchAssessmentReport() {
+      this.loading.assessment = true
+      try {
+        const { result } = await fetchAssessmentReport()
+        this.assessmentData = result
+      } catch (error) {
+        console.log(error)
+      }
+      this.loading.assessment = false
+    }
+    async fetchReportPage() {
+      this.loading.page = true
+      try {
+        const {
+          result: { records }
+        } = await fetchReportPage(this.pagination)
+        this.pipes = records
+      } catch (error) {
+        console.log(error)
+      }
+      this.loading.page = false
+    }
+
+    async doQuery() {
+      this.loading.query = true
+      await Promise.all([
+        this.fetchBaseReport(),
+        this.fetchFlawReport(),
+        this.fetchHealthReport(),
+        this.fetchAssessmentReport(),
+        this.fetchReportPage()
+      ])
+      this.loading.query = false
+    }
+
+    onPageChange(pagination) {
+      this.pagination = { ...this.pagination, ...pagination }
+      this.doQuery()
+    }
+
+    preparing() {
+      this.doQuery()
+    }
+
+    mounted() {
+      this.preparing()
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .content {
+    padding: 0 $gutter $gutter;
+    background-color: $--color-white;
+    color: $--color-text-primary;
+    .title {
+      text-align: center;
+      font-size: $--font-size-large;
+      border-bottom: $--border-base;
+      padding: $gutter 0;
+      font-weight: bold;
+      margin-bottom: $gutter;
+    }
+  }
+</style>

+ 17 - 9
src/views/spectrum/reform/statistics/ChartItem.vue

@@ -14,7 +14,7 @@
 </template>
 
 <script lang="ts">
-  import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
+  import { Vue, Component, Prop } from 'vue-property-decorator'
   import { IStatisticsData } from '../api/common'
   import emptyImg from '@/assets/icon/null.png'
   import { IPointTarget } from '../../configuration/api/common'
@@ -45,11 +45,11 @@
             { name: 'minValue', displayName: '最大值' },
             { name: 'maxValue', displayName: '最小值' },
             { name: 'avgValue', displayName: '平均值' }
-          ].map((item) => {
+          ].map((item, typeIndex) => {
             return {
               name: `${this.getCodeName(checkCode)}-${item.displayName}`,
               type: 'line',
-              symbol: 'none',
+              symbol: { '0': 'emptyCircle', '1': 'rect', '2': 'triangle' }[String(typeIndex)],
               smooth: true,
               dimensions: ['xposition', item],
               datasetIndex: index
@@ -60,13 +60,21 @@
       return {
         tooltip: { trigger: 'axis' },
         calculable: true,
-        xAxis: [{ type: 'category', boundaryGap: false }],
+        xAxis: [
+          {
+            type: 'category',
+            boundaryGap: false,
+            data: [
+              ...new Set(dataset.map((item) => item.source.map((item: { xposition: string }) => item.xposition)).flat())
+            ].sort((a, b) => (a > b ? 0 : -1))
+          }
+        ],
         yAxis: [{ type: 'value', min: ({ min }) => min }],
-        // dataZoom: [
-        //   { type: 'inside', start: 0, end: 100 },
-        //   { start: 0, end: 100 }
-        // ],
-        // legend: { show: true, type: 'scroll' },
+        dataZoom: dataset.some(({ source }) => source.length > 100) && [
+          { type: 'inside', start: 0, end: 100 },
+          { start: 0, end: 100 }
+        ],
+        legend: this.itemKey === 'monthData' && { show: true, type: 'scroll', width: '80%' },
         grid: { top: 45, left: 45, right: 45, bottom: 30, containLabel: true },
         toolbox: {
           show: true,

+ 17 - 7
src/views/spectrum/reform/statistics/DayAndHourChart.vue

@@ -23,7 +23,7 @@
   @Component({ name: 'ChartItem' })
   export default class ChartItem extends Vue {
     @Prop({ type: String }) title!: string
-    @Prop({ type: Array, default: () => [] }) data!: IStatisticsDayNHour
+    @Prop({ type: Object, default: () => ({}) }) data!: IStatisticsDayNHour
     @Prop({ type: Array, default: () => [] }) standards!: IPointTarget['showVos']
     emptyImg = emptyImg
 
@@ -33,7 +33,7 @@
     }
 
     get option() {
-      const { datas, rainFallVos } = this.data
+      const { datas = [], rainFallVos = [] } = this.data
       const dataset = [
         {
           id: 'rainfall',
@@ -44,7 +44,7 @@
           source: statisticalData
         }))
       ]
-
+      // 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
       const series = dataset
         .map(({ id }, index) => {
           return index === 0
@@ -53,20 +53,20 @@
                 dimensions: ['xposition', 'rfallTotal'],
                 datasetIndex: index,
                 type: 'line',
-                symbol: 'none',
+                symbol: 'circle',
                 smooth: true
               }
             : [
                 { name: 'minValue', displayName: '最大值' },
                 { name: 'maxValue', displayName: '最小值' },
                 { name: 'avgValue', displayName: '平均值' }
-              ].map((item) => {
+              ].map((item, typeIndex) => {
                 return {
                   name: `${this.getCodeName(id)}-${item.displayName}`,
                   dimensions: ['xposition', item],
                   datasetIndex: index,
                   type: 'line',
-                  symbol: 'none',
+                  symbol: { '0': 'emptyCircle', '1': 'rect', '2': 'triangle' }[String(typeIndex)],
                   smooth: true
                 }
               })
@@ -76,7 +76,17 @@
       return {
         tooltip: { trigger: 'axis' },
         calculable: true,
-        xAxis: [{ type: 'category', boundaryGap: false }],
+        xAxis: [
+          {
+            type: 'category',
+            boundaryGap: false,
+            data: [
+              ...new Set(
+                dataset.map((item) => (item.source as { xposition: string }[]).map((item) => item.xposition)).flat()
+              )
+            ].sort((a, b) => (a > b ? 0 : -1))
+          }
+        ],
         yAxis: [{ type: 'value', min: ({ min }) => min }],
         dataZoom: dataset.some(({ source }) => source.length > 100) && [
           { type: 'inside', start: 0, end: 100 },

+ 27 - 0
src/views/spectrum/reform/statistics/Map.vue

@@ -0,0 +1,27 @@
+<template>
+  <div class="map">
+    <div>
+      <mini-map />
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+  import { Vue, Component, Prop } from 'vue-property-decorator'
+  import MiniMap from '@/views/widgets/miniMap/index.vue'
+
+  @Component({ name: 'PointMap', components: { MiniMap } })
+  export default class Map extends Vue {}
+</script>
+
+<style lang="scss">
+  .map {
+    height: 100%;
+    position: relative;
+    > div {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+    }
+  }
+</style>

+ 19 - 5
src/views/spectrum/reform/statistics/QueryForm.vue

@@ -1,12 +1,18 @@
 <template>
   <el-form class="form" ref="form" v-bind="{ labelWidth: 'auto', size: 'small' }" :model="formData" inline>
     <el-form-item label="监测站点">
-      <el-select v-model="formData.siteId" @change="onPintChange" filterable :disabled="loading.query">
+      <el-select
+        v-model="formData.siteId"
+        @change="onPintChange"
+        filterable
+        :disabled="loading.query"
+        :loading="fetchingPoint"
+      >
         <el-option v-for="item in points" :key="item.id" :label="item.siteName" :value="item.id" />
       </el-select>
     </el-form-item>
     <el-form-item label="监测指标">
-      <el-select v-model="formData.checkCode" collapse-tags :disabled="loading.query" multiple>
+      <el-select v-model="formData.checkCode" collapse-tags :disabled="fetchingPoint" multiple>
         <el-option v-for="item of standards" :key="item.targetCode" :label="item.targetName" :value="item.targetCode" />
       </el-select>
     </el-form-item>
@@ -51,7 +57,9 @@
     @Prop({ type: Object, default: () => ({}) }) loading!: ILoading
     formData: { siteId: number; checkCode: number[] } = { siteId: undefined, checkCode: [] }
     @Prop({ type: Array, default: () => [] }) points!: IPoint[]
+    @Prop({ type: Boolean, default: false }) fetchingPoint!: ILoading
     standards: IPointTarget['showVos'] = []
+    fetchingStandard: boolean = false
     onQuery() {
       this.$emit('query', { ...this.formData, checkCode: this.formData.checkCode.join() })
     }
@@ -67,9 +75,15 @@
 
     async fetchStandard(sectionId) {
       this.standards = []
-      const { result } = await getTargets({ sectionId })
-      this.standards = result.showVos
-      this.$emit('standard-change', this.standards)
+      this.fetchingStandard = true
+      try {
+        const { result } = await getTargets({ sectionId })
+        this.standards = result.showVos
+        this.$emit('standard-change', this.standards)
+      } catch (error) {
+        console.log(error)
+      }
+      this.fetchingStandard = false
     }
   }
 </script>

+ 5 - 4
src/views/spectrum/reform/statistics/QuerySummary.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="summary">
     <tf-title>统计分析概况</tf-title>
-    <el-row :gutter="10">
+    <el-row :gutter="10" type="flex">
       <el-col :span="12" class="content">
         <el-row type="flex">
           <span style="white-space: nowrap">站点名称:</span>
@@ -32,12 +32,12 @@
         </el-row>
         <div class="notes" v-if="info.notes || noteEditing">
           <template v-if="noteEditing">
-            <el-input type="textarea" :rows="5" v-model="note" />
+            <el-input type="textarea" :rows="5" v-model="note" maxlength="1000" />
           </template>
           <template v-else>{{ info.notes }}</template>
         </div>
       </el-col>
-      <el-col :span="12"> this is a map </el-col>
+      <el-col :span="12"><Map /></el-col>
     </el-row>
   </div>
 </template>
@@ -46,8 +46,9 @@
   import { Vue, Component, Prop } from 'vue-property-decorator'
   import { IStatisticsBase } from '../api/common'
   import { addNote } from '../api/statistics'
+  import Map from './Map.vue'
 
-  @Component({ name: 'QuerySummary' })
+  @Component({ name: 'QuerySummary', components: { Map } })
   export default class QuerySummary extends Vue {
     @Prop({ type: Object, default: () => ({}) }) info!: IStatisticsBase
     @Prop({ type: Number }) siteId!: number

+ 40 - 9
src/views/spectrum/reform/statistics/widget.vue

@@ -7,6 +7,7 @@
         :points="points"
         @point-change="onPointChange"
         @standard-change="standards = $event"
+        :fetching-point="dataLoading.base"
       />
     </template>
     <div class="content">
@@ -17,9 +18,9 @@
         <span>监测天数:{{ baseData.days || '-' }}天</span>
         <span>数据事件:{{ getIntervalValue(baseData.beginDate, baseData.endDate, '-') }} </span>
       </el-row>
-      <el-row>
+      <el-row :gutter="15">
         <el-col :span="12">
-          <QuerySummary :info="baseData" :siteId="query.siteId" @refresh="fetchBaseData" />
+          <QuerySummary :info="baseData" :siteId="query.siteId" @refresh="fetchBaseData" v-loading="dataLoading.base" />
         </el-col>
         <el-col :span="12" style="margin-top: 1em">
           <el-row :gutter="15">
@@ -62,7 +63,7 @@
         <tf-title slot="title">
           <el-row type="flex" align="middle">
             <span style="margin-right: 3em">按天统计</span>
-            <el-radio-group v-model="day.type" size="small">
+            <el-radio-group v-model="day.type" size="small" @change="onDayTypeChange">
               <el-radio label="day">近30天</el-radio>
               <el-radio label="custom">自定义时间</el-radio>
             </el-radio-group>
@@ -77,6 +78,8 @@
               size="small"
               value-format="yyyy-MM-dd"
               style="margin-left: 2em; width: 250px"
+              :disabled="day.type === 'day'"
+              @change="onDayChange"
             />
           </el-row>
         </tf-title>
@@ -85,7 +88,7 @@
         <tf-title slot="title">
           <el-row type="flex" align="middle">
             <span style="margin-right: 3em">按小时统计</span>
-            <el-radio-group v-model="hour.type" size="small">
+            <el-radio-group v-model="hour.type" size="small" @change="onHourTypeChange">
               <el-radio label="hour">近24小时</el-radio>
               <el-radio label="custom">自定义时间</el-radio>
             </el-radio-group>
@@ -100,6 +103,8 @@
               size="small"
               value-format="yyyy-MM-dd"
               style="margin-left: 2em; width: 250px"
+              :disabled="hour.type === 'hour'"
+              @change="onHourChange"
             />
           </el-row>
         </tf-title>
@@ -121,6 +126,11 @@
   import { pointPage } from '../../configuration/api/point'
   import { fetchData, fetchDayData, fetchBaseData, fetchHourData, IQueryParam } from '../api/statistics'
   import { IStatisticsBase, IStatisticsData, IStatisticsDayNHour } from '../api/common'
+  import moment from 'moment'
+
+  const format = 'YYYY-MM-DD'
+  const get30Days = () => [moment().add(-1, 'month').format(format), moment().format(format)]
+  const get24Hours = () => [moment().add(-1, 'day').format(format), moment().format(format)]
 
   @Component({ name: 'Statistics', components: { QueryForm, ChartItem, QuerySummary, DayAndHourChart } })
   export default class Statistics extends Vue {
@@ -142,14 +152,18 @@
     point: Partial<IPoint> = {}
 
     query: Partial<IQueryParam> = {}
-    day = { type: 'day', datetime: [this.$moment().toDate(), this.$moment().add(-1, 'month').toDate()] }
-    hour = { type: 'hour', datetime: [this.$moment().toDate(), this.$moment().add(-24, 'hour').toDate()] }
+    day = { type: 'day', datetime: get30Days() }
+    hour = { type: 'hour', datetime: get24Hours() }
 
-    data: Partial<IStatisticsData> = {}
+    data: Partial<IStatisticsData>[] = []
     baseData: Partial<IStatisticsBase> = {}
     dayData: Partial<IStatisticsDayNHour> = {}
     hourData: Partial<IStatisticsDayNHour> = {}
 
+    get isReady() {
+      return !!this.query.siteId && !!this.query.checkCode && this.query.checkCode.length > 0
+    }
+
     onQuery(query: Partial<IQueryParam>) {
       this.query = { ...query }
       this.baseData = {}
@@ -181,7 +195,8 @@
     async fetchDayData() {
       this.dataLoading.day = true
       try {
-        const { result: dayData } = await fetchDayData(this.query)
+        const [beginDate, endDate] = this.day.datetime || []
+        const { result: dayData } = await fetchDayData({ ...this.query, beginDate, endDate })
         this.dayData = dayData
       } catch (error) {
         console.log(error)
@@ -191,7 +206,8 @@
     async fetchHourData() {
       this.dataLoading.hour = true
       try {
-        const { result: hourData } = await fetchHourData(this.query)
+        const [beginDate, endDate] = this.hour.datetime || []
+        const { result: hourData } = await fetchHourData({ ...this.query, beginDate, endDate })
         this.hourData = hourData
       } catch (error) {
         console.log(error)
@@ -225,6 +241,21 @@
       }
     }
 
+    onDayTypeChange(type) {
+      if (type === 'day') this.day.datetime = get30Days()
+      if (this.isReady) this.fetchDayData()
+    }
+    onDayChange() {
+      if (this.isReady) this.fetchDayData()
+    }
+    onHourTypeChange(type) {
+      if (type === 'hour') this.hour.datetime = get24Hours()
+      if (this.isReady) this.fetchHourData()
+    }
+    onHourChange() {
+      if (this.isReady) this.fetchHourData()
+    }
+
     preparing() {
       this.getAllPoints()
     }