value
2023-09-05 9b26870265cbbc75bcd32529e46b229a49ec30a0
src/views/experiment/passRateStatistics/index.vue
@@ -1,13 +1,491 @@
<template>
  <div>合格率统计</div>
  <div class="content-main">
    <div class="top-bar">
      <el-form ref="form" :inline="true" :rules="rules" :model="searchData" label-position="top">
        <el-form-item label="检测日期:" class="sermargin" prop="date">
          <el-date-picker v-model="searchData.date" type="daterange" range-separator="至" start-placeholder="开始日期"
            end-placeholder="结束日期">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="检验类型:" class="sermargin" prop="type">
          <el-select v-model="searchData.type" placeholder="全部">
            <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="供应商:">
          <el-select v-model="searchData.supplier" placeholder="全部">
            <el-option v-for="item in supplier" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item style="margin-left: 40px;" label="样品:">
          <el-select v-model="searchData.code" filterable placeholder="请选择">
            <el-option v-for="item in sampleOptions" :key="item.value" :label="item.label" :value="item.value">
              <span style="float: left">{{ item.label }}</span>
              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.value }}</span>
            </el-option>
          </el-select>
        </el-form-item>
        <div class="rightBtn">
          <el-form-item>
            <el-button type="primary" @click="clear" plain size="mini">清空</el-button>
            <el-button type="primary" @click="search" size="mini">查询</el-button>
          </el-form-item>
        </div>
      </el-form>
    </div>
    <div class="top-bar-copy"></div>
    <div class="chart-content">
      <div class="qualified-wrapper">
        <div style="margin-left: 20px;padding:20px 0px;font-size:18px">检测样品合格率统计</div>
        <div :hidden="testSample" class="qualified" ref="qualified"></div>
        <div :hidden="!testSample" style="height: 100%;text-align: center; color: #999696df; margin-top: 100px;">暂无数据
        </div>
      </div>
      <div class="unqualified">
        <div class="firstBox-wrapper">
          <div style="margin-left: 20px;padding:20px 0px;font-size:18px">供应商合格率统计</div>
          <div>
            <div :hidden="supplierData" class="firstBox" ref="unqualified_provider"></div>
            <div :hidden="!supplierData" style="height: 100%;text-align: center; color: #999696df; margin-top: 100px;">
              暂无数据</div>
          </div>
        </div>
        <div class="secondBox-wrapper">
          <div class="secondBox_header">
            <div style="font-size:18px">不合格项目统计</div>
            <el-radio-group v-model="type">
              <el-radio-button v-for="item in radiooptions" :key="item.value" :label="item.value">{{ item.label
              }}</el-radio-button>
            </el-radio-group>
          </div>
          <div style="width: 100%;height: 100%;">
            <div :hidden="projectData" class="secondBox" ref="unqualified_project"></div>
            <div :hidden="!projectData" style="height: 100%;text-align: center; color: #999696df; margin-top: 100px;">暂无数据
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="bottom">
      <el-button type="primary" size="mini">数据导出</el-button>
      <!-- <el-button type="primary" size="mini" @click="testWork">测试</el-button> -->
    </div>
  </div>
</template>
<script>
export default {
// 添加滚动监听事件
window.addEventListener('scroll', function () {
  var topBar = document.querySelector('.top-bar');
  var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
  if (scrollTop > 0) {
    topBar.classList.add('fixed');
  } else {
    topBar.classList.remove('fixed');
  }
})
import * as echarts from 'echarts'
import { getSupplierList, getTestSampleStatistics, getSupplierNoPassStatistics, getNoPassProjectStatistics, getSampleOptions } from '@/api/experiment/passRateStatistics';
import { dateFormat } from '../../../utils/dateUtil'
import MyWorker from 'comlink-loader!../../../worker/test';
export default {
  data() {
    return {
      supplier: [],
      sampleOptions: [],
      searchData: {
        date: [],
        type: null,
        supplier: null,
        sample: null,
        code: null
      },
      options: [
        {
          label: '全部',
          value: 3
        },
        {
          label: '原材料',
          value: 0
        },
        {
          label: '成品',
          value: 1
        },
        {
          label: '委托品',
          value: 2
        }
      ],
      radiooptions: [
        {
          label: '环形饼图',
          value: 0
        },
        {
          label: '帕累托图',
          value: 1
        }
      ],
      type: 0,
      rules: {
        // date: [{ required: true, message: '请输入账号', trigger: 'blur' }],
        // type: [{ required: true, message: '请输入名字', trigger: 'blur' }]
      },
      supplierNoPassStatistics: null,
      supplierData: false,
      projectStatistics: null,
      projectData: false,
      testSampleStatistics: null,
      testSample: false,
      m1: null,
      m2: null,
      m3: null
    }
  },
  async mounted() {
    await this.start()
    this.tableStart()
  },
  methods: {
    testWork(){
      const inst = new MyWorker();
      inst.test()
      for (let index = 0; index < 100; index++) {
        console.log("主线程"+index);
      }
    },
    clear(){
       this.searchData.date=[]
       this.searchData.type=null
       this.searchData.supplier=null
       this.searchData.code=null
    },
    async search() {
      this.testSampleStatistics = null
      this.supplierNoPassStatistics = null
      this.projectStatistics = null
      this.supplier = []
      this.sampleOptions = []
      await this.start()
      this.tableStart()
    },
    dateHandle() {
      let data = JSON.parse(JSON.stringify(this.searchData))
      if (this.searchData.date.length != 0 && this.searchData.date != []) {
        data.beginDate = dateFormat(this.searchData.date[0])
        data.endDate = dateFormat(this.searchData.date[1])
      }
      if (data.supplier == '全部') {
        data.supplier = null
      }
      if (data.type === 3) {
        data.type = null
      }
      if (this.sampleOptions.length > 0 && this.sampleOptions != []) {
        let labelSam = this.sampleOptions.filter(item => {
          return item.value == data.code
        })[0]
        data.sample = labelSam.label
      }
      if (data.code == '全部') {
        data.code = null
        data.sample = null
      }
      data.date = null
      return data
    },
    async getSupplierList() {
      let res = await getSupplierList()
      this.supplier.push({ label: '全部', value: '全部' })
      res.data.forEach(item => {
        this.supplier.push({ label: item.supplier, value: item.supplier })
      })
    },
    async getTestSampleStatistics() {
      let param = this.dateHandle()
      let res = await getTestSampleStatistics(param)
      this.testSample = !res.data.noData
      this.testSampleStatistics = res.data
    },
    async getSupplierNoPassStatistics() {
      let param = this.dateHandle()
      let res = await getSupplierNoPassStatistics(param)
      this.supplierData = !res.data.noData
      this.supplierNoPassStatistics = res.data
    },
    async getNoPassProjectStatistics() {
      let param = this.dateHandle()
      let res = await getNoPassProjectStatistics(param)
      this.projectData = !res.data.noData
      this.projectStatistics = res.data
    },
    async start() {
      await this.getTestSampleStatistics()
      await this.getSupplierNoPassStatistics()
      await this.getNoPassProjectStatistics()
      await this.getSupplierList()
      await this.getSampleOptions()
    },
    async getSampleOptions() {
      let res = await getSampleOptions()
      this.sampleOptions.push({
        label: '全部',
        value: '全部'
      })
      res.data.forEach(item => {
        let data = {
          label: item.name,
          value: item.code
        }
        this.sampleOptions.push(data)
      })
    },
    tableStart() {
      const chartDom_qualified = this.$refs.qualified;
      const chartDom_unqualified_provider = this.$refs.unqualified_provider;
      const chartDom_unqualified_project = this.$refs.unqualified_project;
      const myChart1 = echarts.init(chartDom_qualified);
      const myChart2 = echarts.init(chartDom_unqualified_provider, null, {
        height: 300
      });
      const myChart3 = echarts.init(chartDom_unqualified_project, null, {
        height: 268
      });
      window.addEventListener("resize",function(){
        myChart1.resize()
        myChart2.resize()
        myChart3.resize()
      })
      this.m1 = myChart1
      this.m2 = myChart2
      this.m3 = myChart3
      /**
       * 检测合格率统计
       */
      const option_qualified = {
        tooltip: {
          trigger: 'axis',
          axisPointer: { // 坐标轴指示器,坐标轴触发有效
            type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
          }
        },
        legend: {
          data: ['合格', '不合格']
        },
        xAxis: [
          {
            type: 'category',
            data: this.testSampleStatistics.xAxis
          }
        ],
        yAxis: [
          {
            type: 'value',
            axisLabel: {
              formatter: '{value}'
            }
          }
        ],
        series: this.testSampleStatistics.series
      };
      /**
       * 供应商
       */
      const option_unqualified1 = {
        tooltip: {
          trigger: 'axis',
          axisPointer: { // 坐标轴指示器,坐标轴触发有效
            type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
          },
          formatter: function (params) {
            let tooltip = params[0].name + '<br/>';
            params.forEach(function (item) {
              tooltip += item.marker + ' ' + item.seriesName + ': ' + item.value.toFixed(2) + '%<br/>'; // 将数据保留两位小数并转为百分比形式
            });
            return tooltip;
          }
        },
        legend: {
          data: ['合格数量', '不合格数量']
        },
        xAxis: {
          data: this.supplierNoPassStatistics.xAxis
        },
        yAxis: [
          {
            type: 'value',
            axisLabel: {
              formatter: '{value}%'
            }
          }
        ],
        series: this.supplierNoPassStatistics.series
      };
      /**
       * 不合格项目
       */
      const option_unqualified2 = {
        legend: {
          orient: 'vertical',
          x: 'left',
          data: this.projectStatistics.legend
        },
        title: {
          text: '',
          left: 'center',
          top: 'center'
        },
        series: [
          {
            type: 'pie',
            data: this.projectStatistics.series,
            radius: ['40%', '70%'],
            label: {
              show: true,
              formatter: '{b}: {c}%'
            },
          }
        ]
      }
      myChart1.setOption(option_qualified);
      myChart2.setOption(option_unqualified1);
      if (this.type === 0) {
        myChart3.setOption(option_unqualified2);
      }
      if (this.type === 1) {
        myChart3.setOption(option_unqualified2);
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.content-main {
  height: 100%;
  width: 100%;
  overflow: auto;
  .top-bar {
    position: absolute;
    width: 99%;
    top: 0;
    left: 0;
    z-index: 999;
    margin-top: 5px;
    margin-left: 9.5px;
    background-color: #fff;
    display: flex;
    justify-content: space-between;
    padding: 5px 24px 0px 24px;
    transition: position 0.3s ease;
    .el-form {
      width: 100%;
      .chooseMaterialBtn {
        background-color: #fff;
        border-color: rgba(192, 196, 204, 0.5);
        color: gray;
        width: 220px;
      }
    }
    .sermargin {
      margin-right: 60px;
    }
    .rightBtn {
      display: flex;
      justify-content: end;
      margin-right: 20px;
      margin-top: -40px;
      margin-bottom: -10px;
    }
  }
  .top-bar.fixed {
    position: fixed;
    top: 0.45rem;
    left: 0.52rem;
    width: 93.8%;
  }
  .top-bar-copy {
    width: 100%;
    height: 12vh;
  }
  .chart-content {
    margin: 0px -15px;
    margin-bottom: 60px;
    .qualified-wrapper {
      // margin-top: 14vh;
      background-color: #fff;
      width: 100%;
      height: 50vh;
    }
    .qualified {
      width: 100%;
      height: 400px;
    }
    .unqualified {
      margin-top: 10px;
      height: 50vh;
      display: flex;
      justify-content: space-between;
      .firstBox-wrapper {
        background-color: #fff;
        width: 49%;
        .firstBox {
          width: 100%;
          height: 40vh;
        }
      }
      .secondBox-wrapper {
        background-color: #fff;
        width: 49%;
        .secondBox_header {
          display: flex;
          justify-content: space-between;
          margin: 20px 20px;
        }
        .secondBox {
          width: 100%;
          height: 40vh;
        }
      }
    }
  }
  .bottom {
    position: fixed;
    width: 95%;
    bottom: 0rem !important;
    left: 0.6rem !important;
    margin: 0px -15px;
    padding: 20px 40px;
    z-index: 999;
    display: flex;
    justify-content: end;
    background-color: #fff;
  }
}
</style>