Просмотр исходного кода

task-6188 质量指标看板重构

tianxinyu 2 часов назад
Родитель
Сommit
51200442c2

+ 14 - 0
src/api/platform/chart/chart.js

@@ -0,0 +1,14 @@
+import request from '@/utils/request'
+import { BUSINESS_BASE_URL } from '@/api/baseUrl'
+
+/**
+ * 查询质量目标
+ * @param {*} params
+ */
+export function getQualityIndicator (params) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/report/statistic/qualityIndicatorDashBoard',
+        method: 'get',
+        params
+    })
+}

+ 175 - 0
src/views/business/qualityTarget/components/muBiaoChart.vue

@@ -0,0 +1,175 @@
+<template>
+  <div :class="$style.container">
+      <template v-for="(row, rowIndex) in rowData">
+          <dv-decoration-10 v-if="rowIndex === 1" :key="`lineOne${rowIndex}`" />
+          <div :key="`row${rowIndex}`" :class="$style.row" :style="`width: ${row.length / 2 * 100}%;`">
+              <template v-for="(item, index) in row">
+                  <div :key="`${rowIndex * 2 + index}`" :class="$style.column" :style="`width: ${1 / row.length * 100}%;`">
+                      <div :id="`card${rowIndex * 2 + index}`" />
+                  </div>
+                  <dv-decoration-2
+                      v-if="index !== row.length - 1"
+                      :key="`line${rowIndex * 2 + index}`"
+                      :reverse="true"
+                      :dur="2 + index * 2"
+                  />
+              </template>
+          </div>
+          <dv-decoration-10 v-if="rowIndex === 1" :key="`lineTwo${rowIndex}`" />
+      </template>
+  </div>
+</template>
+<script>
+import * as echarts from 'echarts'
+import { monthChartOption } from '../constants/option'
+export default {
+  name: 'mubiao',
+  components: {},
+  props: {
+      info: {
+          type: Array,
+          default: () => []
+      },
+      fontSize: {
+          type: Number,
+          default: 18
+      },
+      chooseYear: {
+          type: String,
+          default: ''
+      },
+      zhibiao: {
+        type: String,
+        default: ''
+      }
+  },
+  data () {
+      return {
+        chartInstances: [] 
+      }
+  },
+  computed: {
+      rowData () {
+          const data = []
+          for (let i = 0; i < this.info.length; i += 2) {
+              data.push(this.info.slice(i, i + 2))
+          }
+          return data
+      }
+  },
+  watch: {
+      info: {
+          handler () {
+              this.init()
+          },
+          deep: true
+      }
+  },
+  created () {},
+  mounted () {
+      this.init()
+  },
+  methods: {
+      init () {
+        this.destroyCharts()
+        let that = this
+          // const D = new Date()
+          // 控制数据显示,历史数据显示整年,本年度数据显示到上一个月
+          // const y = parseInt(D.toJSON().slice(0, 4))
+          const w = window.innerWidth
+          this.fontSize = w >= 1600 ? 20 : w > 1366 && w < 1600 ? 18 : 16
+
+          setTimeout(() => {
+              this.info.forEach((item, index) => {
+                console.log('index', index)
+                const chart = echarts.init(document.getElementById(`card${index}`))
+                  
+                  const option = JSON.parse(JSON.stringify(monthChartOption))
+                  const xData = item.xAxis
+                  const yData = item.series[0]['data']
+                  option.title.text = item.title
+                  option.title.subtext = `${item.subtext}`
+                  if(item.yAxisConfig){
+                    option.yAxis.max = item.yAxisConfig.max
+                    option.yAxis.min = item.yAxisConfig.min
+                  }
+                  option.tooltip = {
+                    trigger: 'axis',
+                    axisPointer: {
+                      type: 'shadow'
+                    }
+                  }
+                  
+                  option.title.textStyle.fontSize = this.fontSize
+                  option.xAxis.data = xData
+                  option.series[0].data = yData
+                  option.series[0].label.show = false
+                  option.series[0].type = item.series[0]['type']
+                  option.series[0].name = item.title
+                  option.series[0].markLine = item.series[0].markLine
+                  chart.setOption(option)
+                  chart.on('click', 'series.bar', params => {  
+                    // console.log('params', params)
+                    that.sendToParent({
+                      xName: params.name,
+                      title: params.seriesName,
+                    })
+                  });
+                  this.chartInstances.push(chart)
+              })
+              
+          }, 100)
+      },
+      sendToParent(data){
+        this.$emit('child-event', data);
+      },
+      destroyCharts() {
+        // 销毁所有图表实例
+        this.chartInstances.forEach(chart => {
+            if (chart && !chart.isDisposed()) {
+                chart.dispose()  // 销毁实例,释放内存
+            }
+        })
+        this.chartInstances = []  // 清空数组
+      },
+      // 组件销毁前自动调用
+      beforeDestroy() {
+          this.destroyCharts()
+      }
+  }
+}
+</script>
+<style lang="scss" module>
+  .container {
+      width: 96%;
+      height: calc(100% - 40px);
+      padding: 20px 2%;
+      .row {
+          position: relative;
+          display: flex;
+          justify-content: space-between;
+          width: 100%;
+          height: calc((100% - 70px) / 2);
+          .column {
+              width: 48%;
+              height: 100%;
+              background-color: rgba(6, 30, 93, 0.5);
+              > div {
+                  width: 100%;
+                  height: 100%;
+              }
+          }
+      }
+      :global {
+          .dv-decoration-10 {
+              width: 96%;
+              height: 5px;
+              margin: 15px 2%;
+          }
+          .dv-decoration-2 {
+              width:5px;
+              height:100%;
+          }
+      }
+  }
+</style>

+ 164 - 0
src/views/business/qualityTarget/components/zhiBiaoChart.vue

@@ -0,0 +1,164 @@
+<template>
+  <div :class="$style.container">
+      <template v-for="(row, rowIndex) in rowData">
+          <dv-decoration-10 v-if="rowIndex === 1" :key="`lineOne${rowIndex}`" />
+          <div :key="`row${rowIndex}`" :class="$style.row" :style="`width: ${row.length / 2 * 100}%;`">
+              <template v-for="(item, index) in row">
+                  <div :key="`${rowIndex * 2 + index}`" :class="$style.column" :style="`width: ${1 / row.length * 100}%;`">
+                      <div :id="`cardzhibiao${rowIndex * 2 + index}`" />
+                  </div>
+                  <dv-decoration-2
+                      v-if="index !== row.length - 1"
+                      :key="`line${rowIndex * 2 + index}`"
+                      :reverse="true"
+                      :dur="2 + index * 2"
+                  />
+              </template>
+          </div>
+          <dv-decoration-10 v-if="rowIndex === 1" :key="`lineTwo${rowIndex}`" />
+      </template>
+  </div>
+</template>
+<script>
+import * as echarts from 'echarts'
+import { monthChartOption } from '../constants/option'
+export default {
+  name: 'mubiao',
+  components: {},
+  props: {
+      info: {
+          type: Array,
+          default: () => []
+      },
+      fontSize: {
+          type: Number,
+          default: 18
+      },
+  },
+  data () {
+      return {
+        chartInstances: [] 
+      }
+  },
+  computed: {
+      rowData () {
+          const data = []
+          for (let i = 0; i < this.info.length; i += 2) {
+              data.push(this.info.slice(i, i + 2))
+          }
+          return data
+      }
+  },
+  watch: {
+      info: {
+          handler () {
+              this.init()
+          },
+          deep: true
+      }
+  },
+  created () {},
+  mounted () {
+      this.init()
+  },
+  methods: {
+      init () {
+        this.destroyCharts()
+        let that = this
+          const D = new Date()
+          // 控制数据显示,历史数据显示整年,本年度数据显示到上一个月
+          // const y = parseInt(D.toJSON().slice(0, 4))
+          const w = window.innerWidth
+          this.fontSize = w >= 1600 ? 20 : w > 1366 && w < 1600 ? 18 : 16
+
+          setTimeout(() => {
+              this.info.forEach((item, index) => {
+                console.log('index', index)
+
+                 
+                  const  chart = echarts.init(document.getElementById(`cardzhibiao${index}`))
+                 
+                  const option = JSON.parse(JSON.stringify(monthChartOption))
+                  const xData = item.xAxis
+                  const yData = item.series[0]['data']
+                  option.title.text = item.title
+                  option.title.subtext = `${item.subtext}`
+                  if(item.yAxisConfig){
+                    option.yAxis.max = item.yAxisConfig.max
+                    option.yAxis.min = item.yAxisConfig.min
+                  }
+                  
+                  option.title.textStyle.fontSize = this.fontSize
+                  option.xAxis.data = xData
+                  option.series[0].data = yData
+                  option.series[0].label.show = false
+                  option.series[0].type = item.series[0]['type']
+                  option.series[0].name = item.title
+                  option.series[0].markLine = item.series[0].markLine
+                  chart.setOption(option)
+                  chart.on('click', 'series.bar', params => {  
+                    // console.log('params', params)
+                    that.sendToParent({
+                      xName: params.name,
+                      title: params.seriesName,
+                    })
+                  });
+                  this.chartInstances.push(chart)
+              })
+              
+          }, 100)
+      },
+      sendToParent(data){
+        console.log('sendToParent', data)
+        this.$emit('child-event', data);
+      },
+      destroyCharts() {
+        // 销毁所有图表实例
+        this.chartInstances.forEach(chart => {
+            if (chart && !chart.isDisposed()) {
+                chart.dispose()  // 销毁实例,释放内存
+            }
+        })
+        this.chartInstances = []  // 清空数组
+      },
+      // 组件销毁前自动调用
+      beforeDestroy() {
+          this.destroyCharts()
+      }
+  }
+}
+</script>
+<style lang="scss" module>
+  .container {
+      width: 96%;
+      height: calc(100% - 40px);
+      padding: 20px 2%;
+      .row {
+          position: relative;
+          display: flex;
+          justify-content: space-between;
+          width: 100%;
+          height: calc((100% - 70px) / 2);
+          .column {
+              width: 48%;
+              height: 100%;
+              background-color: rgba(6, 30, 93, 0.5);
+              > div {
+                  width: 100%;
+                  height: 100%;
+              }
+          }
+      }
+      :global {
+          .dv-decoration-10 {
+              width: 96%;
+              height: 5px;
+              margin: 15px 2%;
+          }
+          .dv-decoration-2 {
+              width:5px;
+              height:100%;
+          }
+      }
+  }
+</style>

+ 311 - 0
src/views/business/qualityTarget/components/zhibiaoDialog.vue

@@ -0,0 +1,311 @@
+<template>
+
+  <el-dialog
+    :visible.sync="dialogVisible"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    width="90%"
+    class="dialog"
+    top="6vh"
+  >
+  <div class="content">
+    <div class="header">
+        <dv-decoration-8 class="left" />
+        <dv-decoration-5 class="center" :dur="5" />
+        <dv-decoration-8 class="right" :reverse="true" />
+        <div class="title">{{ targetName }}</div>
+          
+        <div class="back" @click.prevent="closeDialog">
+            <dv-border-box-8>返回</dv-border-box-8>
+        </div>
+        <div class="parse" @click="toggleAutoPlay">
+            <img v-if="autoPlay" src="~@/assets/images/icons/parse.png">
+            <img v-else src="~@/assets/images/icons/play.png">
+        </div>
+        <div class="pnButton">
+          <el-button
+            icon="el-icon-arrow-left"
+            class="preNextButton"
+            circle
+            @click.native="skipTo('pre')"
+          ></el-button>
+          <div class="textContent">{{ chartIndex + 1 }}</div>
+          <el-button
+            icon="el-icon-arrow-right"
+            class="preNextButton"
+            circle
+            @click.native="skipTo('next')"
+          ></el-button>
+        </div>
+    </div>
+    <dv-border-box-1>
+        <zhi-biao-chart v-if="renderData.length" :info="renderData" :font-size="fontSize" :choose-year="year" :zhibiao="targetName" />
+    </dv-border-box-1>
+  </div>
+</el-dialog>
+</template>
+<script>
+import { getQualityIndicator } from '@/api/platform/chart/chart'
+export default {
+  components: {
+    ZhiBiaoChart: () => import('./zhiBiaoChart.vue'),
+  },
+  props: {
+    targetName: {
+      type: String,
+      default: ''
+    },
+    dateRange: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+      const d = new Date()
+      return {
+          dialogVisible: true,
+          loading: false,
+          fullscreen: false,
+
+          level: '',
+          year: d.toJSON().slice(0, 4),
+          initData: {},
+          renderData: [],
+          fontSize: 18,
+          chartIndex: 0,
+          dataFetchTimer: null,
+          autoPlayTimer: null,
+          autoPlay: true,
+          size: 4,
+          pageAll: 0,
+          BeginDate: "",
+          endDate: "2026-02",
+          dataScope: [],
+      }
+  },
+  watch: {
+      chartIndex (v) {
+        this.renderData = this.initData && this.initData.length > 0 ? this.initData.slice(v * this.size, (v + 1) * this.size) : []
+      }
+  },
+  mounted () {
+    this.updateAll()
+  },
+  beforeDestroy () {
+    this.clenUp()
+  },
+  methods: {
+    closeDialog() {
+      this.$emit('closeDialog')
+    },
+      initializeData () {
+          const w = window.innerWidth
+          const { first = '', second = '' } = this.$store.getters.level || {}
+
+          this.initData = {}
+          this.chartIndex = 0
+          this.level = second || first    
+          this.fontSize = w >= 1600 ? 20 : w > 1366 && w < 1600 ? 18 : 16
+      },
+      updateAll () {
+          this.initializeData()
+          this.fetchData().then(() => {
+              this.startAutoPlay()
+              this.renderData = this.initData ? this.initData.slice(this.chartIndex * this.size, (this.chartIndex + 1) * this.size) : []
+          })
+      },
+      async fetchData () {
+        return new Promise((resolve, reject) => {
+          const params = {
+            requestType: 'zhibiao',
+            targetName: this.targetName,
+            dateRange: this.dateRange  //202601-202612
+          }
+          getQualityIndicator(params).then(res => { 
+            this.initData = res.data
+            this.pageAll = Math.ceil(this.initData.length / this.size)
+            console.log(this.pageAll, 'this.initData',this.initData)
+            this.dialogVisible = true
+            resolve()
+          }).catch(error => {
+            reject(error)
+          }) 
+        })
+      },
+      startAutoPlay () {
+          this.autoPlay = true
+          if (this.autoPlayTimer) {
+              clearInterval(this.autoPlayTimer)
+          }
+          this.autoPlayTimer = setInterval(() => {
+              this.showNextData()
+          }, 5000)
+      },
+      stopAutoPlay () {
+          this.autoPlay = false
+          clearInterval(this.autoPlayTimer)
+      },
+      showNextData () {
+          if (!this.autoPlay) {
+              return
+          }
+          if (!this.initData) {
+              this.clenUp()
+              return
+          }
+          if ((this.chartIndex + 1) * this.size < this.initData.length) {
+              this.chartIndex++
+          } else  {
+              this.chartIndex = 0
+          }
+      },
+      setupTimer () {
+          // 每3分钟获取一次数据
+          if (this.dataFetchTimer) {
+              clearInterval(this.dataFetchTimer)
+          }
+          this.dataFetchTimer = setInterval(() => {
+              this.fetchData()
+          }, 180 * 1000)
+      },
+      clenUp () {
+          clearInterval(this.dataFetchTimer)
+          clearInterval(this.autoPlayTimer)
+      },
+      changeCycle (e) {
+          // 手动切换
+          this.stopAutoPlay()
+          // 更新当前指标
+          this.chartIndex = 0
+          this.startAutoPlay()
+      },
+      toggleAutoPlay () {
+          this.autoPlay ? this.stopAutoPlay() : this.startAutoPlay()
+      },
+      skipTo(type) {
+        this.stopAutoPlay()
+        if (type === "pre") {
+          if(this.chartIndex == 0){
+            this.chartIndex = this.pageAll - 1;
+          }else{
+            this.chartIndex = this.chartIndex - 1;
+          }
+        }else{
+          if(this.chartIndex == this.pageAll - 1){
+            this.chartIndex = 0;
+          }else{
+            this.chartIndex = this.chartIndex + 1;
+          }
+        }
+      }
+  }
+}
+</script>
+<style lang="scss" scoped>
+  
+  ::v-deep .el-dialog,
+  .dialog,
+  ::v-deep .el-dialog__body{
+      height: 90%;
+  }
+  ::v-deep .el-dialog__body{
+      height: 100%;
+  }
+  ::v-deep .el-dialog__header{
+    display: none;
+  }
+  .content{
+    width: 100%;
+    height: 100%;
+    z-index: 999;
+    background-image: url('~@/assets/images/screen/bg.png');
+    background-size: 100% 100%;
+    box-shadow: 0 0 3px blue;
+    display: flex;
+    flex-direction: column;
+  }
+      .header {
+          position: relative;
+          width: 100%;
+          height: 90px;
+          display: flex;
+          justify-content: space-between;
+          flex-shrink: 0;
+          .left, .right {
+              width: 25%;
+              height: 60px;
+          }
+          .center {
+              width: 40%;
+              height: 60px;
+              margin-top: 30px;
+          }
+          .title {
+              position: absolute;
+              font-size: 30px;
+              font-weight: bold;
+              left: 50%;
+              top: 15px;
+              transform: translateX(-50%);
+              color: #fff;
+          }
+          .back, .parse {
+              width: 8%;
+              max-width: 180px;
+              cursor: pointer;
+              height: 2.825rem;
+              line-height: 2.825rem;
+              text-align: center;
+              margin-top: 3.5%;
+              flex: 1;
+              position: absolute;
+              color: #ffffff;
+          }
+          .back {
+              width: 5%;
+              left: 78%;
+          }
+          .parse {
+              width: 2%;
+              left: 73%;
+              align-items: center;
+              padding: 5px;
+              > img {
+                  height: calc(100% - 10px);
+              }
+          }
+      }
+
+  .pnButton {
+    width: 8%;
+    font-size: 100%;
+    text-align: left;
+    position: absolute;
+    left: 63%;
+    margin-top: 3.5%;
+    padding: 5px;
+    .textContent {
+      display: inline-block;
+      width: 25%;
+      font-size: 115%;
+      text-align: center;
+      color: rgb(63, 150, 165);
+    }
+    .preNextButton {
+      background: transparent;
+      border: 2px solid rgb(63, 150, 165);
+      padding: 10px; 
+    }
+    :v-deep .el-icon-arrow-left {
+      font-size: 18px;
+      font-weight: 900;
+      color: rgb(63, 150, 165);
+    }
+    :v-deep .el-icon-arrow-right {
+      font-size: 18px;
+      font-weight: 900;
+      color: rgb(63, 150, 165);
+    }
+  }
+</style>

+ 202 - 182
src/views/business/qualityTarget/index.vue

@@ -7,104 +7,99 @@
                 <dv-decoration-5 :class="$style.center" :dur="5" />
                 <dv-decoration-8 :class="$style.right" :reverse="true" />
                 <div :class="$style.title">{{ title }}</div>
-                <dv-border-box-8 :class="$style.year">
+                  <div :class="$style.year" @click.prevent="tabChange()">
+                    <dv-border-box-8>{{tab == 'mubiao' ? '质量目标' : '质量指标'}}</dv-border-box-8>
+                  </div>
+                  <div
+                    :class="$style.datewrap"
+                    v-if="tab == 'zhibiao'"
+                  >
+                    <div>月份:</div>
                     <el-date-picker
-                        v-model="year"
-                        type="year"
-                        value-format="yyyy"
-                        format="yyyy"
-                        placeholder="统计年度"
-                        style="width: 80px"
-                        :readonly="false"
-                        :editable="true"
-                        :clearable="false"
-                        @change="updateAll"
-                    />
-                </dv-border-box-8>
-                <dv-decoration-7 :class="$style.cycle">
-                    <el-dropdown @command="changeCycle">
-                        <span class="el-dropdown-link" :style="`font-size: ${fontSize}px;`">{{ selectedCycle }}</span>
-                        <el-dropdown-menu slot="dropdown" class="dept-dropdown">
-                            <el-dropdown-item
-                                v-for="(item, index) in cycleList"
-                                :key="index"
-                                :command="index"
-                            >{{ item }}</el-dropdown-item>
-                        </el-dropdown-menu>
-                    </el-dropdown>
-                </dv-decoration-7>
+                      v-model="endDate"
+                      type="monthrange"
+                      align="right"
+                      unlink-panels
+                      style="background-color: transparent;color: #fff"
+                      format="yyyy 年 MM 月"
+                      value-format="yyyy-MM"
+                      @change="checkYear(endDate, 'end')"
+                      range-separator="至"
+                      start-placeholder="开始日期"
+                      end-placeholder="结束日期"
+                    >
+                    </el-date-picker>
+                  </div>
+                  
                 <div :class="$style.back" @click.prevent="goBack()">
-                    <dv-border-box-8>返回</dv-border-box-8>
+                    <dv-border-box-8>退出</dv-border-box-8>
                 </div>
                 <div :class="$style.parse" @click="toggleAutoPlay">
                     <img v-if="autoPlay" src="~@/assets/images/icons/parse.png">
                     <img v-else src="~@/assets/images/icons/play.png">
                 </div>
+                <div :class="$style.pnButton">
+                  <el-button
+                    icon="el-icon-arrow-left"
+                    :class="$style.preNextButton"
+                    circle
+                    @click.native="skipTo('pre')"
+                  ></el-button>
+                  <div :class="$style.textContent">{{ chartIndex + 1 }}</div>
+                  <el-button
+                    icon="el-icon-arrow-right"
+                    :class="$style.preNextButton"
+                    circle
+                    @click.native="skipTo('next')"
+                  ></el-button>
+                </div>
             </div>
             <!-- 图表区域 -->
             <dv-border-box-1>
-                <month-chart v-if="renderData.length && selectedCycle === '每月'" :info="renderData" :font-size="fontSize" :choose-year="year" />
-                <quarter-chart v-if="renderData.length && selectedCycle === '每季度'" :info="renderData" :font-size="fontSize" :choose-year="year" />
-                <year-chart v-if="renderData.length && selectedCycle === '每年'" :info="renderData" :font-size="fontSize" :choose-year="year" />
+              <mu-biao-chart v-if="renderData.length" :info="renderData" :font-size="fontSize" :choose-year="year" @child-event="handleChildEvent"  />
             </dv-border-box-1>
         </dv-full-screen-container>
+        <zhibiao-dialog v-if="showDialog" loading="true" :targetName="zhibiao" :dateRange="dateRange" @closeDialog="showDialog = false"></zhibiao-dialog>
     </div>
 </template>
 <script>
 import screenfull from 'screenfull'
+import { getQualityIndicator } from '@/api/platform/chart/chart'
 export default {
     components: {
-        MonthChart: () => import('./components/monthChart.vue'),
-        QuarterChart: () => import('./components/quarterChart.vue'),
-        YearChart: () => import('./components/yearChart.vue')
+        MuBiaoChart: () => import('./components/muBiaoChart.vue'),
+        ZhibiaoDialog: () => import('./components/zhibiaoDialog.vue')
     },
     data () {
         const d = new Date()
         return {
+            tab: 'mubiao',
             level: '',
-            title: '质量指标统计',
+            title: '质量指标看板',
             year: d.toJSON().slice(0, 4),
             cycleList: [],
-            sizeMap: {
-                '每月': 4,
-                '每季度': 4,
-                '每年': 4
-            },
-            // year: '2023',
             initData: {},
             renderData: [],
             fontSize: 18,
-            itemIndex: 0,
             chartIndex: 0,
             dataFetchTimer: null,
             autoPlayTimer: null,
-            autoPlay: true
-        }
-    },
-    computed: {
-        selectedCycle () {
-            return this.cycleList[this.itemIndex] || '每月'
-        },
-        size () {
-            return this.sizeMap[this.selectedCycle]
+            autoPlay: true,
+            size: 4,
+            pageAll: 0,
+            BeginDate: "",
+            endDate: "2026-02",
+            dataScope: [],
+            dateRange: '',
+            showDialog: false,
+            zhibiao: ''
         }
     },
     watch: {
         chartIndex (v) {
-            this.renderData = this.initData[this.selectedCycle] ? this.initData[this.selectedCycle].slice(v * this.size, (v + 1) * this.size) : []
-        },
-        itemIndex (v) {
-            this.renderData = this.initData[this.selectedCycle] ? this.initData[this.selectedCycle].slice(this.chartIndex * this.size, (this.chartIndex + 1) * this.size) : []
+          this.renderData = this.initData && this.initData.length > 0 ? this.initData.slice(v * this.size, (v + 1) * this.size) : []
         }
     },
-    // beforeRouteEnter (to, from, next) {
-    //     Promise.all([]).done(([res]) => {
-    //         console.log(res)
-    //     }).then(err => {
-    //         window.observer.trigger('error', err)
-    //         next()
-    //     })
-    // },
     created () {
         // 默认全屏展示
         if (screenfull.isEnabled && !screenfull.isFullscreen) {
@@ -112,6 +107,13 @@ export default {
         }
 
         this.updateAll()
+
+        if (!this.BeginDate && !this.endDate) {
+          this.BeginDate = this.getDate(1) + "";
+          this.endDate = this.getDate(0);
+          this.dataScope.push(this.BeginDate);
+          this.dataScope.push(this.endDate);
+        }
     },
     beforeDestroy () {
         if (screenfull.isFullscreen) {
@@ -120,14 +122,57 @@ export default {
         this.clenUp()
     },
     methods: {
+      handleChildEvent(e) {
+        console.log('子组件传参',e)
+        this.zhibiao = e.title
+        this.dateRange = `${e.xName.split('年度')[0]}01-${e.xName.split('年度')[0]}12`
+        this.stopAutoPlay()
+        this.showDialog = true
+      },
+      checkYear(date, date2) {       
+        this.dateRange = date.map(item => item.replace('-', '')).join('-')
+        this.updateAll()
+      },
+      /* 获取当前年份*/
+        getDate(year, isString) {
+          year = year || 0;
+          let nowDate = new Date();
+          let date = new Date(new Date().setDate(1) + 31 * 24 * 60 * 60 * 1000);
+          let month = date.getMonth() + 1;
+          let m1 = nowDate.getMonth() + 1;
+          let month1 = m1 < 10 ? "0" + m1 : nowDate.getMonth() + 1;
+          month = month < 10 ? "0" + month : "" + month;
+          if(isString){
+            return `${nowDate.getFullYear() - year}01-${nowDate.getFullYear()-year}${month1}`
+          }else{
+            return [
+              nowDate.getFullYear() - year + "-01",
+              nowDate.getFullYear() - year + "-" + month1,
+            ];
+          }
+          
+        },
+        tabChange () {
+          console.log(this.getDate(), 111)
+          if(this.tab == 'mubiao') {
+            this.tab = 'zhibiao'
+            this.dateRange = this.getDate(0, true)
+            this.endDate = this.getDate(0, false)
+          } else { 
+            this.tab = 'mubiao'
+            this.dateRange = ''
+          }
+          this.targetName = ''
+          this.chartIndex = 0
+          this.updateAll()
+        },
         initializeData () {
             const w = window.innerWidth
             const { first = '', second = '' } = this.$store.getters.level || {}
 
             this.initData = {}
-            this.itemIndex = 0
             this.chartIndex = 0
-            this.level = second || first
+            this.level = second || first    
             this.fontSize = w >= 1600 ? 20 : w > 1366 && w < 1600 ? 18 : 16
         },
         updateAll () {
@@ -135,49 +180,26 @@ export default {
             this.fetchData().then(() => {
                 this.startAutoPlay()
                 this.setupTimer()
-                this.renderData = this.initData[this.selectedCycle] ? this.initData[this.selectedCycle].slice(this.chartIndex * this.size, (this.chartIndex + 1) * this.size) : []
+                this.renderData = this.initData ? this.initData.slice(this.chartIndex * this.size, (this.chartIndex + 1) * this.size) : []
+                console.log('renderData',this.renderData)
             })
         },
         async fetchData () {
-            // 月度指标统计本年度,季度指标统计今年和去年,年度指标统计所有
-            // const sql = `select a.id_ as aid, a.di_dian_ as place, a.bian_zhi_bu_men_ as dept, a.tong_ji_pin_lv_ as cycle, a.tong_ji_yue_fen_ as statisticalTime, a.create_time_ as createTime, b.id_ as bid, b.zhi_liang_mu_biao as goal, b.zhi_liang_zhi_bia as target, b.zhi_biao_xian_zhi as limitValue, b.shi_ji_shu_zhi_ as result, b.yuan_shi_shu_ju_ as originalData from t_zlzbpjb a inner join (select tong_ji_yue_fen_, max(create_time_) as max from t_zlzbpjb where di_dian_ = '${this.level}' group by tong_ji_yue_fen_) a_latest on a.tong_ji_yue_fen_ = a_latest.tong_ji_yue_fen_ and a.create_time_ = a_latest.max left join t_zlzbpjzb b on a.id_ = b.parent_id_ where a.shi_fou_guo_shen_ = '已完成' and a.di_dian_ = '${this.level}' and ((a.tong_ji_pin_lv_ = '每月' and a.tong_ji_yue_fen_ like concat(${this.year}, '%') or (a.tong_ji_pin_lv_ = '每季度' and (a.tong_ji_yue_fen_ like concat(${this.year}, '%') or a.tong_ji_yue_fen_ like concat(${this.year - 1}, '%'))) or a.tong_ji_pin_lv_ = '每年')`
-            return new Promise((resolve, reject) => {
-                this.$common.request('query', {
-                    key: 'getQualityTargetData',
-                    params: [this.level, this.year, this.year - 1]
-                }).then(res => {
-                    const { data = [] } = res.variables || {}
-                    const dataMap = {
-                        '每月': new Array(12).fill({}),
-                        '每季度': this.generateQuarter(),
-                        '每年': this.generateYear()
-                    }
-                    // 组装数据
-                    const result = {}
-                    data.forEach((item, index) => {
-                        const { cycle, statisticalTime, target, result: targetValue, limitValue } = item
-                        if (!result[cycle]) {
-                            result[cycle] = []
-                        }
-                        let targetIndex = result[cycle].findIndex(i => i.title === target)
-                        if (targetIndex === -1) {
-                            result[cycle].push({
-                                title: target,
-                                data: dataMap[cycle].map(d => ({ ...d }))
-                            })
-                            targetIndex = result[cycle].length - 1
-                        }
-                        const dataIndex = cycle === '每月' ? parseInt(statisticalTime.split('年')[1].split('月')[0]) - 1 : result[cycle][targetIndex].data.findIndex(i => i.statisticalTime === statisticalTime)
-                        result[cycle][targetIndex].data[dataIndex] = { ...item, result: parseFloat(targetValue), limitValue: parseFloat(limitValue) }
-                    })
-                    this.initData = result
-                    this.cycleList = Object.keys(this.initData)
-                    console.log(this.initData)
-                    resolve()
-                }).catch(error => {
-                    reject(error)
-                })
-            })
+          return new Promise((resolve, reject) => {
+            const params = {
+              requestType: this.tab == 'mubiao' ? 'mubiao' : 'zhibiao',
+              targetName: this.targetName,
+              dateRange: this.dateRange  //202601-202612
+            }
+            getQualityIndicator(params).then(res => { 
+              this.initData = res.data
+              this.pageAll = Math.ceil(this.initData.length / this.size)
+              console.log(this.pageAll, 'this.initData',this.initData)
+              resolve()
+            }).catch(error => {
+              reject(error)
+            }) 
+          })
         },
         generateQuarter () {
             const result = []
@@ -213,21 +235,17 @@ export default {
             clearInterval(this.autoPlayTimer)
         },
         showNextData () {
-            // console.log(this.chartIndex)
+            console.log(this.chartIndex, '111111111')
             if (!this.autoPlay) {
                 return
             }
-            if (!this.initData[this.selectedCycle]) {
+            if (!this.initData) {
                 this.clenUp()
                 return
             }
-            if ((this.chartIndex + 1) * this.size < this.initData[this.selectedCycle].length) {
+            if ((this.chartIndex + 1) * this.size < this.initData.length) {
                 this.chartIndex++
-            } else if (this.itemIndex < this.cycleList.length - 1) {
-                this.itemIndex++
-                this.chartIndex = 0
-            } else {
-                this.itemIndex = 0
+            } else  {
                 this.chartIndex = 0
             }
         },
@@ -248,7 +266,6 @@ export default {
             // 手动切换
             this.stopAutoPlay()
             // 更新当前指标
-            this.itemIndex = e
             this.chartIndex = 0
             this.startAutoPlay()
         },
@@ -257,6 +274,22 @@ export default {
         },
         goBack () {
             this.$router.back(-1)
+        },
+        skipTo(type) {
+          this.stopAutoPlay()
+          if (type === "pre") {
+            if(this.chartIndex == 0){
+              this.chartIndex = this.pageAll - 1;
+            }else{
+              this.chartIndex = this.chartIndex - 1;
+            }
+          }else{
+            if(this.chartIndex == this.pageAll - 1){
+              this.chartIndex = 0;
+            }else{
+              this.chartIndex = this.chartIndex + 1;
+            }
+          }
         }
     }
 }
@@ -332,7 +365,7 @@ export default {
                 top: 15px;
                 transform: translateX(-50%);
             }
-            .year, .cycle, .back, .parse {
+            .year, .back, .parse {
                 width: 8%;
                 max-width: 180px;
                 cursor: pointer;
@@ -350,87 +383,74 @@ export default {
                 display: flex;
                 justify-content: center;
                 align-items: center;
-                :global {
-                    .el-input--small .el-input__inner {
-                        width: 100% !important;
-                        background: rgba(255, 255, 255, 0);
-                        border: none;
-                        color: #fff;
-                        font-size: 16px;
-                        cursor: pointer;
-                        // padding-left: 0;
-                        padding-right: 0;
-                    }
-                }
-            }
-            .cycle {
-                display: flex;
-                min-width: 150px;
-                justify-content: flex-end;
-                // width: 125px;
-                right: 75%;
-                padding-left: 10px;
-                color: #fff;
-                font-size: 22px;
-                font-weight: 400;
-                :global {
-                    .el-dropdown {
-                        width: calc(100% - 52px);
-                        text-overflow: ellipsis;
-                        overflow: hidden;
-                        white-space: nowrap;
-                        .el-dropdown-link {
-                            text-align: center;
-                        }
-                    }
-                }
             }
             .back {
                 width: 5%;
-                left: calc(75% + 80px);
+                left: calc(80% + 80px);
             }
             .parse {
                 width: 2%;
-                left: 75%;
+                left: 80%;
                 align-items: center;
                 padding: 5px;
                 > img {
                     height: calc(100% - 10px);
                 }
             }
-            @media only screen and (max-width: 1680px) {
-                .year, .cycle, .back, .parse {
-                    height: 2.5rem;
-                    line-height: 2.5rem;
-                    margin-top: 2.5%;
-                }
-                .year {
-                    right: 82%;
-                }
-                .cycle {
-                    width: 5%;
-                    min-width: 120px;
-                    font-size: 18px;
-                    font-weight: normal;
-                }
-                .back {
-                    left: calc(75% + 60px);
-                }
-            }
-            @media only screen and (max-width: 1366px) {
-                .year {
-                    right: 80%;
-                }
-                .cycle {
-                    right: 70%;
-                    min-width: 140px;
-                    font-size: 16px;
-                    font-weight: normal;
-                }
-                .back {
-                    left: calc(75% + 50px);
-                }
-            }
         }
     }
+
+    .pnButton {
+      width: 7%;
+      font-size: 100%;
+      text-align: left;
+      position: absolute;
+      left: calc(78% - 90px);
+      margin-top: 2%;
+      padding: 5px;
+      .textContent {
+        display: inline-block;
+        width: 25%;
+        font-size: 115%;
+        text-align: center;
+        color: rgb(63, 150, 165);
+      }
+      .preNextButton {
+        background: transparent;
+        border: 2px solid rgb(63, 150, 165);
+        padding: 6px;
+        :global {
+          .el-icon-arrow-left {
+            font-size: 18px;
+            font-weight: 900;
+            color: rgb(63, 150, 165);
+          }
+          .el-icon-arrow-right {
+            font-size: 18px;
+            font-weight: 900;
+            color: rgb(63, 150, 165);
+          }
+        }
+        
+      }
+    }
+    .datewrap{
+      width: 50%;
+      height: 45%;
+      line-height: 45%;
+      text-align: center;
+      margin: 2.3% 0 0 6.7%;
+      font-size: 100%;
+      color: #fff !important;
+      align-items: center;
+      display: flex;
+      position: absolute;
+      right: 32%;
+      :global{
+        .el-range-input{
+          color: #fff;
+          background: transparent;
+        }
+      }
+    }
 </style>

+ 26 - 26
src/views/statistics/index.vue

@@ -199,15 +199,15 @@
 
                 </div>
               </div> -->
-          <div
+          <!-- <div
             class="ttitle"
             style="text-align: center; height: 0.8%"
             v-if="pageOT == 1"
           >
             一、质量目标
-          </div>
+          </div> -->
 
-          <div
+          <!-- <div
             v-if="pageOT == 1"
             style="
               display: inline-block;
@@ -221,9 +221,9 @@
                 质量方针:{{ fangZhen }}
               </div></dv-border-box-7
             >
-          </div>
+          </div> -->
 
-          <div
+          <!-- <div
             v-if="pageOT == 1"
             class="congxiebox7"
             style="
@@ -328,9 +328,9 @@
                 暂无数据
               </div>
             </div>
-          </div>
+          </div> -->
 
-          <div
+          <!-- <div
             v-if="pageOT == 1"
             class="congxiebox7"
             style="
@@ -419,7 +419,7 @@
                 暂无数据
               </div>
             </div>
-          </div>
+          </div> -->
 
           <!--   <div
             class="congxiebox7"
@@ -874,7 +874,7 @@
             v-if="pageOT == pageAll + 2"
           >
             <div class="ttitle" style="text-align: center">
-              、人员培训与管理
+              、人员培训与管理
             </div>
             <div class="componentsData" style="height: 87%" v-if="relOf">
               <s4renYuanPeiXun
@@ -946,7 +946,7 @@
             "
             v-if="pageOT == pageAll + 3"
           >
-            <div class="ttitle" style="text-align: center">、设备维保</div>
+            <div class="ttitle" style="text-align: center">、设备维保</div>
             <div class="componentsData" style="height: 87%" v-if="relOf">
               <s7sheBeiJiaoZhun
                 style="height: 50%"
@@ -1009,7 +1009,7 @@
             "
             v-if="pageOT == pageAll + 4"
           >
-            <div class="ttitle" style="text-align: center">、质量管理</div>
+            <div class="ttitle" style="text-align: center">、质量管理</div>
             <div class="componentsData" style="height: 87%" v-if="relOf">
               <s9neiBuZhiLiang
                 style="height: 50%"
@@ -1071,7 +1071,7 @@
             "
             v-if="pageOT == pageAll + 5"
           >
-            <div class="ttitle" style="text-align: center">、质量管理</div>
+            <div class="ttitle" style="text-align: center">、质量管理</div>
             <div class="componentsData" style="height: 87%" v-if="relOf">
               <s15tousu
                 style="height: 50%"
@@ -1171,7 +1171,7 @@
             "
             v-if="pageOT == pageAll + 6"
           >
-            <div class="ttitle" style="text-align: center">、质量管理</div>
+            <div class="ttitle" style="text-align: center">、质量管理</div>
             <div class="componentsData" style="height: 87%" v-if="relOf">
               <s2manYiDu
                 style="height: 50%"
@@ -1229,7 +1229,7 @@
             "
             v-if="pageOT == pageAll + 7"
           >
-            <div class="ttitle" style="text-align: center">、质量管理</div>
+            <div class="ttitle" style="text-align: center">、质量管理</div>
             <div class="componentsData" style="height: 87%" v-if="relOf">
               <s1zhiLiangMuBiao
                 style="height: 50%"
@@ -1626,7 +1626,7 @@ export default {
       showComponents: {}, //显示全部统计子组件 , 若有新增,往后累计。 供动态表单进行查阅使用。
       dataScope: [],
       colorw: "#fff",
-      pageOT: 1,
+      pageOT: 2,
       rollup: true,
       idsStr: "",
       quality: [],
@@ -1767,7 +1767,7 @@ export default {
         }
       } else if (type === "next") {
         if (this.pageOT >= this.pageAll + 7) {
-          this.pageOT = 1;
+          this.pageOT = 2;
 
           this.showFenZu.title =
             this.zhiliangmuNeirong[0] !== undefined
@@ -1827,9 +1827,9 @@ export default {
         repostCurd("query", getfengxianObjFB(end, filterDept)),
         repostCurd("query", getneishenObjFB(end, filterDept)),
         repostCurd("query", getguanshenObjFB(end, filterDept)),
-        repostCurd("query", getzhiliangmubiaotitleObj(end, filterDept)),
-        repostCurd("query", getZhiLiangMuBiaoPZ(end)),
-        repostCurd("query", getZhiLiangMuBiao(end)),
+        // repostCurd("query", getzhiliangmubiaotitleObj(end, filterDept)),
+        // repostCurd("query", getZhiLiangMuBiaoPZ(end)),
+        // repostCurd("query", getZhiLiangMuBiao(end)),
       ]).then(
         ([
           response,
@@ -1859,9 +1859,9 @@ export default {
           fb5,
           fb6,
           fb7,
-          fb8,
-          response32,
-          response31,
+          // fb8,
+          // response32,
+          // response31,
         ]) => {
           that.config = response.variables.data;
           that.buhegelvObj = response1.variables.data;
@@ -1918,8 +1918,8 @@ export default {
           that.fengxianfbObj = fb5.variables.data;
           that.neishenfbObj = fb6.variables.data;
           that.guanshenfbObj = fb7.variables.data;
-          that.zhiliangmubiaotitle = fb8.variables.data;
-          that.muBiaoDataHandle(response32, response31);
+          // that.zhiliangmubiaotitle = fb8.variables.data;
+          // that.muBiaoDataHandle(response32, response31);
 
           that.relOf = true;
         }
@@ -2264,7 +2264,7 @@ export default {
 
       this.timer1 = setInterval(() => {
         if (this.pageOT >= this.pageAll + 7) {
-          this.pageOT = 1;
+          this.pageOT = 2;
 
           this.showFenZu.title =
             this.zhiliangmuNeirong[0] !== undefined
@@ -2464,7 +2464,7 @@ export default {
 
       this.timer1 = setInterval(() => {
         if (this.pageOT >= this.pageAll + 7) {
-          this.pageOT = 1;
+          this.pageOT = 2;
 
           this.showFenZu.title =
             this.zhiliangmuNeirong[0] !== undefined