zouyu
2026-05-25 edc6b742457bcdfcfbd49ff41a625f956a733459
src/views/statisticalCharts/qualificationRateStatistics/index.vue
@@ -1,19 +1,12 @@
<template>
  <div class="app-container">
    <el-row>
      <el-col :span="4">
        <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>
        </el-radio-group>
      </el-col>
      <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="选择日期"
            <el-date-picker :picker-options="pickerOptions" 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">
              value-format="yyyy-MM-dd" clearable @change="changeDatePicker">
            </el-date-picker>
          </el-form-item>
          <el-form-item label="样品名称" prop="sampleName">
@@ -25,6 +18,13 @@
          <el-form-item label="供应商名称" prop="supplierName">
            <el-input v-model="supplierName" clearable placeholder="请输入供应商名称" size="small"
              @change="changeDate"></el-input>
          </el-form-item>
          <el-form-item label="IFS域" prop="contract">
            <el-select v-model="contract" clearable placeholder="请选择IFS域" size="small"
                        @change="changeDate">
              <el-option label="ZTNS" value="ZTNS"/>
              <el-option label="KJNS" value="KJNS"/>
            </el-select>
          </el-form-item>
        </el-form>
      </el-col>
@@ -81,8 +81,17 @@
              下载
            </el-button>
          </div>
          <lims-table :tableData="tableData" :column="tableColumn" :tableLoading="tableLoading"
            :height="'calc(40vh - 40px)'" :show-summary="true" :summary-method="getSummaries"></lims-table>
          <el-table ref="passRateTable" :height="'calc(40vh - 40px)'" :data="tableData" border v-loading="tableLoading" show-summary :summary-method="getSummaries">
            <el-table-column label="序号" type="index" align="center" width="80"></el-table-column>
            <el-table-column label="供应商名称" prop="supplierName" show-overflow-tooltip align="center" min-width="140"></el-table-column>
            <el-table-column label="到货批次" prop="totalBatch" show-overflow-tooltip align="center" min-width="140"></el-table-column>
            <el-table-column label="不合格批次" prop="unqualifiedBatch" show-overflow-tooltip align="center" min-width="140"></el-table-column>
            <el-table-column label="合格率(%)" prop="passRate" show-overflow-tooltip align="center" min-width="140">
              <template slot-scope="scope">
                {{ scope.row.passRate != null ? scope.row.passRate + '%' : '0%'}}
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-col>
    </el-row>
@@ -108,11 +117,39 @@
  data() {
    // 这里存放数据
    return {
      pickerOptions: {
        shortcuts: [{
          text: '最近一周',
          onClick(picker) {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
            picker.$emit('pick', [start, end]);
          }
        }, {
          text: '最近一个月',
          onClick(picker) {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
            picker.$emit('pick', [start, end]);
          }
        }, {
          text: '最近一年',
          onClick(picker) {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 365);
            picker.$emit('pick', [start, end]);
          }
        }]
      },
      dateType: '1',
      datePicker: [],
      beginDate: '',
      endDate: '',
      sampleName: '',
      contract: '',
      modelName: '',
      supplierName: '',
      inspectionTitle: '原材料',
@@ -180,7 +217,7 @@
          data: [],
          label: {
            show: true,
            formatter: (v) => v.value + '%'
            formatter: (v) =>  v.value + '%'
          }
        }
      ],
@@ -203,7 +240,7 @@
        }
      },
      lineColors: ['#91A0FC'],
      barColors: ['#13ce66', '#F56C6C'], // 合格绿 / 不合格红
      barColors: ['#5b9bd5', '#ed7d31'], // 合格绿 / 不合格红
      barColors2: ['#A4EEDA'],
      pieTooltip: {
        trigger: 'item'
@@ -214,7 +251,7 @@
      },
      rawPieSeries: [
        {
          name: 'Access From',
          name: '',
          type: 'pie',
          radius: '70%',
          center: ['50%', '50%'],
@@ -224,7 +261,7 @@
            borderWidth: 2
          },
          label: {
            alignTo: 'edge',
            alignTo: 'labelLine',
            formatter: '{name|{b}}\n{time|{c}}',
            edgeDistance: 10,
            lineHeight: 15,
@@ -240,14 +277,14 @@
            length2: 40
          },
          data: [
            { value: 0, name: '不合格数量', itemStyle: { color: '#F56C6C' } },
            { value: 0, name: '合格数量', itemStyle: { color: '#67C23A' } }
            { value: 0, name: '不合格数量', itemStyle: {color: '#ed7d31'} },
            { value: 0, name: '合格数量', itemStyle: { color: '#5b9bd5' } }
          ]
        }
      ],
      conductorPieSeries: [
        {
          name: 'Access From',
          name: '',
          type: 'pie',
          radius: '70%',
          center: ['50%', '50%'],
@@ -257,7 +294,7 @@
            borderWidth: 2
          },
          label: {
            alignTo: 'edge',
            alignTo: 'labelLine',
            formatter: '{name|{b}}\n{time|{c}}',
            edgeDistance: 10,
            lineHeight: 15,
@@ -273,14 +310,14 @@
            length2: 40,
          },
          data: [
            { value: 0, name: '不合格数量', itemStyle: { color: '#F56C6C' } },
            { value: 0, name: '合格数量', itemStyle: { color: '#67C23A' } },
            { value: 0, name: '不合格数量', itemStyle: { color: '#ed7d31' } },
            { value: 0, name: '合格数量', itemStyle: { color: '#5b9bd5' } },
          ]
        }
      ],
      dlanPieSeries: [
        {
          name: 'Access From',
          name: '',
          type: 'pie',
          radius: '70%',
          center: ['50%', '50%'],
@@ -290,7 +327,7 @@
            borderWidth: 2
          },
          label: {
            alignTo: 'edge',
            alignTo: 'labelLine',
            formatter: '{name|{b}}\n{time|{c}}',
            edgeDistance: 10,
            lineHeight: 15,
@@ -306,8 +343,8 @@
            length2: 40,
          },
          data: [
            { value: 0, name: '不合格数量', itemStyle: { color: '#F56C6C' } },
            { value: 0, name: '合格数量', itemStyle: { color: '#67C23A' } },
            { value: 0, name: '不合格数量', itemStyle: { color: '#ed7d31' } },
            { value: 0, name: '合格数量', itemStyle: { color: '#5b9bd5' } },
          ]
        }
      ],
@@ -388,24 +425,12 @@
      ],
      tableData: [],
      tableLoading: false,
      tableColumn: [
        { label: '供应商名称', prop: 'supplierName', minWidth: '200px' },
        { label: '到货批次', prop: 'totalBatch', minWidth: '100px' },
        { label: '不合格批次', prop: 'unqualifiedBatch', minWidth: '100px' },
        {
          label: '合格率(%)',
          prop: 'passRate',
          minWidth: '100px',
          formatData: (val) => (val != null ? val + '%' : '0%')
        }
      ],
      rawPassRate: '',
      conductorPassRate: '',
      dlanPassRate: '',
      sum: '',
    }
  },
  mounted() {
    this.setBarChartTitle();
    this.getBar();
@@ -414,15 +439,34 @@
    this.getPassRateCom();
    this.getTableData();
  },
watch:{
  datePicker:{
    handler(newVal){
      //计算开始时间与结束时间的天数差
      if (newVal && newVal.length === 2) {
        const startDate = new Date(newVal[0]);
        const endDate = new Date(newVal[1]);
        const timeDiff = endDate - startDate;
        const dayDiff = timeDiff / (1000 * 3600 * 24);
        if (dayDiff <= 7) {
          this.dateType = '1';
        } else if (dayDiff > 7 && dayDiff <= 31) {
          this.dateType = '2';
        } else if (dayDiff > 31) {
          this.dateType = '3';
        }
      }else{
        this.dateType = '1';
      }
    },  immediate:true
  }
},
  // 方法集合
  methods: {
    // 获取合格率图表数据
    setBarChartTitle() {
      this.echartsOptions.title.text = `${this.inspectionTitle}合格率趋势`;
    },
    getBar() {
      const types = this.currentMaterialProp.split(',');
      const requests = types.map(t => {
@@ -433,6 +477,7 @@
          sampleName: this.sampleName,
          modelName: this.modelName,
          supplierName: this.supplierName,
          contract:this.contract,
          materialProp: t,
        };
        return getRawPassRateByBarChart(params);
@@ -454,7 +499,38 @@
          }
        });
        const sortedDates = Object.keys(dateMap).sort();
        const weekOrderMap = {
          "星期一": 0,
          "星期二": 1,
          "星期三": 2,
          "星期四": 3,
          "星期五": 4,
          "星期六": 5,
          "星期日": 6
        };
        const yearOrderMap = {
          "1月": 0,
          "2月": 1,
          "3月": 2,
          "4月": 3,
          "5月": 4,
          "6月": 5,
          "7月": 6,
          "8月": 7,
          "9月": 8,
          "10月": 9,
          "11月": 10,
          "12月": 11
        };
        const sortedDates = Object.keys(dateMap).sort((a, b) => {
          if(a.includes("星期") && b.includes("星期")) {
            return weekOrderMap[a] - weekOrderMap[b];
          } else if(a.includes("月") && b.includes("月")) {
            return yearOrderMap[a] - yearOrderMap[b];
          } else {
            return new Date(a) - new Date(b);
          }
        });
        let qualifiedData = [];
        let unQualifiedData = [];
        let lineData = [];
@@ -496,6 +572,7 @@
            sampleName: this.sampleName,
            modelName: this.modelName,
            supplierName: this.supplierName,
            contract:this.contract,
            materialProp: t
          };
          return getRawPassRateByCake(params);
@@ -604,6 +681,7 @@
          sampleName: this.sampleName,
          modelName: this.modelName,
          supplierName: this.supplierName,
          contract:this.contract,
          materialProp: t,
        };
        return getMaterialPropTable(params);
@@ -638,6 +716,9 @@
        // Sort by totalBatch descending
        tableData.sort((a, b) => b.totalBatch - a.totalBatch);
        this.tableData = tableData;
        this.$nextTick(()=>{
          this.$refs.passRateTable.doLayout()
        })
        this.tableLoading = false;
      }).catch(() => {
        this.tableLoading = false;