src/views/statisticalCharts/qualificationRateStatistics/index.vue
@@ -2,7 +2,7 @@
  <div class="app-container">
    <el-row>
      <el-col :span="4">
        <el-radio-group v-model="dateType" @change="changeDate">
        <el-radio-group v-model="dateType" @change="changeDateType">
          <el-radio-button label="1">本周</el-radio-button>
          <el-radio-button label="2">本月</el-radio-button>
          <el-radio-button label="3">今年</el-radio-button>
@@ -11,18 +11,9 @@
      <el-col :span="20">
        <el-form ref="entity" size="small" :inline="true">
          <el-form-item style="width: 20%;">
            <el-date-picker
              v-model="datePicker"
              end-placeholder="结束日期"
              format="yyyy-MM-dd"
              placeholder="选择日期"
              range-separator="至"
              size="small"
              start-placeholder="开始日期"
              type="daterange"
              style="width: 100%;"
              value-format="yyyy-MM-dd"
              @change="changeDatePicker">
            <el-date-picker v-model="datePicker" end-placeholder="结束日期" format="yyyy-MM-dd" placeholder="选择日期"
              range-separator="至" size="small" start-placeholder="开始日期" type="daterange" style="width: 100%;"
              value-format="yyyy-MM-dd" @change="changeDatePicker">
            </el-date-picker>
          </el-form-item>
          <el-form-item label="样品名称" prop="sampleName">
@@ -32,65 +23,65 @@
            <el-input v-model="modelName" clearable placeholder="请输入型号" size="small" @change="changeDate"></el-input>
          </el-form-item>
          <el-form-item label="供应商名称" prop="supplierName">
            <el-input v-model="supplierName" clearable placeholder="请输入供应商名称" size="small" @change="changeDate"></el-input>
            <el-input v-model="supplierName" clearable placeholder="请输入供应商名称" size="small"
              @change="changeDate"></el-input>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>
    <el-row :gutter="20">
      <el-col :span="8">
        <div class="pie-card">
          <div class="title">原材料合格率</div>
          <span class="data">{{passRate}}</span>
          <Echarts ref="chart"
                   :legend="pieLegend"
                   :series="materialPieSeries"
                   :tooltip="pieTooltip"
                   style="height: 34vh;"></Echarts>
      <el-col :span="6">
        <div class="pie-card" :class="{ active: currentMaterialProp === '00Raw' }" @click="updateTitle('原材料')">
          <div class="title"><span style="color: #005BAC;font-weight: bold;">原材料</span>合格率</div>
          <Echarts ref="chart" :legend="pieLegend" :series="rawPieSeries" :tooltip="pieTooltip" style="height: 36vh;">
          </Echarts>
        </div>
      </el-col>
      <el-col :span="8">
        <div class="pie-card">
          <div class="title"><span style="color: #F56C6C">本月</span>检验类型数量</div>
          <Echarts ref="chart"
                   :chartStyle="chartStyle2"
                   :legend="pieLegend"
                   :series="materialPieSeries1"
                   :tooltip="pieTooltip"
                   style="height: 34vh;"></Echarts>
      <el-col :span="6">
        <div class="pie-card" :class="{ active: currentMaterialProp === '01Cu' }" @click="updateTitle('铜')">
          <div class="title"><span style="color: #005BAC;font-weight: bold;">铜</span>合格率</div>
          <Echarts ref="chart" :legend="pieLegend" :series="cuPieSeries" :tooltip="pieTooltip" style="height: 36vh;">
          </Echarts>
        </div>
      </el-col>
      <el-col :span="8">
        <div class="pie-card">
          <div class="title">原材料<span style="color: #F56C6C">本月</span>与<span style="color: #F56C6C">上月</span>合格率对比</div>
          <Echarts ref="chart"
                   :barColors="barColors2"
                   :chartStyle="chartStyle"
                   :grid="grid"
                   :legend="barLegend"
                   :series="barSeries"
                   :tooltip="tooltip"
                   :xAxis="xAxis1"
                   :yAxis="yAxis1"
                   style="height: 34vh;"></Echarts>
      <el-col :span="6">
        <div class="pie-card" :class="{ active: currentMaterialProp === '02Al' }" @click="updateTitle('铝')">
          <div class="title"><span style="color: #005BAC;font-weight: bold;">铝</span>合格率</div>
          <Echarts ref="chart" :legend="pieLegend" :series="alPieSeries" :tooltip="pieTooltip" style="height: 36vh;">
          </Echarts>
        </div>
      </el-col>
      <el-col :span="6">
        <div class="pie-card" :class="{ active: currentMaterialProp === '04Dlan' }" @click="updateTitle('电缆')">
          <div class="title"><span style="color: #005BAC;font-weight: bold;">电缆</span>合格率</div>
          <Echarts ref="chart" :legend="pieLegend" :series="dlanPieSeries" :tooltip="pieTooltip" style="height: 36vh;">
          </Echarts>
        </div>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="24">
    <el-row :gutter="20">
      <el-col :span="12">
        <div class="inspection-card">
          <div class="title">合格率</div>
          <Echarts ref="chart"
                   :barColors="barColors"
                   :grid="grid"
                   :legend="legend"
                   :lineColors="lineColors"
                   :options="echartsOptions"
                   :series="echartsSeries"
                   :tooltip="tooltip"
                   :xAxis="xAxis"
                   :yAxis="yAxis"
                   style="height: 40vh;"></Echarts>
          <div class="title" style="display:flex;align-items:center;justify-content:space-between;">
            <div>
              <span style="color: #005BAC;font-weight: bold;">{{ inspectionTitle }}</span>合格率趋势
            </div>
            <el-button type="text" icon="el-icon-download" @click="downloadBarChart">
              下载
            </el-button>
          </div>
          <Echarts ref="barChart" :barColors="barColors" :grid="grid" :legend="legend" :lineColors="lineColors"
            :options="echartsOptions" :series="echartsSeries" :tooltip="tooltip" :xAxis="xAxis" :yAxis="yAxis"
            style="height: 40vh;">
          </Echarts>
        </div>
      </el-col>
      <el-col :span="12">
        <div class="inspection-card">
          <div class="title"><span style="color: #005BAC;font-weight: bold;">{{ inspectionTitle }}</span>明细数据</div>
          <lims-table :tableData="tableData" :column="tableColumn" :tableLoading="tableLoading"
            :height="'calc(40vh - 40px)'"></lims-table>
        </div>
      </el-col>
    </el-row>
@@ -99,17 +90,19 @@
<script>
import Echarts from "@/components/echarts/echarts.vue";
import limsTable from "@/components/Table/lims-table.vue";
import {
  getOrderTypeCookie,
  getRawPassRateByBarChart,
  getRawPassRateByCake,
  getRawUpMonth
  getRawUpMonth,
  getMaterialPropTable
} from "@/api/statisticalCharts/dataAnalysis";
export default {
  name: "QualificationRateStatistics",
  // import 引入的组件需要注入到对象中才能使用
  components: {Echarts},
  components: { Echarts, limsTable },
  data() {
    // 这里存放数据
    return {
@@ -120,10 +113,17 @@
      sampleName: '',
      modelName: '',
      supplierName: '',
      inspectionTitle: '原材料',
      currentMaterialProp: '00Raw',
      echartsOptions: {
        title: {
          text: '示例图表',
          left: 'center'
          text: '',
          left: 'center',
          top: 10,
          textStyle: {
            fontSize: 14,
            fontWeight: 'bold'
          }
        }
      },
      xAxis: [
@@ -153,43 +153,46 @@
      ],
      echartsSeries: [
        {
          name: '总数',
          name: '合格',
          type: 'bar',
          data: [],
          label: {
            show: true,
            position: 'top'
          },
            position: 'inside'
          }
        },
        {
          name: '不合格',
          type: 'bar',
          data: [],
          label: {
            show: true,
            position: 'inside'
          }
        },
        {
          name: '合格率',
          type: 'line',
          smooth: true,
          tooltip: {
            valueFormatter: function (value) {
              return value + ' %';
            }
          },
          yAxisIndex: 1,
          data: [],
          label: {
            show: true,
            position: 'top',
            formatter: function (value) {
              return value.value + ' %';
            },
            distance: 14
          },
          yAxisIndex: 1,
          data: []
        },
            formatter: (v) => v.value + '%'
          }
        }
      ],
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        bottom: '15%',
        containLabel: true
      },
      legend: {
        data: ['总数','合格率']
        data: ['合格', '不合格', '合格率'],
        orient: 'horizontal',
        bottom: 0,
        itemGap: 20
      },
      tooltip: {
        trigger: 'axis',
@@ -197,26 +200,57 @@
          type: 'shadow'
        }
      },
      lineColors: ['#409EFF'],
      barColors: ['#E6A23C'],
      barColors2: ['#adde8b'],
      lineColors: ['#91A0FC'],
      barColors: ['#13ce66', '#F56C6C'], // 合格绿 / 不合格红
      barColors2: ['#A4EEDA'],
      pieTooltip: {
        trigger: 'item'
      },
      pieLegend: {
        orient: 'vertical',
        right: 20,
        top: 'middle',
        orient: 'horizontal',
        bottom: 0,
      },
      materialPieSeries: [
      rawPieSeries: [
        {
          name: 'Access From',
          type: 'pie',
          radius: ['40%', '70%'],
          right: '22%',
          radius: '70%',
          center: ['50%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 5,
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            alignTo: 'edge',
            formatter: '{name|{b}}\n{time|{c}}',
            edgeDistance: 10,
            lineHeight: 15,
            rich: {
              time: {
                fontSize: 10,
                color: '#999'
              }
            }
          },
          labelLine: {
            length: 20,
            length2: 40
          },
          data: [
            { value: 0, name: '不合格数量', itemStyle: { color: '#F56C6C' } },
            { value: 0, name: '合格数量', itemStyle: { color: '#67C23A' } }
          ]
        }
      ],
      cuPieSeries: [
        {
          name: 'Access From',
          type: 'pie',
          radius: '70%',
          center: ['50%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderColor: '#fff',
            borderWidth: 2
          },
@@ -233,12 +267,78 @@
            },
          },
          labelLine: {
            length: 30,
            length: 20,
            length2: 40,
          },
          data: [
            { value: 0, name: '不合格数量' },
            { value: 0, name: '合格数量' },
            { value: 0, name: '不合格数量', itemStyle: { color: '#F56C6C' } },
            { value: 0, name: '合格数量', itemStyle: { color: '#67C23A' } },
          ]
        }
      ],
      alPieSeries: [
        {
          name: 'Access From',
          type: 'pie',
          radius: '70%',
          center: ['50%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            alignTo: 'edge',
            formatter: '{name|{b}}\n{time|{c}}',
            edgeDistance: 10,
            lineHeight: 15,
            rich: {
              time: {
                fontSize: 10,
                color: '#999'
              }
            },
          },
          labelLine: {
            length: 20,
            length2: 40,
          },
          data: [
            { value: 0, name: '不合格数量', itemStyle: { color: '#F56C6C' } },
            { value: 0, name: '合格数量', itemStyle: { color: '#67C23A' } },
          ]
        }
      ],
      dlanPieSeries: [
        {
          name: 'Access From',
          type: 'pie',
          radius: '70%',
          center: ['50%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            alignTo: 'edge',
            formatter: '{name|{b}}\n{time|{c}}',
            edgeDistance: 10,
            lineHeight: 15,
            rich: {
              time: {
                fontSize: 10,
                color: '#999'
              }
            },
          },
          labelLine: {
            length: 20,
            length2: 40,
          },
          data: [
            { value: 0, name: '不合格数量', itemStyle: { color: '#F56C6C' } },
            { value: 0, name: '合格数量', itemStyle: { color: '#67C23A' } },
          ]
        }
      ],
@@ -250,7 +350,6 @@
          right: '22%',
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 5,
            borderColor: '#fff',
            borderWidth: 2
          },
@@ -319,19 +418,58 @@
        },
      ],
      tableData: [],
      passRate: '',
      tableLoading: false,
      tableColumn: [
        { label: '批号', prop: 'updateBatchNo', minWidth: '120px' },
        { label: '抵达成品数量', prop: 'qtyArrived', minWidth: '100px' },
        { label: '零件描述', prop: 'partDesc', minWidth: '200px' },
        {
          dataType: 'tag',
          label: '检验状态',
          prop: 'inspectStatus',
          minWidth: '100px',
          formatData: (params) => {
            if (params == 0) return '检验中'
            if (params == 1) return '合格'
            if (params == 2) return '不合格'
            if (params == 3) return '未下单'
            if (params == 4) return '让步放行'
            return null
          },
          formatType: (params) => {
            if (params == 1 || params == 4) return 'success'
            if (params == 0 || params == 2) return 'danger'
            if (params == 3) return 'warning'
            return null
          }
        },
        { label: '下发时间', prop: 'sendTime', minWidth: '150px' }
      ],
      rawPassRate: '',
      cuPassRate: '',
      alPassRate: '',
      dlanPassRate: '',
      sum: '',
    }
  },
  mounted() {
    this.getBar()
    this.getRawPass()
    this.getOrderType()
    this.getPassRateCom()
    this.setBarChartTitle();
    this.getBar();
    this.getRawPass();
    this.getOrderType();
    this.getPassRateCom();
    this.getTableData();
  },
  // 方法集合
  methods: {
    // 获取合格率图表数据
    setBarChartTitle() {
      this.echartsOptions.title.text = `${this.inspectionTitle}合格率趋势`;
    },
    getBar() {
      const params = {
        dateType: this.dateType,
@@ -340,43 +478,64 @@
        sampleName: this.sampleName,
        modelName: this.modelName,
        supplierName: this.supplierName,
      }
        materialProp: this.currentMaterialProp,
      };
      getRawPassRateByBarChart(params).then((res) => {
        let lineData = []
        let barData = []
        let xAxis = []
        let qualifiedData = [];
        let unQualifiedData = [];
        let lineData = [];
        let xAxis = [];
        res.data.forEach(item => {
          barData.push(item.sum)
          lineData.push(item.passRate)
          xAxis.push(item.searchTime)
        })
        this.echartsSeries[0].data = barData
        this.echartsSeries[1].data = lineData
        this.yAxis[0].max = Math.ceil(Math.max.apply(null, barData) / 50) * 50
        this.yAxis[0].interval = this.yAxis[0].max / 5
        this.xAxis[0].data = xAxis
      })
          qualifiedData.push(item.qualified || 0);
          unQualifiedData.push(item.unQualified || 0);
          lineData.push(item.passRate || 0);
          xAxis.push(item.searchTime);
        });
        this.echartsSeries[0].data = qualifiedData;
        this.echartsSeries[1].data = unQualifiedData;
        this.echartsSeries[2].data = lineData;
        this.xAxis[0].data = xAxis;
      });
    },
    // 获取原材料合格率图表数据
    // 获取物料属性合格率图表数据
    getRawPass() {
      const params = {
        dateType: this.dateType,
        beginDate: this.beginDate,
        endDate: this.endDate,
        sampleName: this.sampleName,
        modelName: this.modelName,
        supplierName: this.supplierName,
      }
      getRawPassRateByCake(params).then((res) => {
        this.materialPieSeries[0].data[0].value = res.data.unQualified
        this.materialPieSeries[0].data[1].value = res.data.qualified
        this.passRate = res.data.passRate + '%'
      })
      const materials = [
        { type: '00Raw', series: 'rawPieSeries', rate: 'rawPassRate' },
        { type: '01Cu', series: 'cuPieSeries', rate: 'cuPassRate' },
        { type: '02Al', series: 'alPieSeries', rate: 'alPassRate' },
        { type: '04Dlan', series: 'dlanPieSeries', rate: 'dlanPassRate' }
      ];
      materials.forEach(item => {
        const params = {
          dateType: this.dateType,
          beginDate: this.beginDate,
          endDate: this.endDate,
          sampleName: this.sampleName,
          modelName: this.modelName,
          supplierName: this.supplierName,
          materialProp: item.type
        }
        getRawPassRateByCake(params).then((res) => {
          if (res.data) {
            this[item.series][0].data[0].value = res.data.unQualified || 0
            this[item.series][0].data[1].value = res.data.qualified || 0
            this[item.rate] = res.data.passRate != null ? res.data.passRate + '%' : ''
          } else {
            this[item.series][0].data[0].value = 0
            this[item.series][0].data[1].value = 0
            this[item.rate] = ''
          }
        })
      });
    },
    // 获取本月检验类型数量
    getOrderType() {
      getOrderTypeCookie().then((res) => {
        if (res.code === 201) return
        this.materialPieSeries1[0].data[0].value = res.data.customer // 委托
        this.materialPieSeries1[0].data[1].value = res.data.enter // 进厂
        this.materialPieSeries1[0].data[2].value = res.data.quarterly // 季度
@@ -396,13 +555,24 @@
        this.barSeries[0].data = barData
      })
    },
    changeDate () {
    changeDate() {
      this.getBar()
      this.getRawPass()
      this.getTableData()
      // this.getOrderType()
      // this.getPassRateCom()
    },
    changeDatePicker (val) {
    changeDateType() {
      this.datePicker = []
      this.beginDate = ''
      this.endDate = ''
      this.getBar()
      this.getRawPass()
      this.getTableData()
    },
    changeDatePicker(val) {
      if (val) {
        this.beginDate = val[0] + ' 00:00:00'
        this.endDate = val[1] + ' 23:59:59'
@@ -412,8 +582,62 @@
      }
      this.getBar()
      this.getRawPass()
      // this.getOrderType()
      // this.getPassRateCom()
      this.getTableData()
    },
    updateTitle(title) {
      this.inspectionTitle = title;
      const typeMap = {
        '原材料': '00Raw',
        '铜': '01Cu',
        '铝': '02Al',
        '电缆': '04Dlan',
      };
      this.currentMaterialProp = typeMap[title] || '00Raw';
      this.setBarChartTitle();
      this.getBar();
      this.getTableData();
    },
    getTableData() {
      this.tableLoading = true;
      const params = {
        dateType: this.dateType,
        beginDate: this.beginDate,
        endDate: this.endDate,
        sampleName: this.sampleName,
        modelName: this.modelName,
        supplierName: this.supplierName,
        materialProp: this.currentMaterialProp,
      };
      getMaterialPropTable(params).then((res) => {
        if (Array.isArray(res.data)) {
          this.tableData = res.data;
        } else if (res.data && res.data.records) {
          this.tableData = res.data.records;
        } else {
          this.tableData = [];
        }
        this.tableLoading = false;
      }).catch(() => {
        this.tableLoading = false;
      });
    },
    //  下载柱状图图片
    downloadBarChart() {
      if (!this.$refs.barChart) {
        this.$message.warning('图表尚未加载完成');
        return;
      }
      const title = `${this.inspectionTitle}_合格率趋势`;
      this.$refs.barChart.downloadImage(title);
    },
  },
}
@@ -423,24 +647,38 @@
.title {
  padding: 10px 0 0 20px;
}
.table {
  padding: 0 10px 10px;
}
.pie-card {
  width: 100%;
  background: #FFFFFF;
  margin-top: 10px;
  position: relative;
  cursor: pointer;
  border-radius: 8px;
  transition:
    transform 0.25s ease,
    box-shadow 0.25s ease;
}
.pie-card.active {
  transform: translateY(-3px) scale(1.03);
  box-shadow: 0 5px 10px rgba(0, 91, 172, 0.25);
}
.data {
  position: absolute;
  font-size: 20px;
  transform: translate(-50%);
  left: 40%;
  top: 42%;
  transform: translate(-50%, -50%);
  left: 50%;
  top: 50%;
  z-index: 1;
}
.inspection-card{
.inspection-card {
  width: 100%;
  background: #FFFFFF;
  margin-top: 10px;