spring
2025-03-03 10f334d1b36f8dad1edcd3b489c9eb6b8773d444
Merge branch 'dev' of http://114.132.189.42:9002/r/lims-ruoyi-before into dev
已修改6个文件
已添加5个文件
1936 ■■■■■ 文件已修改
src/api/statisticalCharts/dataAnalysis.js 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/echarts/DataComparison.vue 507 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/echarts/echarts.vue 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Navbar.vue 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/materialOrder/copperOrder.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/materialOrder/customsInspection.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/productOrder/components/add.vue 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/statisticalCharts/itemInspectionAnalysis/index.vue 535 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/statisticalCharts/qualificationRateStatistics/index.vue 448 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/structural/capabilityAndLaboratory/capability/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/statisticalCharts/dataAnalysis.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
// ç»Ÿè®¡å›¾è¡¨
import request from "@/utils/request";
//合格率统计
export function getRawPassRateByBarChart(query) {
  return request({
    url: "/dataAnalysis/getRawPassRateByBarChart",
    method: "get",
    params: query,
  });
}
//原材料统计
export function getRawPassRateByCake(query) {
  return request({
    url: "/dataAnalysis/getRawPassRateByCake",
    method: "get",
    params: query,
  });
}
//本月检验类型数量
export function getOrderTypeCookie() {
  return request({
    url: "/dataAnalysis/getOrderTypeCookie",
    method: "get",
  });
}
//本月检验类型数量
export function getRawUpMonth() {
  return request({
    url: "/dataAnalysis/getRawUpMonth",
    method: "get",
  });
}
//查询原材料项检分析
export function getRawProductAnalysis(query) {
  return request({
    url: "/dataAnalysis/getRawProductAnalysis",
    method: "post",
    data: query,
  });
}
//查询原材料项检分析合格率
export function getRawProductAnalysisRawPass(query) {
  return request({
    url: "/dataAnalysis/getRawProductAnalysisRawPass",
    method: "post",
    data: query,
  });
}
//查询原材料项检分析列表
export function getRawProductAnalysisAllList(query) {
  return request({
    url: "/dataAnalysis/getRawProductAnalysisAllList",
    method: "post",
    data: query,
  });
}
//查询检验项
export function getRawItemNames(query) {
  return request({
    url: "/dataAnalysis/getRawItemNames",
    method: "get",
    params: query,
  });
}
//查询原材料项检和厂家数据对比
export function getRawSupplierCompare(query) {
  return request({
    url: "/dataAnalysis/getRawSupplierCompare",
    method: "post",
    data: query,
  });
}
src/components/echarts/DataComparison.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,507 @@
<template>
  <div>
    <div>
      <el-row class="title">
        <el-col :span="6" style="padding-left: 20px;text-align: left;">数据分析</el-col>
        <el-col :span="18" style="text-align: right;">
          <el-button size="medium" @click="$emit('goBack')">返回</el-button>
        </el-col>
      </el-row>
    </div>
    <div class="container">
      <div>
        <div style="padding: 0 0 10px 10px">填写厂家数据</div>
        <el-form ref="supplierForm" :model="supplierForm" :rules="rules" class="demo-ruleForm" label-width="40px">
          <el-row :gutter="20">
            <el-col :span="3">
              <el-form-item label="1:" prop="one">
                <el-input v-model="supplierForm.one" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="3">
              <el-form-item label="2:" prop="two">
                <el-input v-model="supplierForm.two" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="3">
              <el-form-item label="3:" prop="three">
                <el-input v-model="supplierForm.three" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="3">
              <el-form-item label="4:" prop="four">
                <el-input v-model="supplierForm.four" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="3">
              <el-form-item label="5:" prop="five">
                <el-input v-model="supplierForm.five" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item>
                <el-button size="small" type="primary" @click="submitForm()">数据分析</el-button>
                <el-button size="small" @click="resetForm()">重置</el-button>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
      <table :border='true' class="table">
        <tr>
          <th class="thTitle">          </th>
          <th class="thTitle">1</th>
          <th class="thTitle">2</th>
          <th class="thTitle">3</th>
          <th class="thTitle">4</th>
          <th class="thTitle">5</th>
          <th class="thTitle">平均值</th>
          <th class="thTitle">标准偏差</th>
          <th class="thTitle">相对偏差</th>
          <th class="thTitle">平均标准偏差</th>
        </tr>
        <tr>
          <td class="thBack">厂家检测数据</td>
          <td v-for="(item,index) in supplierData" :key="index" class="tdData">{{item}}</td>
        </tr>
        <tr>
          <td class="thBack">检测中心数据</td>
          <td v-for="(item,index) in localData" :key="index" class="tdData">{{item}}</td>
        </tr>
        <tr>
          <td class="thBack">绝对偏差</td>
          <td v-for="(item,index) in absoluteDeviation" :key="index" class="tdData">{{item}}</td>
        </tr>
        <tr>
          <td class="thBack">平均值</td>
          <td v-for="(item,index) in average" :key="index" class="tdData">{{item}}</td>
        </tr>
        <tr>
          <td class="thBack2">厂家</td>
        </tr>
        <tr>
          <td class="thBack">UCL</td>
          <td v-for="(item,index) in supplierULC" :key="index" class="tdData">{{item}}</td>
          <td v-for="(item,index) in empty" :key="'a' + index" class="tdData"></td>
        </tr>
        <tr>
          <td class="thBack">LCL</td>
          <td v-for="(item,index) in supplierLCL" :key="index" class="tdData">{{item}}</td>
          <td v-for="(item,index) in empty" :key="'b' + index" class="tdData"></td>
        </tr>
        <tr>
          <td class="thBack">平均值</td>
          <td v-for="(item,index) in supplierAverage" :key="index" class="tdData">{{item}}</td>
          <td v-for="(item,index) in empty" :key="'c' + index" class="tdData"></td>
        </tr>
        <tr>
          <td class="thBack">极差</td>
          <td v-for="(item,index) in supplierRange" :key="index" class="tdData">{{item}}</td>
          <td v-for="(item,index) in empty" :key="'d' + index" class="tdData"></td>
        </tr>
        <tr>
          <td class="thBack2">检测中心</td>
        </tr>
        <tr>
          <td class="thBack">UCL</td>
          <td v-for="(item,index) in localULC" :key="index" class="tdData">{{item}}</td>
          <td v-for="(item,index) in empty" :key="'e' + index" class="tdData"></td>
        </tr>
        <tr>
          <td class="thBack">LCL</td>
          <td v-for="(item,index) in localLCL" :key="index" class="tdData">{{item}}</td>
          <td v-for="(item,index) in empty" :key="'f' + index" class="tdData"></td>
        </tr>
        <tr>
          <td class="thBack">平均值</td>
          <td v-for="(item,index) in localAverage" :key="index" class="tdData">{{item}}</td>
          <td v-for="(item,index) in empty" :key="'g' + index" class="tdData"></td>
        </tr>
        <tr>
          <td class="thBack">极差</td>
          <td v-for="(item,index) in localRange" :key="index" class="tdData">{{item}}</td>
          <td v-for="(item,index) in empty" :key="'h' + index" class="tdData"></td>
        </tr>
      </table>
      <el-row>
        <el-col :span="12">
          <div class="inspection-card">
            <div class="echartsTitle">检测数据对比</div>
            <Echarts ref="chart"
                     :grid="grid"
                     :legend="legend"
                     :lineColors="lineColors"
                     :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="echartsTitle">测量数据标准差对比</div>
            <Echarts ref="chart"
                     :barColors="barColors"
                     :chartStyle="chartStyle"
                     :grid="grid"
                     :legend="legend1"
                     :series="echartsSeries1"
                     :tooltip="tooltip"
                     :xAxis="xAxis1"
                     :yAxis="yAxis1"
                     style="height: 40vh;"></Echarts>
          </div>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <div class="inspection-card">
            <div class="echartsTitle">偏差分析</div>
            <Echarts ref="chart"
                     :grid="grid"
                     :legend="legend2"
                     :lineColors="lineColors"
                     :series="echartsSeries2"
                     :tooltip="tooltip"
                     :xAxis="xAxis"
                     :yAxis="yAxis2"
                     style="height: 40vh;"></Echarts>
          </div>
        </el-col>
        <el-col :span="12">
          <div class="inspection-card">
            <div class="echartsTitle">检测中心数据</div>
            <Echarts ref="chart"
                     :grid="grid"
                     :legend="legend"
                     :lineColors="lineColors"
                     :series="echartsSeries3"
                     :tooltip="tooltip"
                     :xAxis="xAxis"
                     :yAxis="yAxis"
                     style="height: 40vh;"></Echarts>
          </div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>
<script>
import Echarts from "./echarts.vue";
export default {
  name: "DataComparison",
  // import å¼•入的组件需要注入到对象中才能使用
  components: {Echarts},
  props: {
    comparisonData : {
      type: Object,
      default: () => {}
    },
    selectRow : {
      type: Object,
      default: () => {}
    }
  },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      supplierForm: {
        one: '',
        two: '',
        three: '',
        four: '',
        five: '',
      },
      rules: {
        one: [{ required: true, message: '必填', trigger: 'blur' }],
        two: [{ required: true, message: '必填', trigger: 'blur' }],
        three: [{ required: true, message: '必填', trigger: 'blur' }],
        four: [{ required: true, message: '必填', trigger: 'blur' }],
        five: [{ required: true, message: '必填', trigger: 'blur' }],
      },
      comparisonData1: {},
      supplierData: [], // åŽ‚å®¶æ•°æ®
      localData: [], // æ£€æµ‹ä¸­å¿ƒæ£€æµ‹æ•°æ®
      absoluteDeviation: [], // ç»å¯¹åå·®
      average: [], // å¹³å‡å€¼
      supplierULC: [], // åނ家UCL
      supplierLCL: [], // åނ家LCL
      supplierAverage: [], // åŽ‚å®¶å¹³å‡å€¼
      supplierRange: [], // åŽ‚å®¶æžå·®
      localULC: [], // æ£€æµ‹ä¸­å¿ƒUCL
      localLCL: [], // æ£€æµ‹ä¸­å¿ƒLCL
      localAverage: [], // æ£€æµ‹ä¸­å¿ƒå¹³å‡å€¼
      localRange: [], // æ£€æµ‹ä¸­å¿ƒæžå·®
      manufacturerData: [],
      manufacturer: [
        {value: '1.1'},
        {value: '2.2'},
        {value: '3.3'},
        {value: '4.4'},
        {value: '5.5'},
      ],
      testCenter: [
        {value: '1.2'},
        {value: '2.33'},
        {value: '3.64'},
        {value: '4.3'},
        {value: '5.9'},
      ],
      empty: [
        {data: '1'},
        {data: '2'},
        {data: '3'},
        {data: '4'},
      ],
      lineColors: ['#ed7d31', '#409EFF'],
      barColors: ['#ed7d31', '#409EFF', '#a5a5a5'],
      chartStyle: {
        width: '100%',
        height: '96%' // è®¾ç½®å›¾è¡¨å®¹å™¨çš„高度
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      legend: {
        data: ['厂家检测数据','检测中心检测数据']
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        }
      },
      xAxis: [{
        type: 'category',
        data: ['1', '2', '3', '4', '5']
      }],
      yAxis: [{
        type: 'value'
      }],
      echartsSeries: [
        {
          name: '厂家检测数据',
          type: 'line',
          label: {
            show: true,
            position: 'top',
          },
          data: []
        },
        {
          name: '检测中心检测数据',
          type: 'line',
          label: {
            show: true,
            position: 'top',
          },
          data: []
        }
      ],
      xAxis1: [{
        type: 'category',
        data: ['厂家', '检测中心']
      }],
      legend1: {
        data: ['UCL','LCL', '平均值']
      },
      yAxis1: [
        {
          type: 'value',
        },
      ],
      echartsSeries1: [
        {
          name: 'UCL',
          type: 'bar',
          label: {
            show: true,
            position: 'top'
          },
          data: []
        },
        {
          name: 'LCL',
          type: 'bar',
          label: {
            show: true,
            position: 'top'
          },
          data: []
        },
        {
          name: '平均值',
          type: 'bar',
          label: {
            show: true,
            position: 'top'
          },
          data: []
        },
      ],
      legend2: {
        data: ['平均值','绝对偏差']
      },
      yAxis2: [{
        type: 'value',
        min: 0,
        max: 1,
      }],
      echartsSeries2: [
        {
          name: '平均值',
          type: 'line',
          label: {
            show: true,
            position: 'top',
            formatter: (params) => Math.round(params.value * 1000) / 10 + '%'
          },
          data: [],
        },
        {
          name: '绝对偏差',
          type: 'line',
          label: {
            show: true,
            position: 'top',
            formatter: (params) => Math.round(params.value * 1000) / 10 + '%'
          },
          data: [],
        }
      ],
      echartsSeries3: [
        {
          name: '检测中心检测数据',
          type: 'line',
          data: []
        }
      ],
    }
  },
  mounted() {
    this.getInfo()
  },
  // æ–¹æ³•集合
  methods: {
    getInfo () {
      this.localData = this.comparisonData.localData === null ? ['', '', '', '', '','','', '', ''] : this.comparisonData.localData
      this.localData = this.localData.map((number, index) => index === 7 ? `${Math.round(number * 100)}%` : number)
      this.echartsSeries3[0].data = this.localData.slice(0, 5)
      this.localULC = this.comparisonData.localULC
      this.localLCL = this.comparisonData.localLCL
      this.localAverage = this.comparisonData.localAverage
      this.localRange = this.comparisonData.localRange
    },
    getInfo1 () {
      this.echartsSeries1[0].data = []
      this.supplierData = this.comparisonData1.supplierData === null ? ['', '', '', '', '','','', '', ''] : this.comparisonData1.supplierData
      this.localData = this.comparisonData1.localData === null ? ['', '', '', '', '','','', '', ''] : this.comparisonData1.localData
      this.localData = this.localData.map((number, index) => index === 7 ? `${Math.round(number * 100)}%` : number)
      this.echartsSeries3[0].data = this.localData.slice(0, 5)
      this.echartsSeries[0].data = this.supplierData
      this.echartsSeries[1].data = this.localData
      this.absoluteDeviation = this.comparisonData1.absoluteDeviation === null ? ['', '', '', '', '','','', '', ''] : this.comparisonData1.absoluteDeviation
      this.echartsSeries2[1].data = this.absoluteDeviation
      this.absoluteDeviation = this.absoluteDeviation.map(number => `${Math.round(number * 100)}%`) // ç»å¯¹åå·®ç™¾åˆ†æ¯”转换
      this.average = this.comparisonData1.average === null ? ['', '', '', '', '','','', '', ''] : this.comparisonData1.average
      this.echartsSeries2[0].data = this.average
      this.average = this.average.map(number => `${Math.round(number * 100)}%`) // å¹³å‡å€¼ç™¾åˆ†æ¯”转换
      this.supplierULC = this.comparisonData1.supplierULC === null ? ['', '', '', '', ''] : this.comparisonData1.supplierULC
      this.echartsSeries1[0].data.push(this.supplierULC[0]) // æµ‹é‡æ•°æ®æ ‡å‡†å·®å¯¹æ¯”柱状图数据
      this.supplierLCL = this.comparisonData1.supplierLCL === null ? ['', '', '', '', ''] : this.comparisonData1.supplierLCL
      this.echartsSeries1[1].data.push(this.supplierLCL[0]) // æµ‹é‡æ•°æ®æ ‡å‡†å·®å¯¹æ¯”柱状图数据
      this.supplierAverage = this.comparisonData1.supplierAverage === null ? ['', '', '', '', ''] : this.comparisonData1.supplierAverage
      this.echartsSeries1[2].data.push(this.supplierAverage[0]) // æµ‹é‡æ•°æ®æ ‡å‡†å·®å¯¹æ¯”柱状图数据
      this.supplierRange = this.comparisonData1.supplierRange === null ? ['', '', '', '', ''] : this.comparisonData1.supplierRange
      this.localULC = this.comparisonData1.localULC
      this.echartsSeries1[0].data.push(this.localULC[0]) // æµ‹é‡æ•°æ®æ ‡å‡†å·®å¯¹æ¯”柱状图数据
      this.localLCL = this.comparisonData1.localLCL
      this.echartsSeries1[1].data.push(this.localLCL[0]) // æµ‹é‡æ•°æ®æ ‡å‡†å·®å¯¹æ¯”柱状图数据
      this.localAverage = this.comparisonData1.localAverage
      this.echartsSeries1[2].data.push(this.localAverage[0]) // æµ‹é‡æ•°æ®æ ‡å‡†å·®å¯¹æ¯”柱状图数据
      this.localRange = this.comparisonData1.localRange
    },
    submitForm () {
      this.$refs['supplierForm'].validate((valid) => {
        if (valid) {
          const params = {
            orderIds: this.selectRow.orderIds,
            itemNames: this.selectRow.itemNames,
            supplierDataList: Object.values(this.supplierForm)
          }
          this.$axios.post(this.$api.dataAnalysis.getRawSupplierCompare, params, {
            headers: {
              'Content-Type': 'application/json'
            },
            noQs: true
          }).then(res => {
            if (res.code === 201) {
              return
            }
            this.comparisonData1 = res.data
            this.getInfo1()
          })
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    resetForm () {
      this.$refs['supplierForm'].resetFields();
    },
  },
}
</script>
<style scoped>
.title {
  height: 60px;
  line-height: 60px;
}
.container {
  width: calc(100% - 20px);
  height: calc(100vh - 170px);
  background-color: #fff;
  padding: 10px;
  overflow-y: auto;
}
.table {
  width: 100%;
}
.thTitle {
  background-color: #e0eaf5;
  padding: 6px 2px;
}
.thBack {
  text-align: center;
  background-color: #e0eaf5;
  padding: 2px;
}
.thBack2 {
  text-align: center;
  background-color: #e4f2da;
  padding: 2px;
}
.tdData {
  padding: 4px;
  text-align: center;
  font-size: 13px;
  width: 10%;
}
.inspection-card{
  width: 100%;
  background: #FFFFFF;
  margin-top: 10px;
}
.echartsTitle {
  text-align: center;
  padding-bottom: 10px;
}
</style>
src/components/echarts/echarts.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,238 @@
<template>
  <div>
    <div id="id" ref="chart" :style="chartStyle"></div>
  </div>
</template>
<script>
import * as echarts from 'echarts'
import ResizeListener from 'element-resize-detector';
export default {
  name: 'EChart',
  props: {
    options: {
      type: Object,
      default: () => ({})
    },
    chartStyle: {
      type: Object,
      default: () => ({
        height: '80%',
        width: '100%'
      })
    },
    dataset: {
      type: Object,
      default: () => {}
    },
    xAxis: {
      type: Array,
      default: () => []
    },
    yAxis: {
      type: Array,
      default: () => []
    },
    series: {
      type: Array,
      default: () => []
    },
    grid: {
      type: Object,
      default: () => ({})
    },
    legend: {
      type: Object,
      default: () => ({})
    },
    tooltip: {
      type: Object,
      default: () => ({})
    },
    lineColors: {
      type: Array,
      default: () => ['#00BAFF', '#3DE7C9', '#CCEDF0', '#FFB71C', '#FF5A5A']
    },
    barColors: {
      type: Array,
      default: () => ['#ff8800', '#3DE7C9', '#CCEDF0', '#FFB71C', '#FF5A5A']
    },
    loadingOption: {
      type: Object,
      default: () => ({
        text: '数据加载中...',
        color: '#00BAFF',
        textColor: '#000',
        maskColor: 'rgba(255, 255, 255, 0.8)',
        zlevel: 0
      })
    }
  },
  data() {
    return {
      chartInstance: null,
    }
  },
  watch: {
    options: {
      deep: true,
        // immediate: true,
        handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
    series: {
      deep: true,
      // immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
    dataset: {
      deep: true,
      // immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
    xAxis: {
      deep: true,
      // immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
    yAxis: {
      deep: true,
      // immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
    grid: {
      deep: true,
      // immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
    legend: {
      deep: true,
      // immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
    tooltip: {
      deep: true,
      // immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
    lineColors: {
      deep: true,
      // immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
    barColors: {
      deep: true,
      // immediate: true,
      handler(val) {
        this.$nextTick(() => {
          this.renderChart()
        })
      },
    },
  },
  mounted() {
    this.chartInstance = echarts.init(this.$refs.chart)
    this.renderChart()
    window.addEventListener('resize', this.windowResizeListener);
  },
  beforeDestroy() {
    this.dispose()
  },
  methods: {
    /* å½“窗口缩放时,echart动态调整自身大小 */
    windowResizeListener() {
      if (!this.chartInstance) return;
      this.dispose()
      this.chartInstance = echarts.init(this.$refs.chart)
      this.renderChart()
      this.chartInstance.resize();
    },
    renderChart() {
      const option = {
        backgroundColor: this.options.backgroundColor || '#fff',
        xAxis: this.xAxis,
        yAxis: this.yAxis,
        dataset: this.dataset,
        series: this.series,
        grid: this.grid,
        legend: this.legend,
        tooltip: this.tooltip
      }
      // æ ¹æ®ä¼ å…¥çš„æ•°æ®å’Œé…ç½®å‚数生成图表
      this.generateChart(option)
    },
    generateChart(option) {
      // é…ç½®æŠ˜çº¿å›¾å’ŒæŸ±çŠ¶å›¾çš„æ ·å¼
      if (option.series && option.series.length > 0) {
        option.series.forEach((s, index) => {
          if (s.type === 'line') {
            s.itemStyle = {
              color: this.lineColors[index] || this.lineColors[0]
            }
            s.lineStyle = {
              color: this.lineColors[index] || this.lineColors[0]
            }
          } else if (s.type === 'bar') {
            s.itemStyle = {
              color: this.barColors[index] || this.barColors[0]
            }
          }
        })
      }
      this.chartInstance.clear()
      // æ¸²æŸ“图表
      this.chartInstance.setOption(option)
    },
    dispose() {
      if (this.chartInstance) {
        window.removeEventListener('resize', this.chartInstance.resize);//销毁图表监听事件
        this.chartInstance.dispose()
        this.chartInstance = null
      }
    }
  },
}
</script>
<style scoped>
/* åœ¨è¿™é‡Œå¯ä»¥å†™æ ·å¼ï¼Œæ¯”如设置图表容器的宽度和高度 */
</style>
src/layout/components/Navbar.vue
@@ -12,6 +12,16 @@
      <div class="avatar-wrapper">
        <img :src="avatar" class="user-avatar" />
        <span class="userName">{{ nickName }}</span>
        <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
          <div class="avatar-wrapper">
            <i class="el-icon-caret-bottom" />
          </div>
          <el-dropdown-menu slot="dropdown">
            <router-link to="/user/profile">
              <el-dropdown-item>个人中心</el-dropdown-item>
            </router-link>
          </el-dropdown-menu>
        </el-dropdown>
        <img
          class="logoout"
          src="@/assets/images/logoout.png"
@@ -211,9 +221,6 @@
      }
    }
    .avatar-container {
      margin-right: 30px;
    }
  }
}
</style>
src/router/index.js
@@ -104,18 +104,19 @@
        path: "customsInspection",
        component: () =>
          import("@/views/business/materialOrder/customsInspection"),
        name: "customsInspection",
        name: "CustomsInspection",
        meta: {
          title: "原材料下单详情",
          activeMenu: "/business/materialOrder",
          keepAlive: true
        },
      },
      {
        // é“œææ–™ä¸‹å•
        path: "copperOrder",
        component: () => import("@/views/business/materialOrder/copperOrder"),
        name: "copperOrder",
        meta: { title: "铜材料下单", activeMenu: "/business/materialOrder" },
        name: "CopperOrder",
        meta: { title: "铜材料下单", activeMenu: "/business/materialOrder",keepAlive: true },
      },
    ],
  },
@@ -131,8 +132,8 @@
        path: "add",
        component: () =>
          import("@/views/business/productOrder/components/add.vue"),
        name: "add",
        meta: { title: "成品下单详情", activeMenu: "/business/materialOrder" },
        name: "Add",
        meta: { title: "成品下单详情", activeMenu: "/business/materialOrder",keepAlive: true },
      },
    ],
  },
src/views/business/materialOrder/copperOrder.vue
@@ -421,6 +421,7 @@
}
export default {
  name: 'CopperOrder',
  components: {},
  dicts: ['check_type', 'urgency_level'],
  data() {
@@ -723,7 +724,7 @@
          this.noNeedCheckLoad = false
          if (res.code == 201) return
          this.$message.success('已提交')
          this.goBack()
          this.closeOpenPage()
        }).catch(e=>{
          this.noNeedCheckLoad = false
        })
@@ -1165,7 +1166,7 @@
        if (res.code == 201) return
        this.$message.success('已提交')
        this.bsm3Dia = false;
        this.goBack()
        this.closeOpenPage()
      }).catch(e=>{
        this.saveLoad = false
      })
@@ -1781,8 +1782,16 @@
    },
    goBack () {
      if (this.active == 1) {
        this.$router.go(-1)
      } else {
        this.closeOpenPage()
      }
    },
    closeOpenPage() {
      this.$router.go(-1)
    }
      this.$tab.closeOpenPage()
    },
  }
}
</script>
src/views/business/materialOrder/customsInspection.vue
@@ -388,7 +388,7 @@
      width="32%">
      <span>{{ dialogMessage }}</span>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="goBack()">ç¡® å®š</el-button>
        <el-button type="primary" @click="dialogVisible= false,closeOpenPage()">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <el-dialog
@@ -633,7 +633,7 @@
      this.standardMethodListId = null
    }
  },
  mounted() {
  created() {
    this.active = this.$route.query.active
    this.orderType = this.$route.query.orderType
    this.currentId = this.$route.query.currentId
@@ -1017,7 +1017,7 @@
        if (res.code == 201) return
        this.noNeedCheckDia = false
        this.$message.success('已提交')
        this.goBack()
        this.closeOpenPage()
      }).catch(e=>{
        this.noNeedCheckLoad = false
      })
@@ -1069,7 +1069,7 @@
        if (res.code == 201) return
        this.$message.success('已提交')
        this.bsm3Dia = false;
        this.goBack()
        this.closeOpenPage()
      }).catch(e=>{
        this.saveLoad = false
      })
@@ -1832,8 +1832,16 @@
      return row[property] === value;
    },
    goBack () {
      if (this.active == 1) {
        this.$router.go(-1)
      } else {
        this.closeOpenPage()
      }
    },
    closeOpenPage() {
      this.$router.go(-1)
    }
      this.$tab.closeOpenPage()
    },
  }
}
</script>
src/views/business/productOrder/components/add.vue
@@ -50,10 +50,10 @@
            </el-select>
          </el-form-item>
          <el-form-item label="制单人:">
            <el-input v-model="addObj.custom" disabled size="small"></el-input>
            <el-input v-model="addObj.custom" disabled size="small" clearable></el-input>
          </el-form-item>
          <el-form-item label="委托单位:" prop="company">
            <el-input v-model="addObj.company" disabled placeholder="选择委托单位" size="small" style="width: 200px">
            <el-input v-model="addObj.company" disabled placeholder="选择委托单位" size="small" style="width: 208px">
              <template slot="append">
                <el-button slot="append" :disabled="active>1&&tabIndex!=4" icon="el-icon-search"
                           @click="openCompanyList"></el-button>
@@ -69,14 +69,14 @@
            </el-select>
          </el-form-item>
          <el-form-item label="样品名称:" prop="sample">
            <el-input v-model="addObj.sample" disabled size="small" style="width: 178px">
            <el-input v-model="addObj.sample" disabled size="small" style="width: 208px">
              <template slot="append"><el-button slot="append" :disabled="active>1&&tabIndex!=4" icon="el-icon-search"
                                                 @click="selectStandardTree = true"></el-button></template>
            </el-input>
          </el-form-item>
          <el-form-item label="样品数量:" prop="sampleNum">
          <el-form-item label="样品数量:" prop="sampleNum" style="margin-right: 0">
            <el-input-number v-model="addObj.sampleNum" :disabled="active>1" :max="100" :min="1" :precision="0"
                             size="small" style="width: 65%;" @change="addStandardTree"></el-input-number>
                             size="small" @change="addStandardTree"></el-input-number>
          </el-form-item>
          <el-form-item label="样品状态:" prop="sampleStatus">
            <el-select v-model="addObj.sampleStatus" :disabled="active>1&&tabIndex!=4" size="small">
@@ -87,21 +87,9 @@
            <el-input v-model="addObj.testQuantity" :disabled="active>1&&tabIndex!=4" clearable size="small"></el-input>
          </el-form-item>
          <el-form-item label="来样方式:" prop="formType">
            <el-select v-model="addObj.formType" :disabled="active>1&&tabIndex!=4" size="small">
            <el-select v-model="addObj.formType" :disabled="active>1&&tabIndex!=4" size="small" clearable>
              <el-option v-for="(a,ai) in dict.type.form_type" :key="ai" :label="a.label" :value="a.value"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="报告发送方式:">
            <el-radio-group v-model="addObj.send" :disabled="active>1&&tabIndex!=4">
              <el-radio :label="1">自取</el-radio>
              <el-radio :label="0">其他</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="样品处理方式:">
            <el-radio-group v-model="addObj.processing" :disabled="active>1&&tabIndex!=4">
              <el-radio :label="0">委托单位取回</el-radio>
              <el-radio :label="1">实验室处理</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="生产单位:" prop="production">
            <el-input v-model="addObj.production" :disabled="active>1&&tabIndex!=4" clearable placeholder="请输入"
@@ -111,10 +99,22 @@
            <el-input v-model="addObj.productionEn" :disabled="active>1&&tabIndex!=4" clearable placeholder="请输入"
                      size="small"></el-input>
          </el-form-item>
          <el-form-item label="样品处理方式:">
            <el-radio-group v-model="addObj.processing" :disabled="active>1&&tabIndex!=4" size="mini">
              <el-radio :label="0" border style="margin-right: 0">委托单位取回</el-radio>
              <el-radio :label="1" border>实验室处理</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="是否留样:">
            <el-radio-group v-model="addObj.isLeave" :disabled="active>1&&tabIndex!=4">
              <el-radio :label="0">不留样</el-radio>
              <el-radio :label="1">留样</el-radio>
            <el-radio-group v-model="addObj.isLeave" border :disabled="active>1&&tabIndex!=4" size="mini">
              <el-radio :label="0" border style="margin-right: 0">不留样</el-radio>
              <el-radio :label="1" border>留样</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="报告发送方式:">
            <el-radio-group v-model="addObj.send" :disabled="active>1&&tabIndex!=4" size="mini">
              <el-radio :label="1" border style="margin-right: 0">自取</el-radio>
              <el-radio :label="0" border>其他</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="委托人:">
@@ -125,7 +125,7 @@
          </el-form-item>
          <el-form-item label="备注:">
            <el-input v-model="addObj.remark" :autosize="{ minRows: 2, maxRows: 2}" :disabled="active>1&&tabIndex!=4" :placeholder="active>1 ? '' : '请输入'" clearable
                      size="small" type="textarea"></el-input>
                      size="small" style="width: 100%" type="textarea"></el-input>
          </el-form-item>
          <el-form-item label="备注英文:">
            <el-input v-model="addObj.remarkEn" :autosize="{ minRows: 2, maxRows: 2}" :disabled="active>1&&tabIndex!=4" :placeholder="active>1 ? '' : '请输入'" clearable
@@ -176,10 +176,9 @@
              </el-form-item>
            </el-form>
          </div>
          <div style="display: flex;align-items: center">
          <div style="display: flex;align-items: center;margin-bottom: 10px">
            <span style="width: 150px;font-size: 14px;text-align: right;">特殊标准:</span>
            <el-input v-model="specialStandardMethod" :disabled="!isSpecial" clearable
            size="small"></el-input>
            <el-input v-model="specialStandardMethod" :disabled="!isSpecial" clearable size="small"></el-input>
            <el-button v-show="active==1" size="small" style="margin-left: 10px"
                       type="primary" @click="editSpecial">编辑</el-button>
          </div>
@@ -432,7 +431,7 @@
      </div>
      <span slot="footer" class="dialog-footer">
        <el-row>
          <el-button @click="issuedDialogVisible=false;goBack">取 æ¶ˆ</el-button>
          <el-button @click="issuedDialogVisible=false;closeOpenPage">取 æ¶ˆ</el-button>
          <el-button :loading="upLoad" type="primary" @click="submitForm2">ç¡® å®š</el-button>
        </el-row>
      </span>
@@ -560,6 +559,7 @@
import {selectCustomPageList} from "@/api/system/customer";
export default {
  name: 'Add',
  components: {
    limsTable,
    cableConfig,
@@ -1210,7 +1210,7 @@
            this.saveLoad = false
            this.$message.success('已提交')
            this.bsm3Dia = false;
            this.goBack()
            this.closeOpenPage()
          }).catch(e=>{
            this.saveLoad = false
          })
@@ -1220,7 +1220,7 @@
            this.saveLoad = false
            this.$message.success('已提交')
            this.bsm3Dia = false;
            this.goBack()
            this.closeOpenPage()
          }).catch(e=>{
            this.saveLoad = false
          })
@@ -1283,7 +1283,7 @@
          this.$message.success('提交成功')
          this.upLoad = false
          this.issuedDialogVisible = false
          this.goBack()
          this.closeOpenPage()
        }).catch(e => {
          this.$message.error('提交失败')
          this.upLoad = false
@@ -1921,16 +1921,12 @@
          state: 2,
          id: this.currentId,
          tell: this.tell
        }, {
          headers: {
            'Content-Type': 'application/json'
          }
        }).then(res => {
          this.noLoading = false;
          this.tell = '';
          this.$message.success('提交成功')
          this.issuedDialogVisible = false;
          this.goBack()
          this.closeOpenPage()
        })
      },
      filterHandler(value, row, column) {
@@ -2143,8 +2139,16 @@
        this.productList0.splice(index,1)
      },
      goBack () {
        if (this.active == 1) {
          this.$router.go(-1)
        } else {
          this.closeOpenPage()
        }
      },
      closeOpenPage() {
        this.$router.go(-1)
      }
        this.$tab.closeOpenPage()
      },
    }
  }
</script>
src/views/statisticalCharts/itemInspectionAnalysis/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,535 @@
<template>
  <div class="app-container">
    <div v-if="!isShowDataCom">
      <el-form ref="entity" size="small" :inline="true">
        <el-form-item style="width: 16%;">
          <el-date-picker
            v-model="datePicker"
            end-placeholder="结束日期"
            format="yyyy-MM-dd"
            placeholder="选择日期"
            range-separator="至"
            size="small"
            start-placeholder="开始日期"
            style="width: 100%;"
            type="daterange"
            value-format="yyyy-MM-dd">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="样品名称" prop="sampleName">
          <el-input v-model="sampleName" clearable placeholder="请输入样品名称" size="small"></el-input>
        </el-form-item>
        <el-form-item label="型号" prop="modelName">
          <el-input v-model="modelName" clearable placeholder="请输入型号" size="small"></el-input>
        </el-form-item>
        <el-form-item label="供应商名称" prop="supplierName">
          <el-input v-model="supplierName" clearable placeholder="请输入供应商名称" size="small"></el-input>
        </el-form-item>
        <el-form-item label="检验项名称" prop="supplierName">
          <el-select v-model="itemNames" :loading="selectLoading" clearable multiple placeholder="请选择"
                     size="small" style="width: 90%;" @focus="getItemList">
            <el-option
              v-for="item in itemNamesList"
              :key="item.value"
              :label="item.label"
              :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button size="small" type="primary" @click="changeData">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div v-if="!isShowDataCom" style="overflow-y: auto;height: calc(100% - 70px);overflow-x: hidden">
      <el-row>
        <el-col :span="24">
          <div class="inspection-card">
            <div style="display: flex;align-items: center;margin-bottom: 10px;justify-content: space-between;">
              <div>原材料项检分析列表</div>
              <el-button size="small" type="primary" @click="openShowData">查看数据分析</el-button>
            </div>
            <lims-table :tableData="editTableData" :column="editColumn"
                        height="400" key="tableData" :isSelection="true"
                        :handleSelectionChange="handleSelectionChange"
                        :tableLoading="editLoading"></lims-table>
          </div>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="6" style="padding-top: 14px">
          <div style="display: flex;margin-left: 10px;align-items: center">
            <span style="width: 100px">分组类型:</span>
            <el-select v-model="groupType" clearable placeholder="请选择"
                       size="small"
                       style="width: 90%;" @change="getBarInfo">
              <el-option
                v-for="item in groupTypeList"
                :key="item.value"
                :label="item.label"
                :value="item.value">
              </el-option>
            </el-select>
          </div>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <div class="inspection-card">
            <div class="title">检验项数据对比</div>
            <Echarts ref="chart"
                     :chartStyle="chartStyle"
                     :dataset="dataset"
                     :grid="grid"
                     :options="echartsOptions"
                     :series="echartsSeries"
                     :tooltip="tooltip"
                     :xAxis="xAxis"
                     :yAxis="yAxis"
                     style="height: 40vh;"></Echarts>
          </div>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <div class="inspection-card">
            <div class="title">原材料项检合格率</div>
            <Echarts ref="chart"
                     :chartStyle="chartStyle"
                     :dataset="dataset1"
                     :grid="grid"
                     :options="echartsOptions1"
                     :series="echartsSeries1"
                     :tooltip="tooltip"
                     :xAxis="xAxis"
                     :yAxis="yAxis1"
                     style="height: 40vh;"></Echarts>
          </div>
        </el-col>
      </el-row>
    </div>
    <el-dialog :visible.sync="dataDialogVisible" title="数据查看" width="80%">
      <div v-if="dataDialogVisible" style="height: 70vh;overflow-y: auto;">
        <lims-table :tableData="tableData" :column="column"
                    @pagination="pagination" key="tableData"
                    :page="page" :tableLoading="tableLoading"></lims-table>
      </div>
    </el-dialog>
    <DataComparison v-if="isShowDataCom" :comparisonData="comparisonData"
                    :selectRow="selectRow" @goBack="goBack"></DataComparison>
  </div>
</template>
<script>
import Echarts from "@/components/echarts/echarts.vue";
import DataComparison from '@/components/echarts/DataComparison.vue'
import limsTable from "@/components/Table/lims-table.vue";
import {
  getRawItemNames,
  getRawProductAnalysis,
  getRawProductAnalysisAllList,
  getRawProductAnalysisRawPass, getRawSupplierCompare
} from "@/api/statisticalCharts/dataAnalysis";
import {selectSampleAndProductByOrderId} from "@/api/business/rawMaterialOrder";
export default {
  name: "ItemInspectionAnalysis",
  // import å¼•入的组件需要注入到对象中才能使用
  components: {limsTable, Echarts, DataComparison},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      selectChangeRows: [], // é€‰ä¸­çš„æ•°æ®
      groupTypeList: [
        {label: '样品', value: '0'},
        {label: '同一厂家, åŒä¸€åž‹å·, ä¸åŒæ‰¹æ¬¡', value: '1'},
        {label: '同一型号, ä¸åŒåނ家', value: '2'},
      ],
      itemNames: [], // æ£€éªŒé¡¹åç§°
      itemNamesList: [],
      selectLoading: false,
      datePicker: [], // æ—¶é—´
      groupType: '', // åˆ†ç»„
      beginDate: '',
      endDate: '',
      sampleName: '', // æ ·å“åç§°
      modelName: '', // åž‹å·
      supplierName: '', // ä¾›åº”商名称
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      echartsOptions: {},
      echartsOptions1: {},
      dataset: {
        dimensions: [],
        source: [],
      },
      dataset1: {
        dimensions: [],
        source: [],
      },
      xAxis: [{ type: 'category' }],
      yAxis: [{}],
      yAxis1: [{
        axisLabel: {
          formatter: '{value} %'
        }
      }],
      echartsSeries: [],
      echartsSeries1: [],
      tooltip: {},
      chartStyle: {
        width: '100%',
        height: '96%' // è®¾ç½®å›¾è¡¨å®¹å™¨çš„高度
      },
      editColumn: [
        {
          label: '批号',
          minWidth: '120px',
          prop: 'updateBatchNo'
        }, {
          label: '委托编号',
          minWidth: '120px',
          prop: 'entrustCode'
        }, {
          label: '零件号',
          minWidth: '120px',
          prop: 'partNo'
        }, {
          label: '零件描述',
          minWidth: '120px',
          prop: 'partDesc'
        }, {
          label: '供应商名称',
          minWidth: '120px',
          prop: 'supplierName',
        }, {
          dataType: 'tag',
          label: '检验状态',
          prop: 'inspectStatus',
          minWidth: '120px',
          formatData: (params) => {
            if (params == 0) {
              return '检验中'
            } else if (params == 1) {
              return '合格'
            } else if (params == 2) {
              return '不合格'
            } else if (params == 3) {
              return '未下单'
            } else if (params == 4) {
              return '让步放行'
            }
          },
          formatType: (params) => {
            if (params == 1 || params == 4) {
              return 'success'
            } else if (params == 3) {
              return 'warning'
            } else if (params == 0 || params == 2) {
              return 'danger'
            }
          }
        }, {
          label: '样品名称',
          minWidth: '300px',
          prop: 'sampleName'
        }, {
          label: '样品型号',
          minWidth: '300px',
          prop: 'sampleModel'
        },{
          label: '下发时间',
          minWidth: '120px',
          prop: 'sendTime'
        },{
          label: '抵达的采购数量',
          minWidth: '130px',
          prop: 'qtyArrived'
        },{
          label: '单位',
          minWidth: '120px',
          prop: 'buyUnitMeas'
        },
        {
          dataType: 'action',
          width: '80px',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '数据查看',
              type: 'text',
              clickFun: (row) => {
                this.handleDataLook(row);
              },
            },
          ]
        }
      ],
      editTableData: [],
      editLoading: false,
      dataDialogVisible: false,
      tableData: [],
      tableLoading: false,
      column: [
        {label: '样品编号', prop: 'sampleCode'},
        {label: '样品名称', prop: 'sample'},
        {label: '检验项分类', prop: 'inspectionItemClass'},
        {label: '检验项', prop: 'inspectionItem'},
        {label: '检验子项', prop: 'inspectionItemSubclass'},
        {label: '单位', prop: 'unit'},
        {label: '样品型号', prop: 'model'},
        {label: '条件', prop: 'radius'},
        {label: '电缆标识', prop: 'cableTag'},
        {label: '试验要求', prop: 'tell'},
        {label: '检验结果', prop: 'lastValue'},
        {
          dataType: 'tag',
          label: '结果判定',
          prop: 'insResult',
          formatData: (params) => {
            if (params == 1) {
              return '合格'
            } else if (params == 0) {
              return '不合格'
            } else if (params == 3) {
              return '不判定'
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 1) {
              return 'success'
            } else if (params == 0) {
              return 'danger'
            } else if (params == 3) {
              return ''
            }  else {
              return null
            }
          }
        }
      ],
      page: {
        total:0,
        size:10,
        current:1
      },
      currentRow: {},
      isShowDataCom: false,
      comparisonData: {},
      selectRow: {},
    }
  },
  mounted() {
    // this.getBar()
  },
  // æ–¹æ³•集合
  methods: {
    getBarInfo (val) {
      if (val === '1') {
        if (!this.modelName || !this.supplierName) {
          this.$message.warning('型号或供应商不能为空')
          this.groupType = ''
          return
        }
      } else if (val === '2') {
        if (!this.modelName) {
          this.$message.warning('型号不能为空')
          this.groupType = ''
          return
        }
        if (this.supplierName) {
          this.$message.warning('不可选供应商名称')
          this.groupType = ''
          return
        }
      }
      this.getBar()
      this.getBar1()
    },
    // èŽ·å–åˆæ ¼çŽ‡å›¾è¡¨æ•°æ®
    getBar() {
      this.echartsSeries = []
      const params = {
        beginDate: this.beginDate,
        endDate: this.endDate,
        sampleName: this.sampleName,
        modelName: this.modelName,
        supplierName: this.supplierName,
        itemNames: this.itemNames,
        groupType: this.groupType,
      }
      getRawProductAnalysis(params).then((res) => {
        if (res.data === null) {
          this.$message.warning('暂无数据')
          return
        }
        for (let i = 0; i < res.data.itemNames.length; i++) {
          this.echartsSeries.push({type: 'line', label: {
              show: true,
              position: 'top'
            },})
        }
        this.dataset.dimensions = this.HaveJson(res.data.itemNames)
        this.dataset.dimensions.unshift('product')
        this.dataset.source = this.HaveJson(res.data.productList)
      })
    },
    getBar1() {
      this.echartsSeries1 = []
      const params = {
        beginDate: this.beginDate,
        endDate: this.endDate,
        sampleName: this.sampleName,
        modelName: this.modelName,
        supplierName: this.supplierName,
        itemNames: this.itemNames,
        groupType: this.groupType,
      }
      getRawProductAnalysisRawPass(params).then((res) => {
        if (res.data === null) {
          this.$message.warning('暂无数据')
          return
        }
        for (let i = 0; i < res.data.itemNames.length; i++) {
          this.echartsSeries1.push({type: 'line',tooltip: {
              valueFormatter: function (value) {
                return value + '%';
              }
            },label: {
              show: true,
              position: 'top',
              formatter: (params) => params.value[params.dimensionNames[params.encode.y[0]]] + '%'
            },})
        }
        this.dataset1.dimensions = this.HaveJson(res.data.itemNames)
        this.dataset1.dimensions.unshift('product')
        this.dataset1.source = this.HaveJson(res.data.productList)
      })
    },
    // æ•°æ®æŸ¥çœ‹
    handleDataLook(row) {
      this.dataDialogVisible = true;
      this.currentRow = row
      this.refreshTable(row)
    },
    // æŸ¥è¯¢å›žè°ƒ
    refreshTable(row) {
      selectSampleAndProductByOrderId({id: row.id}).then(res => {
        this.tableLoading = false
        if (res.code === 200) {
          this.tableData = res.data.records
          this.page.total = res.data.total
        }
      }).catch(err => {
        this.tableLoading = false
      })
    },
    pagination (page) {
      this.page.size = page.limit
      this.refreshTable(this.currentRow)
    },
    changeData () {
      if (this.datePicker !== null && this.datePicker.length > 0) {
        this.beginDate = this.datePicker[0] + ' 00:00:00'
        this.endDate = this.datePicker[1] + ' 23:59:59'
      } else {
        this.beginDate = ''
        this.endDate = ''
      }
      this.getBar()
      this.getBar1()
      this.getTableData()
    },
    getTableData () {
      this.editLoading = true
      const params = {
        beginDate: this.beginDate,
        endDate: this.endDate,
        sampleName: this.sampleName,
        modelName: this.modelName,
        supplierName: this.supplierName,
        itemNames: this.itemNames,
      }
      getRawProductAnalysisAllList(params).then(res => {
        this.editLoading = false
        this.editTableData = res.data
      }).catch(() => {
        this.editLoading = false
      })
    },
    // èŽ·å–æ£€éªŒé¡¹ä¸‹æ‹‰æ¡†
    getItemList () {
      this.selectLoading = true
      this.itemNamesList = []
      const params = {
        beginDate: this.beginDate,
        endDate: this.endDate,
        sampleName: this.sampleName,
        modelName: this.modelName,
        supplierName: this.supplierName,
      }
      getRawItemNames(params).then((res) => {
        this.selectLoading = false
        res.data.map(val => {
          const obj = Object.assign({
            label: val,
            value: val,
          })
          this.itemNamesList.push(obj)
        })
      }).catch(() => {
        this.selectLoading = false
      })
    },
    goBack () {
      this.isShowDataCom = false
    },
    openShowData () {
      if (this.selectChangeRows.length !== 5) {
        this.$message.warning('请选择5条数据')
        return
      }
      if (this.itemNames.length !== 1) {
        this.$message.warning('只能选择1项检验项名称')
        return
      }
      let ids = []
      let itemNames = []
      this.selectChangeRows.forEach(item => {
        ids.push(item.enterOrderId)
      })
      this.itemNames.forEach(item => {
        itemNames.push(item)
      })
      const params = {
        orderIds: ids,
        itemNames: itemNames
      }
      getRawSupplierCompare(params).then(res => {
        this.comparisonData = res.data
        this.selectRow = params
        this.isShowDataCom = true
      })
    },
    handleSelectionChange (val) {
      this.selectChangeRows = val
    },
  },
}
</script>
<style scoped>
.inspection-card{
  width: 100%;
  margin-top: 10px;
}
</style>
src/views/statisticalCharts/qualificationRateStatistics/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,448 @@
<template>
  <div class="app-container">
    <el-row>
      <el-col :span="4">
        <el-radio-group v-model="dateType" @change="changeDate">
          <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="选择日期"
              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">
            <el-input v-model="sampleName" clearable placeholder="请输入样品名称" size="small" @change="changeDate"></el-input>
          </el-form-item>
          <el-form-item label="型号" prop="modelName">
            <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-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: 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: 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: 36vh;"></Echarts>
        </div>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="24">
        <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>
      </el-col>
    </el-row>
  </div>
</template>
<script>
import Echarts from "@/components/echarts/echarts.vue";
import {
  getOrderTypeCookie,
  getRawPassRateByBarChart,
  getRawPassRateByCake,
  getRawUpMonth
} from "@/api/statisticalCharts/dataAnalysis";
export default {
  name: "QualificationRateStatistics",
  // import å¼•入的组件需要注入到对象中才能使用
  components: {Echarts},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      dateType: '1',
      datePicker: [],
      beginDate: '',
      endDate: '',
      sampleName: '',
      modelName: '',
      supplierName: '',
      echartsOptions: {
        title: {
          text: '示例图表',
          left: 'center'
        }
      },
      xAxis: [
        {
          type: 'category',
          data: [],
          axisPointer: {
            type: 'shadow'
          }
        }
      ],
      yAxis: [
        {
          type: 'value',
          name: '总数',
          min: 0,
        },
        {
          type: 'value',
          name: '合格率',
          min: 0,
          max: 100,
          axisLabel: {
            formatter: '{value} %'
          }
        }
      ],
      echartsSeries: [
        {
          name: '总数',
          type: 'bar',
          data: [],
          label: {
            show: true,
            position: 'top'
          },
        },
        {
          name: '合格率',
          type: 'line',
          smooth: true,
          tooltip: {
            valueFormatter: function (value) {
              return value + ' %';
            }
          },
          label: {
            show: true,
            position: 'top',
            formatter: function (value) {
              return value.value + ' %';
            },
            distance: 14
          },
          yAxisIndex: 1,
          data: []
        },
      ],
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      legend: {
        data: ['总数','合格率']
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        }
      },
      lineColors: ['#409EFF'],
      barColors: ['#E6A23C'],
      barColors2: ['#adde8b'],
      pieTooltip: {
        trigger: 'item'
      },
      pieLegend: {
        orient: 'vertical',
        right: 20,
        top: 'middle',
      },
      materialPieSeries: [
        {
          name: 'Access From',
          type: 'pie',
          radius: ['40%', '70%'],
          right: '22%',
          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: '不合格数量' },
            { value: 0, name: '合格数量' },
          ]
        }
      ],
      materialPieSeries1: [
        {
          name: 'Access From',
          type: 'pie',
          radius: ['40%', '70%'],
          right: '22%',
          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: 50,
          },
          data: [
            { value: 0, name: '委托检验' },
            { value: 0, name: '进厂检验' },
            { value: 0, name: '季度检验' },
            { value: 0, name: '抽样' },
          ]
        }
      ],
      barLegend: {},
      chartStyle: {
        width: '90%',
        height: '100%',
      },
      chartStyle2: {
        width: '90%',
        height: '80%',
      },
      xAxis1: [
        {
          type: 'value',
          min: 0,
          max: 100,
          axisLabel: {
            formatter: '{value} %'
          }
        }
      ],
      yAxis1: [
        {
          type: 'category',
          data: []
        }
      ],
      barSeries: [
        {
          type: 'bar',
          data: [],
          tooltip: {
            valueFormatter: function (value) {
              return value + ' %';
            }
          },
          label: {
            show: true,
            formatter: (params) => Math.round(params.value * 100) / 100 + '%'
          }
        },
      ],
      tableData: [],
      passRate: '',
      sum: '',
    }
  },
  mounted() {
    this.getBar()
    this.getRawPass()
    this.getOrderType()
    this.getPassRateCom()
  },
  // æ–¹æ³•集合
  methods: {
    // èŽ·å–åˆæ ¼çŽ‡å›¾è¡¨æ•°æ®
    getBar() {
      const params = {
        dateType: this.dateType,
        beginDate: this.beginDate,
        endDate: this.endDate,
        sampleName: this.sampleName,
        modelName: this.modelName,
        supplierName: this.supplierName,
      }
      getRawPassRateByBarChart(params).then((res) => {
        let lineData = []
        let barData = []
        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
      })
    },
    // èŽ·å–åŽŸææ–™åˆæ ¼çŽ‡å›¾è¡¨æ•°æ®
    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 + '%'
      })
    },
    // èŽ·å–æœ¬æœˆæ£€éªŒç±»åž‹æ•°é‡
    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 // å­£åº¦
        this.materialPieSeries1[0].data[3].value = res.data.spotCheck // æŠ½æ ·
      })
    },
    // æœ¬æœˆä¸Žä¸Šæœˆåˆæ ¼çŽ‡å¯¹æ¯”
    getPassRateCom() {
      getRawUpMonth().then((res) => {
        let month = []
        let barData = []
        res.data.forEach(item => {
          month.push(item.month)
          barData.push(item.passRate)
        })
        this.yAxis1[0].data = month
        this.barSeries[0].data = barData
      })
    },
    changeDate () {
      this.getBar()
      this.getRawPass()
      // this.getOrderType()
      // this.getPassRateCom()
    },
    changeDatePicker (val) {
      if (val) {
        this.beginDate = val[0] + ' 00:00:00'
        this.endDate = val[1] + ' 23:59:59'
      } else {
        this.beginDate = ''
        this.endDate = ''
      }
      this.getBar()
      this.getRawPass()
      // this.getOrderType()
      // this.getPassRateCom()
    },
  },
}
</script>
<style scoped>
.title {
  padding: 10px 0 0 20px;
}
.table {
  padding: 0 10px 10px;
}
.pie-card {
  width: 100%;
  background: #FFFFFF;
  margin-top: 10px;
  position: relative;
}
.data {
  position: absolute;
  font-size: 20px;
  transform: translate(-50%);
  left: 40%;
  top: 42%;
  z-index: 1;
}
.inspection-card{
  width: 100%;
  background: #FFFFFF;
  margin-top: 10px;
}
</style>
src/views/structural/capabilityAndLaboratory/capability/index.vue
@@ -385,8 +385,8 @@
      this.$refs.upload.clearFiles()
      this.uploadDia = false
      this.uploading = false
      if (response.code === 201) {
        this.$message.error(response.message)
      if (response.code !== 200) {
        this.$message.error(response.msg)
        return
      }
      this.$message.success('上传成功')