Vue CPK分析工具页面设计源码(支持左右可拖拽和表格可编辑、复制粘贴)仿照SPC开发

效果图:  

前端代码: 

父组件

<template>
  <div class="app-container home">
    <!--    <el-divider />-->
    <el-row
      type="flex"
      justify="space-around"
      class="row-bg"
      style="margin-bottom: 10px"
    >
      <drag-resize layout-type="L_R" :default-left-width="550" :min-left-width="500" :max-left-width="1000" style="border:0px solid red" @useleftwidth="changeleftwidth()">
        <template slot="lefthtml">
          <el-col>
            <el-row type="flex" justify="space-around" class="row-bg">
              <el-col :span="24">
                <el-card class="box-card" style="height: 300px; margin-bottom: 3px">
                  <cpk-echart ref="cpkEchart" :echartData="tableData" :resultData="cpkData"></cpk-echart>
                </el-card>
              </el-col>
            </el-row>
            <el-row type="flex" justify="space-around" class="row-bg">
              <el-col :span="24">
                <el-card class="box-card cardDiv1">
                  <div slot="header" class="clearfix">
                <span style="font-size: 15px; font-weight: bold"
                >CPK分析结果</span
                >
                  </div>
                  <cpk-item ref="cpkItem" :cpkData="cpkData"></cpk-item>
                </el-card>
              </el-col>
            </el-row>
          </el-col>
        </template>
        <template slot="righthtml">
          <el-col>
            <el-row type="flex" justify="space-around" class="row-bg">
              <el-col :span="24">
                <el-card class="box-card" style="height: 300px">
                  <cpk-line ref="cpkLine" :linePropData="lineData" :lslVal="LSL" :mbzVal="MBZ" :uslVal="USL"></cpk-line>
                </el-card>
              </el-col>
            </el-row>
            <el-row type="flex" justify="space-around" class="row-bg">
              <el-col :span="24" style="">
                <el-card class="box-card cardDiv2">
                  <div slot="header" class="clearfix">
              <span
                style="
                  font-size: 15px;
                  font-weight: bold;
                  margin-left: 11px;
                  margin-right: 10px;
                "
              >CPK数据统计</span
              >
                    <el-button
                      type="warning"
                      size="mini"
                      icon="el-icon-upload"
                      plain
                      @click="handleImport"
                    >导入</el-button
                    >
                    <el-button
                      type="primary"
                      size="mini"
                      icon="el-icon-download"
                      plain
                      @click="handleExport"
                    >导出</el-button
                    >
                    <el-button
                      type="info"
                      size="mini"
                      icon="el-icon-delete"
                      plain
                      :loading="clearLoading"
                      @click="clearCpk"
                    >清除数据</el-button
                    >
<!--                    <el-button-->
<!--                      type="danger"-->
<!--                      size="mini"-->
<!--                      icon="el-icon-edit"-->
<!--                      plain-->
<!--                      :loading="clearLoading"-->
<!--                      @click="pasteCpkData"-->
<!--                    >一键粘贴</el-button-->
<!--                    >-->
                    <el-button
                      type="danger"
                      size="mini"
                      icon="el-icon-setting"
                      plain
                      @click="cpkItems"
                    >分析选项</el-button
                    >
                    <el-button
                      type="success"
                      size="mini"
                      icon="el-icon-s-data"
                      plain
                      :loading="cpkCountLoading"
                      @click="cpkCount"
                    >计算CPK</el-button
                    >
                  </div>
                  <cpk-table ref="cpkTable" :tableData="tableData"></cpk-table>
                </el-card>
              </el-col>
            </el-row>
          </el-col>
        </template>
      </drag-resize>


    </el-row>
    <el-dialog
      title="CPK分析选项"
      :visible.sync="open"
      width="1000px"
      append-to-body
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="110px">
        <el-row :gutter="24">
          <el-divider content-position="left" style="color: #13ce66"
            >规格设置</el-divider
          >
          <el-col :span="8">
            <el-form-item label="上规格" prop="usl">
              <el-input-number
                v-model="form.usl"
                placeholder="请输入上规格"
                :min="0"
                :max="1000000"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="目标值" prop="targetValue">
              <el-input-number
                v-model="form.targetValue"
                placeholder="请输入目标值"
                :min="0"
                :max="1000000"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="下规格" prop="lsl">
              <el-input-number
                v-model="form.lsl"
                placeholder="请输入下规格"
                :min="0"
                :max="1000000"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-divider content-position="left" style="color: #13ce66"
            >样本设置</el-divider
          >
          <el-col :span="8">
            <el-form-item label="小数位数" prop="xsCount">
              <el-input-number
                v-model="form.xsCount"
                placeholder="请输入小数位数"
                :min="0"
                :max="5"
                :precision="0"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-divider content-position="left" style="color: #13ce66"
            >计算CPK</el-divider
          >
          <el-col :span="8">
            <el-form-item label="子组大小" prop="sonGroup">
              <el-input-number
                v-model="form.sonGroup"
                placeholder="请输入子组大小"
                :min="1"
                :max="999999"
                :precision="0"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="数据组数" prop="dataCount">
              <el-input-number
                v-model="form.dataCount"
                placeholder="请输入数据组数"
                :min="0"
                :max="999999"
                :precision="0"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <div style="color: red; transform: translateY(10px)">
              注:值为0时表示自动计算
            </div>
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-col :span="12">
            <el-form-item label="估算标准差方法" prop="types">
              <el-radio-group v-model="radioVal" @change="setTypes">
                <el-radio :label="1" :value="1">标准差</el-radio>
<!--                <el-radio :label="2" :value="2">极差值</el-radio>-->
<!--                <el-radio :label="3" :value="3">合并标准差</el-radio>-->
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <div style="color: red; transform: translateY(10px)">
              注:当样本大小或子组大小等于1时,直接按极差值计算
            </div>
          </el-col>
        </el-row>
        <el-row :gutter="24"> </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
<!--    <file-import ref="fileImport" :title="title" :path="path"></file-import>-->
    <el-dialog
      :title="title"
      :visible.sync="fileOpen"
      width="400px"
      append-to-body
    >
      <el-upload
        ref="upload"
        :limit="1"
        accept=".xlsx, .xls"
        action
        :auto-upload="false"
        :on-change="handle"
        :file="file"
        drag
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <div class="el-upload__tip text-center" slot="tip">
          <span>仅允许导入xls、xlsx格式文件。</span>
<!--          <el-link-->
<!--            type="primary"-->
<!--            :underline="false"-->
<!--            style="font-size: 12px; vertical-align: baseline"-->
<!--            @click="importTemplate"-->
<!--          >下载模板</el-link-->
<!--          >-->
        </div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
<!--        <el-button type="primary" @click="submitFileForm">确 定</el-button>-->
        <el-button @click="fileOpen = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import * as echarts from "echarts";
import * as XLSX from "xlsx/xlsx.mjs";
import { read, utils } from 'xlsx/xlsx.mjs';
import FileSaver from "file-saver";
import CpkEchart from "../module/cpkEchart";
import CpkItem from "../module/cpkItems";
import CpkLine from "../module/cpkLine";
import CpkTable from "../module/cpkTable";
import FileImport from "@/components/FileImport";
import DragResize from '@/components/DragResize';
import { listSysmessage, getSysmessage, delSysmessage, addSysmessage, updateSysmessage,listMyUnreadNotice,setMessageReaded } from "@/api/system/sysmessage";
import { cpkAcount } from "@/api/cpk/cpk";
import {mapGetters} from "vuex";

export default {
  name: "cpkCount",
  components: { CpkEchart, CpkItem, CpkLine, CpkTable,FileImport,DragResize },
  data() {
    return {
      // 版本号
      version: "3.8.6",
      tableKey: false, //表格的key及显示与隐藏
      excelName: "", //excel表格名称
      excelHeader: [], //excel的表头
      tableColumn: [], //表格的表头
      LSL:'',
      MBZ:'',
      USL:'',
      form: {
        xsCount:2
      },
      rules:{
        usl: [
          { required: true, message: "上规格不能为空", trigger: ["blur"] }
        ],
        targetValue: [
          { required: true, message: "目标值不能为空", trigger: ["blur",] }
        ],
        lsl: [
          { required: true, message: "下规格不能为空", trigger: ["blur",] }
        ],
        sonGroup:[
          { required: true, message: "子组大小不能为空", trigger: ["blur",] }
          ],
        dataCount: [
          { required: true, message: "数组组数不能为空", trigger: ["blur",] }
        ]
      },
      open: false,
      isOpenModal:false,
      radioVal: 1,
      title:'CPK数据导入',
      path:'',
      fileOpen:false,
      tableData:[],
      lineData:[],
      resultData:{},
      tableLength:0,
      file:null,
      cpkData:'',
      cpkParams:{
      createBy: "",// 创建人
      data: "", //数据 //"10,50,10,10,10"
      sonGroup:0, // 子组大小
      usl:0,//上规格
      lsl:0, //下规格
      targetValue:0,//目标值
      xsCount:0, //小数位数  默认两位
      dataCount:0,//数据组数
      types:1//估算标准差方法 1标准差 2 极值差 3 合并标准差//
  },
      tData:[
        ['','','','','','','','','',''],
        ['','','','','','','','','',''],
        ['','','','','','','','','',''],
        ['','','','','','','','','',''],
        ['','','','','','','','','',''],
        ['','','','','','','','','',''],
        ['','','','','','','','','',''],
        ['','','','','','','','','',''],
        ['','','','','','','','','',''],
        ['','','','','','','','','',''],
      ],
      clearLoading:false,
      cpkCountLoading:false
    };
  },
  computed: {
    ...mapGetters(['name']),
  },
  created() {
  },
  mounted() {
    // this.tableData = this.$refs.cpkTable.tableData2
    //数据组装
    // this.tableData = this.tableData.map(item => Object.values(item));
    // 监听键盘按键事件
    // window.addEventListener('keydown', this.handleKeyDown);
    this.pasteDataByMounted()
  },
  beforeDestroy() {
    // 移除键盘按键事件监听
    window.removeEventListener('keydown', this.handleKeyDown);
  },
  methods: {
    goTarget(href) {
      window.open(href, "_blank");
    },
    cancel() {
      this.open = false;
    },
    //监听粘贴事件
    pasteDataByMounted(){
      document.addEventListener("paste", e => {
        e.preventDefault(); //阻止默认粘贴事件
        e.stopPropagation(); //阻止事件冒泡
        let pasteData = (e.clipboardData || window.clipboardData).getData("text"); //以text方式接收粘贴内容
        // 将复制的数据按行分割
        const rows = pasteData.split('\n');

        // 清空表格数据
        // this.tableData = [];
        const tableData = []
        // 将数据填充到表格中
        for (let i = 0; i < rows.length; i++) {
          const arr = []
          const rowData = rows[i].split('\r');
          if(rowData[0] !=='' && rowData[0] !== null){
            arr.push(rowData[0])
          }
          // const tableRow = {
          //   col1: rowData[0],
          //   col2: rowData[1],
          //   // 其他列...
          // };
          tableData.push(arr);
        }
        this.tableData = tableData
        this.lineData = tableData
        this.$message.success('粘贴成功')
      })
    },

    handleKeyDown(event) {
      // 按下Ctrl+V执行粘贴操作
      if (event.ctrlKey && event.key === 'v') {
        // 获取粘贴的内容 监听键盘事件获取ctrl+v的内容 获取不到弃用  改为document.addEventListener("paste")进行监听
        const pastedData = event.clipboardData.getData('text/plain');
      }
    },
    /** 导出按钮操作 */
    handleExport() {
      const data = this.tableData
      // 创建工作簿对象
      const workbook = XLSX.utils.book_new();

      // 创建工作表对象
      const worksheet = XLSX.utils.json_to_sheet(data);

      // 将工作表添加到工作簿中
      XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');

      // 导出 Excel 文件
      const excelData = XLSX.write(workbook, { type: 'array', bookType: 'xlsx' });

      // 创建 Blob 对象
      const blob = new Blob([excelData], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });

      // 创建下载链接
      const url = URL.createObjectURL(blob);

      // 创建下载链接并点击下载
      const link = document.createElement('a');
      link.href = url;
      link.download = this.excelName+'.xlsx';
      link.click();

      // 释放资源
      URL.revokeObjectURL(url);
    },
    //分析选项保存提交用来计算CPK
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.open = false;
          this.isOpenModal = true
          this.LSL = this.form.lsl
          this.MBZ = this.form.targetValue
          this.USL = this.form.usl
          this.$nextTick(()=>{
            setTimeout(()=>{
              this.$refs.cpkLine.setLineData()
            },300)

          })
          // this.$nextTick(()=>{
          //   this.$refs.cpkEchart.initEchart()
          // })
        }
      });
    },
    handleImport(){
      this.file = null
      this.fileOpen = true
    },
    setTypes(val){
      this.form.types = val
    },
    //分析选项
    cpkItems(){
      this.open = true
    },
    //清除数据
    clearCpk(){
      this.clearLoading = true
      this.tableData = this.tData
      this.$refs.cpkTable.tableDatas =this.tableData
      this.lineData = []
      this.$refs.cpkLine.lineData =this.lineData
      this.$message.success('清除成功')
      setTimeout(()=>{
        this.clearLoading = false
      },500)

    },
    //一键粘贴
    pasteCpkData() {
      this.pasteDataByMounted()
    },
    //计算CPK
    cpkCount(){
      if(this.isOpenModal){
        this.cpkCountLoading = true
        this.$refs.cpkItem.loading = true;
        this.$refs.cpkEchart.myChart.showLoading({
          text: "加载中...",
          color: "#1890ff",
          textColor: "#1890ff",
          showSpinner: false,
          maskColor: "rgba(255, 255, 255, 0.7)",});
        let table = ''
        if(this.tableData.length === 0){
          table = this.$refs.cpkTable.tableDatas.join(',')
        }else{
          table = this.tableData.join(',') //数组转字符串逗号隔开
        }
        Object.assign(this.cpkParams,this.form)
        this.cpkParams.xsCount = this.form.xsCount || 2//默认小数位数2位
        this.cpkParams.data = table
        this.cpkParams.createBy = this.name
        cpkAcount(this.cpkParams).then(response => {
          // this.sysmessageList = response.rows;
          if(response.code === 200){
            this.LSL = this.form.lsl
            this.MBZ = this.form.targetValue
            this.USL = this.form.usl
            this.cpkData = response.data
            this.$nextTick(()=>{
              this.$refs.cpkEchart.initEchart()
            })
            this.$message.success('计算成功')
            this.$refs.cpkEchart.myChart.hideLoading();
            this.cpkCountLoading = false
            this.$refs.cpkItem.loading = false;
          }else{
            console.log(response.msg)
            this.cpkCountLoading = false
          }
        }).catch(error=>{
          this.cpkCountLoading = false
          this.$refs.cpkItem.loading = false;
          this.$refs.cpkEchart.myChart.hideLoading();
        });
      }else{
        this.$message.warning('分析选项必填项不能为空')
      }
    },
    //
    changeleftwidth(){
      this.$nextTick(()=>{
        if(this.$refs.cpkEchart){
          this.$refs.cpkEchart.dregResize()
        }
        if(this.$refs.cpkLine){
          this.$refs.cpkLine.resizeTheChart()
        }
      })
    },
    readFile(file) {
      //文件读取
      return new Promise((resolve) => {
        let reader = new FileReader();
        reader.readAsBinaryString(file); //以二进制的方式读取
        reader.onload = (ev) => {
          resolve(ev.target.result);
        };
      });
    },
    // 上传文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
    async handle(ev) {
      //改变表格key值
      this.$refs.cpkTable.loading = true;
      this.$refs.cpkLine.myChart.showLoading({
        text: "加载中...",
        color: "#1890ff",
        textColor: "#1890ff",
        showSpinner: false,
        maskColor: "rgba(255, 255, 255, 0.7)",});
      this.tableKey = true;
      this.file = ev.raw;
      this.excelName = this.file.name;
      //截取表格文件名
      this.excelName = this.excelName.substring(
        0,
        this.excelName.lastIndexOf(".")
      );
      console.log("上传的未解析源文件", this.file);
      if (!this.file) {
        console.log("文件打开失败");
        return;
      } else {
        //<!-- 用来解析表头的代码-->
        // let data = await this.readFile(file);
        // let workbook = XLSX.read(data, { type: "binary" }); //解析二进制格式数据
        // console.log("二进制数据的解析:", workbook);
        // let worksheet = workbook.Sheets[workbook.SheetNames[0]]; //获取第一个Sheet
        // // 调用解析表头方法
        // this.getHeader(worksheet);
        // let result = XLSX.utils.sheet_to_json(worksheet); //转换为json数据格式
        // console.log("最终解析的 json 格式数据:", result);
        // this.tableData = result;
        // // 调用处理表头函数
        // this.setTable();
        //<!-- 用来解析表头的代码-->
        // 读取 Excel 文件
        //<!-- 不需要解析表头的代码-->
        const file = this.file;
        const reader = new FileReader();
        const that = this
        reader.onload = function(e) {
          const data = new Uint8Array(e.target.result);
          const workbook = read(data, { type: 'array' });
          const sheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[sheetName];
          const jsonData = utils.sheet_to_json(worksheet, { header: 1, raw: false, defval: '' });
          // const worksheet = workbook.Sheets[workbook.SheetNames[0]];
          // const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
          that.tableData = jsonData
          that.lineData = jsonData
          // 在这里处理读取到的数据
        };
        reader.readAsArrayBuffer(file);
        that.fileOpen = false

        that.$refs.cpkLine.lineData = this.tableData;
        that.LSL = this.form.lsl
        that.MBZ = this.form.targetValue
        that.USL = this.form.usl
        setTimeout(()=>{
          that.$message.success(this.excelName+'导入成功')
          that.$refs.upload.clearFiles();
          that.$refs.cpkTable.loading = false;
          that.$refs.cpkLine.myChart.hideLoading();
        },800)
        // that.tableLength = that.tableData.length
        // this.setTable()
        //<!-- 不需要解析表头的代码-->
      }
    },
    submitFileForm(){
      if(this.tableLength ===0){
        this.$message.warning('请先上传文件!')
        return
      }
        // this.$refs.cpkTable.tabledData2 = this.tableData
      this.fileOpen = false
      this.$message.success('导入成功')
    },
    // 解析出表格表头
    getHeader(sheet) {
      // const XLSX = XLSX;
      const headers = [];
      const range = XLSX.utils.decode_range(sheet["!ref"]); // worksheet['!ref'] 是工作表的有效范围
      let C;
      /* 获取单元格值 start in the first row */
      const R = range.s.r; // 行 // C 列
      let i = 0;
      for (C = range.s.c; C <= range.e.c; ++C) {
        var cell =
          sheet[
            XLSX.utils.encode_cell({ c: C, r: R })
            ]; /* 根据地址得到单元格的值find the cell in the first row */
        var hdr = "UNKNOWN" + C; // 如果有空表头,会替换为您想要的默认值replace with your desired default
        // XLSX.utils.format_cell 生成单元格文本值
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell);
        if (hdr.indexOf("UNKNOWN") > -1) {
          if (!i) {
            hdr = "__EMPTY";
          } else {
            hdr = "__EMPTY_" + i;
          }
          i++;
        }
        headers.push(hdr);
      }
      // 保存至data中
      this.excelHeader = headers;
      return headers;
    },
    // 设置表格中英文映射
    setTable() {
      const headers = this.excelHeader;
      const excellist = this.tableData;
      const tableTitleData = []; // 存储表格表头数据
      const tableMapTitle = {}; // 设置表格内容中英文对照用
      headers.forEach((_, i) => {
        tableMapTitle[_] = "cord" + i;
        tableTitleData.push({
          prop: "cord" + i,
          label: _,
          width: 100,
        });
      });
      console.log("表格头标题:", tableTitleData);
      // 映射表格内容属性名为英文
      const newTableData = [];
      excellist.forEach((_) => {
        const newObj = {};
        Object.keys(_).forEach((key) => {
          newObj[tableMapTitle[key]] = _[key];
        });
        newTableData.push(newObj);
      });
      this.tableColumn = tableTitleData;
      this.tableData = newTableData;
    },
  },
};
</script>

<style scoped lang="scss">
::v-deep .el-card__body {
  padding: 15px 20px 20px 20px;
  display: flex;
  justify-content: center;
}
::v-deep .el-table--medium .el-table__cell {
  padding: 5px 0;
}
::v-deep .el-table th.el-table__cell.is-leaf,
.el-table td.el-table__cell {
  padding: 0px;
  height: 30px;
  line-height: 30px;
}
.el-divider__text {
  color: #4caf50;
}
.box-div {
  height: 120px;
  padding: 35px;
  margin: 20px;
}
.cardDiv1 {
  width: 100%;
  margin-bottom: 10px;
  height: calc(100vh - 135px);
  overflow: auto;
}
.cardDiv2 {
  width: 100%;
  margin-top: 3px;
  margin-bottom: 20px;
  height: calc(100vh - 135px);
}
.app-container {
  padding: 0px;
  background: #eeeeee50;
}
.home {
  blockquote {
    padding: 10px 20px;
    margin: 0 0 20px;
    font-size: 17.5px;
    border-left: 5px solid #eee;
  }
  hr {
    margin-top: 20px;
    margin-bottom: 20px;
    border: 0;
    border-top: 1px solid #eee;
  }
  .col-item {
    margin-bottom: 20px;
  }

  ul {
    padding: 0;
    margin: 0;
  }

  font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 13px;
  color: #676a6c;
  overflow-x: hidden;

  ul {
    list-style-type: none;
  }

  h4 {
    margin-top: 0px;
  }

  h2 {
    margin-top: 10px;
    font-size: 26px;
    font-weight: 100;
  }

  p {
    margin-top: 10px;

    b {
      font-weight: 700;
    }
  }
}
</style>

四个子组件

左1

<template>
  <div ref="cpk" id="cpk" style="height: 300px; width: 100%"></div>
</template>

<script>
  import * as echarts from "echarts";
  import { debounce } from "../../../../utils";
  export default {
    name: "CpkVue",
    components: {},
    props:{
      echartData:{

      },
      resultData:{

      }
    },
    watch: {
      echartData: {
        handler: function (val, oldVal) {
          if (val) {
            this.eData = val
            this.eData = val.flat()//二维转一维
            this.eData = this.eData.map(Number);
          }
        },
        // immediate: true
      },
      resultData: {
        handler: function (val, oldVal) {
          if (val) {
            this.rData = val
          }
        },
        // immediate: true
      },
    },
    data() {
      return {
        myChart: null,
        eData:[],
        rData:{},
        defaultMin:0
      };
    },
    created() {
      this.initEchart();
    },
    mounted() {
      const cpkEchart = document.getElementById("cpk");
      this.myChart = echarts.init(cpkEchart);
      this.echartReseize()
    },
    beforeDestroy() {
      if (!this.myChart) {
        return;
      }
      window.removeEventListener("resize", this.__resizeHandler);
      this.myChart = null;
    },
    methods: {
      initEchart() {
        const nums = 1.398;
        const tableData = this.eData || []
        const resultData = this.rData || {}
        const lsl = resultData.lsl && Number(resultData.lsl) || ''; //下规格
        const usl = resultData.usl && Number(resultData.usl) || ''; //上规格
        const maxVal = resultData.maxValue && Number(resultData.maxValue) || ''; //最大值
        const minVal = resultData.minValue && Number(resultData.minValue) || ''; //最小值
        // const nom = 25.34;
        const sigma_plus3 = Number(resultData.sigma) || ''; //+3sigma
        const sigma_minus3 = Number(resultData.sigmaF) || ''; //-3sigma
        //平均值
        const mean = resultData.avgValue && Number(Number(resultData.avgValue).toFixed(2)) || ''; //24.3
        //cpk标准差 组内
        const std1 = 3.32;
        //ppk标准差  整体
        const std2 = resultData.stdev2 && Number(resultData.stdev2) || 0
        //样本范围
        const range = [minVal-5, maxVal+5];
        //x轴分辨率
        const resolution = 10000;
        //计算X轴上的每个点
        const xData = [];
        //步长
        const step = (range[1] - range[0]) / resolution;
        for (let i = range[0]; i <= range[1]; i += step) {
          xData.push(parseFloat(i.toFixed(2)));
        }
        const groupCount = Number(resultData.dataCount) || 0;
        const min = Math.min(...tableData);
        const max = Math.max(...tableData);
        const binWidth = (max - min) / groupCount;

        const bins = Array.from({ length: groupCount }, (_, i) => ({
          range: [min + i * binWidth, min + (i + 1) * binWidth],
          count: 0,
        }));
        if(tableData.length >0){
          this.defaultMin = Math.min.apply(null, xData)
        }
        tableData.forEach((value) => {
          let binIndex = Math.floor((value - min) / binWidth);
          if(binIndex===groupCount){
            binIndex--
          }
          bins[binIndex].count++;
        });

        bins.sort((a, b) => a.range[0] - b.range[0]); // 按照 range 范围值从小到大排序
        //柱状图上的点
        //组装数据
        const newData = bins.map(item => {
          const newValue = [Number(Number(item.range[0]).toFixed(2)), item.count];
          return newValue;
        });
        const barData = newData
        // const barData = [
        //   [22.20, 2],
        //   [23.06, 6],
        //   [23.91, 6],
        //   [24.77, 4],
        //   [25.63, 13],
        //   [26.48, 11],
        //   [27.34, 4],
        //   [28.20, 1],
        //   [29.06, 1],
        //   [29.91, 2],
        // ];

        //计算曲线上每个点的y值
        // 组内
        const yData1 = [];
        for (let i = 0; i < xData.length; i++) {
          const x = xData[i];
          const y =
            Math.exp(-0.5 * Math.pow((x - mean) / std1, 2)) / // exp 返回e的x次幂 e是自然对数
            (std1 * Math.sqrt(2 * Math.PI)); //sqrt 返回x的平方根
          yData1.push(y);
        }
        //整体
        const yData2 = [];
        for (let i = 0; i < xData.length; i++) {
          const x = xData[i];
          const y =
            Math.exp(-0.5 * Math.pow((x - mean) / std2, 2)) / // pow 返回x的y次幂
            (std2 * Math.sqrt(2 * Math.PI));
          yData2.push(y);
        }
        // Echarts 图的配置
        const optionData = {
          title: {
            text: "CPK分析直方图",
            subtext: "",
            textStyle: {
              fontSize: 15,
            },
          },
          legend: {

            // data: [
            //   {
            //     name:"过程能力(估算)",
            //     borderType: 'dashed',
            //     itemStyle:{
            //       opacity:0
            //     },
            //     lineStyle: {
            //       color: '#1980ff', // 设置线的颜色为红色
            //       type:'dashed',
            //       width:2
            //     }
            //   },
            //   {
            //     name:"过程能力(实测)",
            //     itemStyle:{
            //       opacity:0
            //     },
            //     // lineStyle: {
            //     //   color: '#1980ff', // 设置线的颜色为红色
            //     //   type:'dashed',
            //     //   width:2
            //     // }
            //   },
            //
            // ],
          },
          //提示
          tooltip: {
            trigger: "item",
            axisPointer: {
              type: "shadow",
            },
            formatter: function (params) {
              if (params.componentType === "series") {
                return `${params.seriesName}<br>${parseFloat(
                  parseFloat(params.value[0]) - nums * 0.5
                ).toFixed(2)}~${parseFloat(
                  parseFloat(params.value[0]) + parseFloat(nums * 0.5)
                ).toFixed(2)} : ${params.value[1]}</br>`;
              } else {
                return `${params.name} : ${params.value}`;
              }
            },
          },
          toolbox: {
            show: true,
            feature: {
              saveAsImage: { show: true },
            },
          },
          xAxis: [
            {
              type: "value",
              axisLabel: {
                showMinLabel: false, //不显示坐标轴最小值标签
                showMaxLabel: false, //不显示坐标轴最大值标签
              },
              boundaryGap: false,
              min: this.defaultMin,
              max: Math.max.apply(null, xData),
            },
            {
              type: "category",
              axisTick: {
                show: false, //不显示刻度
              },
              axisLabel: {
                show: false, // 将 show 参数设置为 false
                formatter: "{value}",
              },
              data: xData,
            },
          ],
          // xAxis: [
          //     {
          //       type: "value",
          //       axisLabel: {
          //         showMinLabel: false, //不显示坐标轴最小值标签
          //         showMaxLabel: false, //不显示坐标轴最大值标签
          //       },
          //       boundaryGap: false,
          //       min: Math.min.apply(null, xData),
          //       max: Math.max.apply(null, xData),
          //     },
          //   {
          //   type: 'category',
          //   name: '范围',
          //   data: bins.map((bin) => `${bin.range[0].toFixed(2)} - ${bin.range[1].toFixed(2)}`),
          //   axisLabel: {
          //     formatter: (value) => value.split(' - ')[0], // 只返回左边的范围值
          //   },
          // }
          // ],
          yAxis: [
            {
              type: "value",
              name: "频数",
              position: "left",
              // 网格线
              splitLine: {
                show: false,
              },
              axisLine: {
                show: true, //是否显示坐标轴轴线
                lineStyle: {
                  color: "#000",
                },
              },
            },
            {
              type: "value",
              name: "",
            },
            {
              type: "value",
              name: "概率",
              position: "right",
              // 网格线
              splitLine: {
                show: false,
              },
              axisLine: {
                show: true, //是否显示坐标轴轴线
                lineStyle: {
                  color: "black",
                },
              },
            },
          ],
          series: [
            {
              name: "数据个数", // y 轴名称
              type: "bar", // y 轴类型
              yAxisIndex: 0, //使用主坐标轴
              xAxisIndex: 0, //使用主坐标轴x轴
              barWidth: '85%',              //---柱形宽度
              barCategoryGap: "50%", //---柱形间距
              itemStyle: {
                normal: {
                  show: true,
                  color: "#1890ff", //柱子颜色
                  borderColor: "#1890ff", //边框颜色
                  barBorderRadius: 2,
                },
              },
              data: barData, // y 轴数据 -- 源数据
            },
            //先去掉组内
            // {
            //   // name: "组内",
            //   type: "line",
            //   xAxisIndex: 1,
            //   yAxisIndex: 1,
            //   symbol: "none",
            //   smooth: true,
            //   data: yData1,
            //   lineStyle: {
            //     color: '#1980ff', // 设置线的颜色为红色
            //     type:'dashed',
            //     width:2
            //   }
            // },
            {
              name: "整体",
              type: "line",
              yAxisIndex: 1,
              xAxisIndex: 1,
              symbol: "none",
              smooth: true,
              data: yData2,
              itemStyle:{
                opacity:0
              },
              lineStyle: {
                color: 'green', // 设置线的颜色为红色
                width:2
              }
            },
            {
              name: "",
              type: "line",
              xAxisIndex: 0,
              yAxisIndex: 0,
              symbol: "none",
              smooth: true,

              //实测数据警示线
              markLine: {
                symbol: ["none"], // 箭头方向
                itemStyle: { color: "#FF0000" },
                animation: false,
                label: {
                  show: true,
                  fontSize: 14,
                  fontWeight: "bold",
                  formatter: function (params) {
                    if (
                      params.name === "-3σ" ||
                      params.name === "+3σ" ||
                      params.name === "X-bar"
                    ) {
                      return `${params.name}\n`;
                    } else {
                      return `${params.name}`;
                    }
                  },
                },
                data: [
                  {
                    name: "LSL",
                    xAxis: lsl,
                    lineStyle: { color: "#066d06", width: 2 },
                    label: { color: "#066d06", position: "end" },
                  },
                  {
                    name: "USL",
                    xAxis: usl,
                    lineStyle: { color: "#066d06", width: 2 },
                    label: { color: "#066d06", position: "end" },
                  },
                  // {
                  //   name: "NOM",
                  //   xAxis: nom,
                  //   lineStyle: { color: "#ffbe11", width: 2 },
                  //   label: { color: "#ffbe11", position: "end" },
                  // },
                  {
                    name: "-3σ",
                    xAxis: sigma_minus3,
                    lineStyle: { color: "red", width: 2 },
                    label: { color: "red", position: "end" },
                  },
                  {
                    name: "+3σ",
                    xAxis: sigma_plus3,
                    lineStyle: { color: "red", width: 2 },
                    label: { color: "red", position: "end" },
                  },
                  {
                    name: "X-bar",
                    xAxis: mean,
                    lineStyle: { color: "red", width: 2 },
                    label: { color: "red", position: "end" },
                  },
                ],
              },
            },
          ],
        };
        this.$nextTick(() => {
          this.myChart.setOption(optionData);
        }, 500);
      },
      echartReseize(){
        this.__resizeHandler = debounce(() => {
          // this.myChart 所绘制的图表
          if (this.myChart) {
            this.myChart.resize();
          }
        }, 100);
        this.$nextTick(() => {
          window.addEventListener("resize", this.__resizeHandler);
        }, 500);
      },
      dregResize(){
        if (this.myChart) {
          this.myChart.resize();
        }
      }
    },
  };
</script>

<style scoped lang="scss">
  .statistics {
    width: 1000px;
    height: 400px;
  }
  .cpk {
    /*height: 300px;*/
    /*width: 700px;*/
  }
</style>

右1

<template>
  <div id="main1" style="height: 220px;width:100%">

  </div>
</template>

<script>
    import * as echarts from "echarts";

    export default {
        name: "index",
      components:{},
      data(){
          return{
            myChart:null
          }
      },
      created() {
        this.setLineData()
      },
      mounted() {
        const chartDom = document.getElementById('main1');
        this.myChart = echarts.init(chartDom);
        this.$nextTick(()=>{
          this.myChart.resize()
        })
        window.addEventListener('resize', this.resizeTheChart) //监听屏幕变化时自适应图
      },
      methods:{
        resizeTheChart() {
          if (this.myChart) {
            this.myChart.resize()
          }
        },
        setLineData(){
          var option;
          const data= ['10', '20', '30', '40', '50', '60', '70','80','90',100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,400]

          const dateList = data.map(function (item) {
            return item;
          });
          option = {
            visualMap: [
              {
                show: false,
                type: 'continuous',
                seriesIndex: 0,
                min: 0,
                max: 700
              },
              {
                show: false,
                type: 'continuous',
                seriesIndex: 1,
                dimension: 0,
                min: 0,
                max: dateList.length - 1
              }
            ],
            title: [{
              text: '数据趋势图形',
              textStyle: {
                fontSize: 15
              },

            },
              // {
              //   text: '单位:万元',
              //   left:'80%',
              //   textStyle:{
              //     fontSize:13,
              //     fontWeight:100
              //   }
              // }
              ],
            tooltip: {
              trigger: 'axis'
            },
            xAxis: {
              type: 'category',
              data: ['10', '20', '30', '40', '50', '60', '70','80','90',100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,400]
            },
            yAxis: {
              type: 'value',
              max:800,
              min:0,
              minInterval: 200,
              interval:200, //每次增加几个
              splitLine:{
                show:true,
                lineStyle:{
                  // type:'dashed',
                }
              }
            },
            series: [
              {
                data: [150, 230, 224, 218, 135, 147, 260,260,22,324,44,234,546,34,234,234,64,24,346,242,436,24,643,462,462,45,343,234,62,342,46,342,363,345,234,632,34,46,34],
                type: 'line',
                // itemStyle: {
                //   normal: {
                //     color: "#2ec7c9",
                //     lineStyle: {
                //       color: "rgb(30 198 149)"
                //     }
                //   }
                // },
                markLine: {
                  symbol: 'none',
                  data: [
                    {
                      yAxis: 100,
                      name: 'LSL',
                      lineStyle: {
                        type: 'solid',
                        color: '#066d06',
                        width: 1
                      },
                      // label: {
                      //   normal: {
                      //     formatter: '供电碳排放强度基线'
                      //   }
                      // }

                    },
                    {
                      yAxis: 260,
                      name: 'M',
                      lineStyle: {
                        type: 'dashed',
                        color: '#e50808',
                        width:2
                      },
                    },
                    {
                      yAxis: 600,
                      name: 'USL',
                      lineStyle: {
                        type: 'solid',
                        color: '#066d06',
                        width: 1
                      },
                      // label: {
                      //   normal: {
                      //     formatter: '供热碳排放强度基线'           // 设置基线
                      //   }
                      // }
                    }
                  ]
                }
              }
            ]
          };
          this.$nextTick(()=>{
            option && this.myChart.setOption(option);
          },200)

        },
      }
    }
</script>

<style scoped>

</style>

左下1

<template>
  <div style="width: 100%;">
    <el-row type="flex" justify="space-around" class="row-bg">
      <el-col :span="24">
        <el-table
          :data="tableData"
          :row-class-name="tableRowClassName"
          border
          :header-cell-style="{background:'#e8f4ff',color:'#606266'}"
          style="width: 100%">
          <el-table-column
            prop="ybzs"
            width="100px"
            label="样本总数">
          </el-table-column>
          <el-table-column
            prop="zzdx"
            width="100px"
            label="子组大小">
          </el-table-column>
          <el-table-column
            prop="average"
            label="平均值">
          </el-table-column>
          <el-table-column
            prop="max"
            label="最大值">
          </el-table-column>
          <el-table-column
            prop="min"
            label="最小值">
          </el-table-column>
        </el-table>
        <el-table
          :data="tableData3"
          :row-class-name="tableRowClassName"
          border
          :header-cell-style="{background:'#e8f4ff',color:'#606266'}"
          style="width: 100%">
          <el-table-column
            prop="sgg"
            width="100px"
            label="上规格">
          </el-table-column>
          <el-table-column
            prop="mbz"
            width="100px"
            label="目标值">
          </el-table-column>
          <el-table-column
            prop="xgg"
            label="下规格">
          </el-table-column>
          <el-table-column
            prop="add3sigma"
            label="+3Sigma">
          </el-table-column>
          <el-table-column
            prop="reduce3sigma"
            label="-3Sigma">
          </el-table-column>
        </el-table>
        <el-table
          :data="tableData2"
          :row-class-name="tableRowClassName"
          class="trStyle"
          border
          :header-cell-style="{background:'#e8f4ff',color:'#606266'}"
          style="width: 100%">
          <el-table-column
            prop="code"
            width="100px"
            label="指标项">
            <template slot-scope="{row}">
              <div style="color: #1890ff">{{ row.code }}</div>
            </template>
          </el-table-column>
          <el-table-column
            prop="date"
            width="100px"
            label="组内">
          </el-table-column>
          <el-table-column
            prop="money"
            label="整体">
          </el-table-column>
          <el-table-column
            prop="name"
            label="实测">
          </el-table-column>
        </el-table>
        <el-table
          :data="tableData4"
          :row-class-name="tableRowClassName"
          border
          :header-cell-style="{background:'#e8f4ff',color:'#606266'}"
          style="width: 100%">
          <el-table-column
            prop="ca"
            width="100px"
            label="CA">
          </el-table-column>
          <el-table-column
            prop="v1"
            width="120px"
            label="">
          </el-table-column>
          <el-table-column
            prop="v2"
            width="140px"
            label="">
          </el-table-column>
          <el-table-column
            prop="v3"
            label="">
          </el-table-column>
        </el-table>
      </el-col>
    </el-row>

  </div>
</template>

<script>
  export default {
    name: "index",
    components: {},
    data() {
      return {
        tableData: [
          {
            ybzs: '50',
            zzdx: '5',
            average: '20.825',
            max: '30.55',
            min:'22.25'
          },
        ],
        tableData3: [
          {
            sgg: '28',
            mbz: '25.5',
            xgg: '23',
            add3sigma: '31.38',
            reduce3sigma:'20.82'
          },
        ],
        tableData4: [
          {
            ca: '28',
            v1: '[n=6]>28 %8.57',
            v2: '[n=2]<23 %2.57',
            v3: '[n=8]超规格 %11.43',
          },
        ],
        tableData2: [
          {
            code: 'STDEV',
            date: '1.750471',
            money: '1.62874',
            name: '0',
          },
          {
            code: 'CPK',
            date: '6.35',
            money: '0.38',
            name: '0',
          },
          {
            code: 'CP',
            date: '0.48',
            money: '0.51',
            name: '0',
          },
          {
            code: 'CPL',
            date: '0.6',
            money: '0.64',
            name: '0',
          },
          {
            code: 'CPU',
            date: '0.578',
            money: '0.36',
            name: '0',
          },
          {
            code: 'PPM<LSL',
            date: '35968.25',
            money: '25654.84',
            name: '0',
          },
          {
            code: 'PPM>USL',
            date: '145288.65',
            money: '128542.21',
            name: '565625',
          },
          {
            code: 'PPM Total',
            date: '13353.65',
            money: '15847.25.21',
            name: '33425',
          },
        ]
      }
    },
    methods: {
      tableRowClassName({row, rowIndex}) {
        if (rowIndex % 2 === 0) {
          return 'warning-row';
        } else if (rowIndex % 2 !== 0) {
          return 'success-row';
        }
        return '';
      }
    }
  }
</script>

<style>
  .el-table .warning-row {
    background: rgba(252, 239, 216, 0.37);
  }

  .el-table .success-row {
    /*background: #f0f9ebdb;*/
    background: rgba(252, 239, 216, 0.37);
  }
  .trStyle table>tr>td{
    background: #e8f4ff;
  }
  ::v-deep .el-table__row .warning-row td{
    background-color: #1c84c6;
  }
</style>

右下1

<template>
  <div style="width: 100%;">
    <el-row type="flex" justify="space-around" class="row-bg">
    </el-row>
    <el-row>
      <el-col :span="24" >
        <el-table
          :data="tableDatas"
          v-loading="loading"
          element-loading-text="加载中..."
          element-loading-spinner="el-icon-loading"
          element-loading-background="rgba(255, 255, 255, 0.7)"
          :show-header=false
          border
          height="calc(100vh - 215px)"
          style="width: 100%">
          <el-table-column
            v-for="(item, index) in tableDatas[0]" :key="index">
            <template slot-scope="scope">
              <div class="noBor">
                <el-input-number :min="0" :max="999999"
                  v-model="scope.row[index]"
                  placeholder=""
                ></el-input-number>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </el-col>
    </el-row>

  </div>
</template>

<script>
  import events from '@/utils/events'
    export default {
        name: "index",
      components:{},
      props:{
          tableData:{
            type:Array,
            default:[]
          }
      },
      data(){
          return{
            // tableNewData:this.tableData,
            tableDatas:[
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
             ["0", "0", "0", "0", "0", "0", "0",'0','0','0'],
           ],
            loading:false
          }
      },
      watch:{
        tableData: {
          handler: function(val, oldVal) {
            if(val){
              this.tableDatas = val
              const newArr = [];
              for (let i = 0; i < this.tableDatas.length; i += 10) {
                const group = this.tableDatas.slice(i, i + 10).map(item => item[0]);
                newArr.push(group);
              }
              this.tableDatas = newArr
              console.log(newArr);
            }
          },
          // immediate: true
        },
      },
      created() {

      },
      mounted() {
      },
      methods:{

      }
    }
</script>

<style scoped lang="scss">
  ::v-deep .el-input-number--medium .el-input__inner {
    padding-left: 10px;
    padding-right: 10px;
    width:100%;
    border:0px;
    border-radius: 1px
  }
  ::v-deep .el-table td.el-table__cell div {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    width: 100%;
  }
  ::v-deep .el-input-number--medium .el-input-number__decrease {
    width: 36px;
    font-size: 14px;
    display: none;
  }
  ::v-deep .el-input-number--medium .el-input-number__increase {
    width: 36px;
    font-size: 14px;
    display: none;
  }
  ::v-deep .el-table__cell{
    /*padding-left: 2px!important;*/
    /*padding-right: 0px!important;*/
    text-align: center;
  }
  ::v-deep .el-table--border .el-table__cell:hover{
    background-color: #107c41 !important;
    /*cursor: crosshair;*/
  }
  ::v-deep .el-table--medium .el-table__cell {
    padding: 4px 0!important;
  }
  ::v-deep .el-table--border .el-table__cell:first-child .cell {
    padding-left: 2px;
  }
  ::v-deep .el-table .cell {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: normal;
    word-break: break-all;
    line-height: 23px;
    padding-left: 4px!important;
    padding-right: 4px!important;
  }
  ::v-deep .el-loading-spinner {
    top: 30%;
    margin-top: -21px;
    width: 100%;
    text-align: center;
    position: absolute;
  }
</style>

拖拽组件 可支持左右、上下模式拖拽


<template>
  <div style="width:100%;height:100%;overflow:hidden;">
    <!-- 左右布局 -->
    <div v-if="layoutType === 'L_R'" style="width:100%;height:100%;overflow:hidden;display:flex;flex-direction:row">
      <div class="basestyle" :style="{width: leftwidth+'px'}">
        <div v-if="isdown" class="zhezhao">
          <iframe src="" style="position:absolute;z-index:-1" frameborder="0"></iframe>
        </div>
        <slot name="lefthtml"></slot>
      </div>
      <!-- @mouseleave="tuoUp()" -->
      <div class="tuodonglr" @mousedown.stop.prevent="tuoDown">
        <div class="lrbtn" @mousedown.stop.prevent="tuoDown">
          <img :src="updown" alt="" style="transform: translate(0px, 3px) rotate(0deg); width:14px;" />
        </div>
      </div>
      <div class="basestyle" style="flex:1;">
        <div v-if="isdown" class="zhezhao">
          <iframe style="position:absolute;z-index:-1" src="" frameborder="0"></iframe>
        </div>
        <slot name="righthtml"></slot>
      </div>
    </div>
    <!-- 上下布局 -->
    <div v-if="layoutType === 'U_D'" style="width:100%;height:100%;overflow:hidden;display:flex;flex-direction:column">
      <div class="heibasestyle" :style="{height: topheight+'px'}">
        <div v-if="isdown" class="zhezhao">
          <iframe style="position:absolute;z-index:-1" src="" frameborder="0"></iframe>
        </div>
        <slot name="tophtml"></slot>
      </div>
      <div class="tuodongud" @mousedown.stop.prevent="tuoDown">
        <div class="udbtn" @mousedown.stop.prevent="tuoDown">
          <img :src="updown" alt="" style="width:14px;" />
        </div>
      </div>
      <div class="heibasestyle" style="flex:1;">
        <div v-if="isdown" class="zhezhao">
          <iframe style="position:absolute;z-index:-1" src="" frameborder="0"></iframe>
        </div>
        <slot name="bottomhtml"></slot>
      </div>
    </div>
  </div>
</template>

<script>
  import updown from '../../assets/images/drag.png'
  export default {
    name: 'MingResize',
    props: {
      layoutType: {
        type: String,
        default: 'L_R' // L_R 左右 U_D 上下
      },
      defaultLeftWidth: {
        type: Number,
        default: 0
      },
      defaultTopHeight: {
        type: Number,
        default: 200
      },
      minLeftWidth: {
        type: Number,
        default: 400
      },
      maxLeftWidth: {
        type: Number,
        default: 800
      },
      minTopHeight: {
        type: Number,
        default: 100
      },
      maxTopHeight: {
        type: Number,
        default: 500
      }
    },
    data() {
      return {
        isdown: false,
        topheight: 100,
        leftwidth: 550,
        updown,
        nowY: null,
        nowX: null
      }
    },

    mounted() {
      if (this.layoutType === 'L_R') {
        this.leftwidth = this.defaultLeftWidth
      } else if (this.layoutType === 'U_D') {
        this.topheight = this.defaultTopHeight
      }
    },

    destroyed() {
      this.tuoUp()
    },

    methods: {
      tuoDown(event) {
        this.isdown = true
        // console.log(event)
        window.addEventListener('mousemove', this.mouseMove)
        window.addEventListener('mouseup', this.tuoUp)
        this.nowX = event.clientX
        this.nowY = event.clientY
        // console.log('现在的X轴:::', event.clientX, '现在的Y轴:::', event.clientY)
      },

      // 拖动start
      tuoUp() {
        console.log('鼠标抬起啦');
        window.removeEventListener('mousemove', this.mouseMove)
        window.removeEventListener('mouseup', this.tuoUp)
        this.isdown = false
        this.$emit('useleftwidth', this.leftwidth)
      },
      mouseMove(event) {
        if (this.layoutType === 'L_R') {
          // console.log(this.nowX, '-----', event.clientX);
          const wid = this.leftwidth + (event.clientX - this.nowX)
          if (this.minLeftWidth < wid && wid < this.maxLeftWidth) {
            this.leftwidth = wid
          }
          this.nowX = event.clientX
          // this.$emit('useleftwidth', this.leftwidth)
        } else if (this.layoutType === 'U_D') {
          // console.log(this.nowY, '---Y軸--', event.clientY);
          const hei = this.topheight + (event.clientY - this.nowY)
          if (this.minTopHeight < hei && hei < this.maxTopHeight) {
            this.topheight = hei
          }
          this.nowY = event.clientY
          this.$emit('usetopheight', this.topheight)
        }

        // console.log('区域拖动');
      }
      // 拖动end
    }
  }
</script>
<style scoped>
  .tuodonglr{
    position: relative;
    -moz-user-select:none;-webkit-user-select:none;user-select:none;height:100%;width: 6px;
    cursor:col-resize;background:#dddddd;display:flex;justify-content: flex-start;align-items: center;
  }
  .tuodonglr:hover{
    background:#aaaaaa;
  }
  .tuodonglr:hover:after {
    position: absolute;
    top: 290px;
    left: 16px;
    font-size: 14px;
    padding: 2px;
    background-color: #ffffff;
    border: 1px solid #999999;
    border-radius: 5px;
    text-align: center;
    color: #666666;
    /*这里显示的内容为title属性对应的值*/
    content: '左右拖动改变区域大小';
    z-index: 888;
    width: 80px;
  }

  .tuodongud{
    position: relative;-moz-user-select:none;-webkit-user-select:none;user-select:none;width: 100%;background:#dddddd;
    height:6px; cursor:row-resize;border:1px solid #cccccc;
  }
  .tuodongud:hover{
    background:#aaaaaa;
  }
  .tuodongud:hover:after {
    position: absolute;
    left: 43%;
    top: 16px;
    font-size: 14px;
    padding: 2px;
    background-color: #ffffff;
    border: 1px solid #999999;
    border-radius: 5px;
    text-align: center;
    color: #666666;
    /*这里显示的内容为title属性对应的值*/
    content: '上下拖动改变区域大小';
    z-index: 9999900;
    width: 80px;
  }
  .heibasestyle{width: 100%;overflow: auto;position:relative;}
  .basestyle{
    position:relative;
    height:100%;overflow:auto
  }
  .lrbtn{
    cursor:pointer; position:absolute;z-index:888; background:#ffffff;border-radius:50%;text-align:center;
    width:20px;height:20px; line-height: 13px;border:1px solid #f0f0f0;box-shadow:#2196F3  0px 0px 10px;left:-7px;top:290px;
  }
  .udbtn{
    cursor:pointer; position:absolute;z-index:888; background:#ffffff;border-radius:50%;text-align:center;left: 45%;
    width:20px;height:20px; line-height: 13px;border:1px solid #f0f0f0;box-shadow:#666 0px 0px 10px;top:-7px;
  }
  .zhezhao{
    position:absolute;left:0;top:0; bottom:0;right:0;background:rgba(9,9,9,0);z-index:888;overflow:hidden;
  }
</style>

后端代码:

cpkController.java

package com.ruoyi.web.controller.cpk;


import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.cpk.Cpk;
import com.ruoyi.system.service.cpk.ICpkService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * cpk 计算Controller
 *
 * @author ruoyi
 * @date 2023-10-03
 */
@Api(value="Cpk",tags={"cpk 计算"})
@RestController
@RequestMapping("/cpk")
public class CpkController extends BaseController
{
    @Autowired
    private ICpkService cpkService;

    /**
     * 查询cpk 计算列表
     */
    @ApiOperation(value = "查询cpk 计算列表,权限 office:cpk:list",  httpMethod = "GET")
    //@PreAuthorize("@ss.hasPermi('office:cpk:list')")
    @GetMapping("/list")
    public TableDataInfo list(Cpk cpk)
    {
        startPage();
        List<Cpk> list = cpkService.selectCpkList(cpk);
        return getDataTable(list);
    }

    /**
     * 导出cpk 计算列表
     */
    @ApiOperation(value = "导出cpk 计算列表,权限office:cpk:export",  httpMethod = "POST")
    //@PreAuthorize("@ss.hasPermi('office:cpk:export')")
    @Log(title = "cpk 计算", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Cpk cpk)
    {
        List<Cpk> list = cpkService.selectCpkList(cpk);
        ExcelUtil<Cpk> util = new ExcelUtil<Cpk>(Cpk.class);
        util.exportExcel(response, list, "cpk 计算数据");
    }

    /**
     * 获取cpk 计算详细信息
     */
    @ApiOperation(value = "获取cpk 计算详细信息,权限 office:cpk:query", httpMethod = "GET")
    //@PreAuthorize("@ss.hasPermi('office:cpk:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(cpkService.selectCpkById(id));
    }

    /**
     * 新增cpk 计算
     */
    @ApiOperation(value = "新增cpk 计算,权限 office:cpk:add",httpMethod = "POST")
    //@PreAuthorize("@ss.hasPermi('office:cpk:add')")
    @Log(title = "cpk 计算", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Cpk cpk)
    {
        return toAjax(cpkService.insertCpk(cpk));
    }

    /**
     * 修改cpk 计算
     */
    @ApiOperation(value = "修改cpk 计算,权限 office:cpk:edit",  httpMethod = "POST")
    //@PreAuthorize("@ss.hasPermi('office:cpk:edit')")
    @Log(title = "cpk 计算", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    public AjaxResult edit(@RequestBody Cpk cpk)
    {
        return toAjax(cpkService.updateCpk(cpk));
    }



    /**
     * 删除cpk 计算
     */
    @ApiOperation(value = "删除cpk 计算,权限 office:cpk:remove", httpMethod = "GET")
    //@PreAuthorize("@ss.hasPermi('office:cpk:remove')")
    @Log(title = "cpk 计算", businessType = BusinessType.DELETE)
    @GetMapping("/remove/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(cpkService.deleteCpkByIds(ids));
    }


    /**
     * cpk 计算
     */
    @ApiOperation(value = "cpk 计算,权限 office:cpk:edit",  httpMethod = "POST")
    @Log(title = "cpk 计算", businessType = BusinessType.UPDATE)
    @PostMapping("/sumCpk")
    public AjaxResult sumCpk(@RequestBody Cpk cpk)
    {
        String data = cpk.getData();
        String[] split = data.split(",");

        if(split.length >0){
            Cpk spks = cpkService.sumCpk(cpk);
            return AjaxResult.success(spks);
        }else{
            return AjaxResult.success("数据为空");
        }
    }
}

domain实体类 cpk.java

package com.ruoyi.system.domain.cpk;

import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

/**
 * cpk 计算对象 cpk
 *
 * @author ruoyi
 * @date 2023-10-03
 */
public class Cpk extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** 主键 */
    private Long id;

    /** 数据 */
    @Excel(name = "数据")
    private String data;

    /** 总样本数 */
    @Excel(name = "总样本数")
    private String dataSum;

    /** 子组大小 */
    @Excel(name = "子组大小")
    private String sonGroup;

    /** 平均值 */
    @Excel(name = "平均值")
    private String avgValue;

    /** 最大值 */
    @Excel(name = "最大值")
    private String maxValue;

    /** 最小值 */
    @Excel(name = "最小值")
    private String minValue;

    /** 上规格 */
    @Excel(name = "上规格")
    private String usl;

    /** 目标值 */
    @Excel(name = "目标值")
    private String targetValue;

    /** 下规格 */
    @Excel(name = "下规格")
    private String lsl;

    /** 正sigma */
    @Excel(name = "正sigma")
    private String sigma;

    /** 负sigma */
    @Excel(name = "负sigma")
    private String sigmaF;

    /** 小数位数 */
    @Excel(name = "小数位数")
    private String xsCount;

    /** 数据组数 */
    @Excel(name = "数据组数")
    private String dataCount;

    /** 估算标准差方法 1标准差 2 极值差 3 合并标准差 */
    @Excel(name = "估算标准差方法 1标准差 2 极值差 3 合并标准差")
    private String types;

    /** 标准差值组内 */
    @Excel(name = "标准差值组内")
    private String stdev1;

    /** 标准差值整体 */
    @Excel(name = "标准差值整体")
    private String stdev2;

    /** 标准差值实测 */
    @Excel(name = "标准差值实测")
    private String stdev3;

    /** 工序内力指数组内 */
    @Excel(name = "工序内力指数组内")
    private String cpk1;

    /** 工序内力指数整体 */
    @Excel(name = "工序内力指数整体")
    private String cpk2;

    /** 工序内力指数实测 */
    @Excel(name = "工序内力指数实测")
    private String cpk3;

    /** 产品品质标准度组内 */
    @Excel(name = "产品品质标准度组内")
    private String cp1;

    /** 产品品质标准度整体 */
    @Excel(name = "产品品质标准度整体")
    private String cp2;

    /** 产品品质标准度实测 */
    @Excel(name = "产品品质标准度实测")
    private String cp3;

    /** 下规格工序能力组内 */
    @Excel(name = "下规格工序能力组内")
    private String cpl1;

    /** 下规格工序能力整体 */
    @Excel(name = "下规格工序能力整体")
    private String cpl2;

    /** 下规格工序能力实测 */
    @Excel(name = "下规格工序能力实测")
    private String cpl3;

    /** 上规格工序能力组内 */
    @Excel(name = "上规格工序能力组内")
    private String cpu1;

    /** 上规格工序能力整体 */
    @Excel(name = "上规格工序能力整体")
    private String cpu2;

    /** 上规格工序能力实测 */
    @Excel(name = "上规格工序能力实测")
    private String cpu3;

    /** 预测的低于下规格值的不合格品数组内 */
    @Excel(name = "预测的低于下规格值的不合格品数组内")
    private String ppmLsl1;

    /** 预测的低于下规格值的不合格品数整体 */
    @Excel(name = "预测的低于下规格值的不合格品数整体")
    private String ppmLsl2;

    /** 预测的低于下规格值的不合格品数实测 */
    @Excel(name = "预测的低于下规格值的不合格品数实测")
    private String ppmLsl3;

    /** 预测的超过上规格值的不合格品数组内 */
    @Excel(name = "预测的超过上规格值的不合格品数组内")
    private String ppmUls1;

    /** 预测的超过上规格值的不合格品数整体 */
    @Excel(name = "预测的超过上规格值的不合格品数整体")
    private String ppmUls2;

    /** 预测的超过上规格值的不合格品数实测 */
    @Excel(name = "预测的超过上规格值的不合格品数实测")
    private String ppmUls3;

    /** 预测的总的不合格品数组内 */
    @Excel(name = "预测的总的不合格品数组内")
    private String ppmTotle1;

    /** 预测的总的不合格品数组内 */
    @Excel(name = "预测的总的不合格品数组内")
    private String ppmTotle2;

    /** 预测的总的不合格品数组内 */
    @Excel(name = "预测的总的不合格品数组内")
    private String ppmTotle3;

    /** 制程准确度组内 */
    @Excel(name = "制程准确度组内")
    private String ca1;

    /** 制程准确度整体 */
    @Excel(name = "制程准确度整体")
    private String ca2;

    /** 制程准确度实测 */
    @Excel(name = "制程准确度实测")
    private String ca3;

    /** attr */
    @Excel(name = "attr")
    private String attr1;

    /** attr */
    @Excel(name = "attr")
    private String attr2;

    /** attr */
    @Excel(name = "attr")
    private String attr3;

    /** attr */
    @Excel(name = "attr")
    private String attr4;

    /** attr */
    @Excel(name = "attr")
    private String attr5;

    /** attr */
    @Excel(name = "attr")
    private String attr6;

    /** attr */
    @Excel(name = "attr")
    private String attr7;

    /** attr */
    @Excel(name = "attr")
    private String attr8;

    /** attr */
    @Excel(name = "attr")
    private String attr9;

    /** attr */
    @Excel(name = "attr")
    private String attr10;

    public void setId(Long id)
    {
        this.id = id;
    }

    public Long getId()
    {
        return id;
    }
    public void setData(String data)
    {
        this.data = data;
    }

    public String getData()
    {
        return data;
    }
    public void setDataSum(String dataSum)
    {
        this.dataSum = dataSum;
    }

    public String getDataSum()
    {
        return dataSum;
    }
    public void setSonGroup(String sonGroup)
    {
        this.sonGroup = sonGroup;
    }

    public String getSonGroup()
    {
        return sonGroup;
    }
    public void setAvgValue(String avgValue)
    {
        this.avgValue = avgValue;
    }

    public String getAvgValue()
    {
        return avgValue;
    }
    public void setMaxValue(String maxValue)
    {
        this.maxValue = maxValue;
    }

    public String getMaxValue()
    {
        return maxValue;
    }
    public void setMinValue(String minValue)
    {
        this.minValue = minValue;
    }

    public String getMinValue()
    {
        return minValue;
    }
    public void setUsl(String usl)
    {
        this.usl = usl;
    }

    public String getUsl()
    {
        return usl;
    }
    public void setTargetValue(String targetValue)
    {
        this.targetValue = targetValue;
    }

    public String getTargetValue()
    {
        return targetValue;
    }
    public void setLsl(String lsl)
    {
        this.lsl = lsl;
    }

    public String getLsl()
    {
        return lsl;
    }
    public void setSigma(String sigma)
    {
        this.sigma = sigma;
    }

    public String getSigma()
    {
        return sigma;
    }
    public void setSigmaF(String sigmaF)
    {
        this.sigmaF = sigmaF;
    }

    public String getSigmaF()
    {
        return sigmaF;
    }
    public void setXsCount(String xsCount)
    {
        this.xsCount = xsCount;
    }

    public String getXsCount()
    {
        return xsCount;
    }
    public void setDataCount(String dataCount)
    {
        this.dataCount = dataCount;
    }

    public String getDataCount()
    {
        return dataCount;
    }
    public void setTypes(String types)
    {
        this.types = types;
    }

    public String getTypes()
    {
        return types;
    }
    public void setStdev1(String stdev1)
    {
        this.stdev1 = stdev1;
    }

    public String getStdev1()
    {
        return stdev1;
    }
    public void setStdev2(String stdev2)
    {
        this.stdev2 = stdev2;
    }

    public String getStdev2()
    {
        return stdev2;
    }
    public void setStdev3(String stdev3)
    {
        this.stdev3 = stdev3;
    }

    public String getStdev3()
    {
        return stdev3;
    }
    public void setCpk1(String cpk1)
    {
        this.cpk1 = cpk1;
    }

    public String getCpk1()
    {
        return cpk1;
    }
    public void setCpk2(String cpk2)
    {
        this.cpk2 = cpk2;
    }

    public String getCpk2()
    {
        return cpk2;
    }
    public void setCpk3(String cpk3)
    {
        this.cpk3 = cpk3;
    }

    public String getCpk3()
    {
        return cpk3;
    }
    public void setCp1(String cp1)
    {
        this.cp1 = cp1;
    }

    public String getCp1()
    {
        return cp1;
    }
    public void setCp2(String cp2)
    {
        this.cp2 = cp2;
    }

    public String getCp2()
    {
        return cp2;
    }
    public void setCp3(String cp3)
    {
        this.cp3 = cp3;
    }

    public String getCp3()
    {
        return cp3;
    }
    public void setCpl1(String cpl1)
    {
        this.cpl1 = cpl1;
    }

    public String getCpl1()
    {
        return cpl1;
    }
    public void setCpl2(String cpl2)
    {
        this.cpl2 = cpl2;
    }

    public String getCpl2()
    {
        return cpl2;
    }
    public void setCpl3(String cpl3)
    {
        this.cpl3 = cpl3;
    }

    public String getCpl3()
    {
        return cpl3;
    }
    public void setCpu1(String cpu1)
    {
        this.cpu1 = cpu1;
    }

    public String getCpu1()
    {
        return cpu1;
    }
    public void setCpu2(String cpu2)
    {
        this.cpu2 = cpu2;
    }

    public String getCpu2()
    {
        return cpu2;
    }
    public void setCpu3(String cpu3)
    {
        this.cpu3 = cpu3;
    }

    public String getCpu3()
    {
        return cpu3;
    }
    public void setPpmLsl1(String ppmLsl1)
    {
        this.ppmLsl1 = ppmLsl1;
    }

    public String getPpmLsl1()
    {
        return ppmLsl1;
    }
    public void setPpmLsl2(String ppmLsl2)
    {
        this.ppmLsl2 = ppmLsl2;
    }

    public String getPpmLsl2()
    {
        return ppmLsl2;
    }
    public void setPpmLsl3(String ppmLsl3)
    {
        this.ppmLsl3 = ppmLsl3;
    }

    public String getPpmLsl3()
    {
        return ppmLsl3;
    }
    public void setPpmUls1(String ppmUls1)
    {
        this.ppmUls1 = ppmUls1;
    }

    public String getPpmUls1()
    {
        return ppmUls1;
    }
    public void setPpmUls2(String ppmUls2)
    {
        this.ppmUls2 = ppmUls2;
    }

    public String getPpmUls2()
    {
        return ppmUls2;
    }
    public void setPpmUls3(String ppmUls3)
    {
        this.ppmUls3 = ppmUls3;
    }

    public String getPpmUls3()
    {
        return ppmUls3;
    }
    public void setPpmTotle1(String ppmTotle1)
    {
        this.ppmTotle1 = ppmTotle1;
    }

    public String getPpmTotle1()
    {
        return ppmTotle1;
    }
    public void setPpmTotle2(String ppmTotle2)
    {
        this.ppmTotle2 = ppmTotle2;
    }

    public String getPpmTotle2()
    {
        return ppmTotle2;
    }
    public void setPpmTotle3(String ppmTotle3)
    {
        this.ppmTotle3 = ppmTotle3;
    }

    public String getPpmTotle3()
    {
        return ppmTotle3;
    }
    public void setCa1(String ca1)
    {
        this.ca1 = ca1;
    }

    public String getCa1()
    {
        return ca1;
    }
    public void setCa2(String ca2)
    {
        this.ca2 = ca2;
    }

    public String getCa2()
    {
        return ca2;
    }
    public void setCa3(String ca3)
    {
        this.ca3 = ca3;
    }

    public String getCa3()
    {
        return ca3;
    }
    public void setAttr1(String attr1)
    {
        this.attr1 = attr1;
    }

    public String getAttr1()
    {
        return attr1;
    }
    public void setAttr2(String attr2)
    {
        this.attr2 = attr2;
    }

    public String getAttr2()
    {
        return attr2;
    }
    public void setAttr3(String attr3)
    {
        this.attr3 = attr3;
    }

    public String getAttr3()
    {
        return attr3;
    }
    public void setAttr4(String attr4)
    {
        this.attr4 = attr4;
    }

    public String getAttr4()
    {
        return attr4;
    }
    public void setAttr5(String attr5)
    {
        this.attr5 = attr5;
    }

    public String getAttr5()
    {
        return attr5;
    }
    public void setAttr6(String attr6)
    {
        this.attr6 = attr6;
    }

    public String getAttr6()
    {
        return attr6;
    }
    public void setAttr7(String attr7)
    {
        this.attr7 = attr7;
    }

    public String getAttr7()
    {
        return attr7;
    }
    public void setAttr8(String attr8)
    {
        this.attr8 = attr8;
    }

    public String getAttr8()
    {
        return attr8;
    }
    public void setAttr9(String attr9)
    {
        this.attr9 = attr9;
    }

    public String getAttr9()
    {
        return attr9;
    }
    public void setAttr10(String attr10)
    {
        this.attr10 = attr10;
    }

    public String getAttr10()
    {
        return attr10;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
                .append("id", getId())
                .append("data", getData())
                .append("dataSum", getDataSum())
                .append("sonGroup", getSonGroup())
                .append("avgValue", getAvgValue())
                .append("maxValue", getMaxValue())
                .append("minValue", getMinValue())
                .append("usl", getUsl())
                .append("targetValue", getTargetValue())
                .append("lsl", getLsl())
                .append("sigma", getSigma())
                .append("sigmaF", getSigmaF())
                .append("xsCount", getXsCount())
                .append("dataCount", getDataCount())
                .append("types", getTypes())
                .append("stdev1", getStdev1())
                .append("stdev2", getStdev2())
                .append("stdev3", getStdev3())
                .append("cpk1", getCpk1())
                .append("cpk2", getCpk2())
                .append("cpk3", getCpk3())
                .append("cp1", getCp1())
                .append("cp2", getCp2())
                .append("cp3", getCp3())
                .append("cpl1", getCpl1())
                .append("cpl2", getCpl2())
                .append("cpl3", getCpl3())
                .append("cpu1", getCpu1())
                .append("cpu2", getCpu2())
                .append("cpu3", getCpu3())
                .append("ppmLsl1", getPpmLsl1())
                .append("ppmLsl2", getPpmLsl2())
                .append("ppmLsl3", getPpmLsl3())
                .append("ppmUls1", getPpmUls1())
                .append("ppmUls2", getPpmUls2())
                .append("ppmUls3", getPpmUls3())
                .append("ppmTotle1", getPpmTotle1())
                .append("ppmTotle2", getPpmTotle2())
                .append("ppmTotle3", getPpmTotle3())
                .append("ca1", getCa1())
                .append("ca2", getCa2())
                .append("ca3", getCa3())
                .append("attr1", getAttr1())
                .append("attr2", getAttr2())
                .append("attr3", getAttr3())
                .append("attr4", getAttr4())
                .append("attr5", getAttr5())
                .append("attr6", getAttr6())
                .append("attr7", getAttr7())
                .append("attr8", getAttr8())
                .append("attr9", getAttr9())
                .append("attr10", getAttr10())
                .append("createBy", getCreateBy())
                .append("createTime", getCreateTime())
                .append("updateBy", getUpdateBy())
                .append("updateTime", getUpdateTime())
                .toString();
    }
}

service

package com.ruoyi.system.service.cpk;



import com.ruoyi.system.domain.cpk.Cpk;

import java.util.List;

/**
 * cpk 计算Service接口
 *
 * @author ruoyi
 * @date 2023-10-03
 */
public interface ICpkService
{
    /**
     * 查询cpk 计算
     *
     * @param id cpk 计算主键
     * @return cpk 计算
     */
    public Cpk selectCpkById(Long id);

    /**
     * 查询cpk 计算列表
     *
     * @param cpk cpk 计算
     * @return cpk 计算集合
     */
    public List<Cpk> selectCpkList(Cpk cpk);

    /**
     * 新增cpk 计算
     *
     * @param cpk cpk 计算
     * @return 结果
     */
    public int insertCpk(Cpk cpk);

    /**
     * 修改cpk 计算
     *
     * @param cpk cpk 计算
     * @return 结果
     */
    public int updateCpk(Cpk cpk);

    /**
     * 批量删除cpk 计算
     *
     * @param ids 需要删除的cpk 计算主键集合
     * @return 结果
     */
    public int deleteCpkByIds(Long[] ids);

    /**
     * 删除cpk 计算信息
     *
     * @param id cpk 计算主键
     * @return 结果
     */
    public int deleteCpkById(Long id);

    Cpk sumCpk(Cpk cpk);
}

实现类 cpkServiceImpl.java

package com.ruoyi.system.service.impl.cpk;


import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.cpk.Cpk;
import com.ruoyi.system.mapper.cpk.CpkMapper;
import com.ruoyi.system.service.cpk.ICpkService;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * cpk 计算Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-03
 */
@Service
public class CpkServiceImpl implements ICpkService
{
    @Autowired
    private CpkMapper cpkMapper;

    /**
     * 查询cpk 计算
     *
     * @param id cpk 计算主键
     * @return cpk 计算
     */
    @Override
    public Cpk selectCpkById(Long id)
    {
        return cpkMapper.selectCpkById(id);
    }

    /**
     * 查询cpk 计算列表
     *
     * @param cpk cpk 计算
     * @return cpk 计算
     */
    @Override
    public List<Cpk> selectCpkList(Cpk cpk)
    {
        return cpkMapper.selectCpkList(cpk);
    }

    /**
     * 新增cpk 计算
     *
     * @param cpk cpk 计算
     * @return 结果
     */
    @Override
    public int insertCpk(Cpk cpk)
    {
        cpk.setCreateTime(DateUtils.getNowDate());
        cpk.setCreateBy(SecurityUtils.getUserId().toString());
        return cpkMapper.insertCpk(cpk);
    }

    /**
     * 修改cpk 计算
     *
     * @param cpk cpk 计算
     * @return 结果
     */
    @Override
    public int updateCpk(Cpk cpk)
    {
        cpk.setUpdateTime(DateUtils.getNowDate());
        cpk.setUpdateBy(SecurityUtils.getUserId().toString());
        return cpkMapper.updateCpk(cpk);
    }

    /**
     * 批量删除cpk 计算
     *
     * @param ids 需要删除的cpk 计算主键
     * @return 结果
     */
    @Override
    public int deleteCpkByIds(Long[] ids)
    {
        return cpkMapper.deleteCpkByIds(ids);
    }

    /**
     * 删除cpk 计算信息
     *
     * @param id cpk 计算主键
     * @return 结果
     */
    @Override
    public int deleteCpkById(Long id)
    {
        return cpkMapper.deleteCpkById(id);
    }


    @Override
    public Cpk sumCpk(Cpk cpk)
    {

        // 计算

        // 1、获取数据
        String data = cpk.getData();
        String[] split = data.split(",");

        cpk.setDataSum(split.length + "");

        // 2、最大值-最小值-平均值
        sumAvgValue(split,cpk);

        // 标准差
        double stdevValue = 0.0;

        // 小数位数
        int  decimalPlaces = Integer.valueOf(cpk.getXsCount());

        // 3、判断计算类型   1标准差 2 极值差 3 合并标准差
        if("1".equals(cpk.getTypes())){
            // 计算标准差
            stdevValue = calculateStandardDeviation(split) ;

        }else if ("2".equals(cpk.getTypes())){



        }else if ("3".equals(cpk.getTypes())){

        }

        double s = (stdevValue * 3) + Double.valueOf(cpk.getAvgValue());
        double v = Double.valueOf(cpk.getAvgValue()) - (stdevValue * 3);
        //cpk.setSigma((stdevValue * 3) +cpk.getAvgValue());
        //cpk.setSigmaF(Double.valueOf(cpk.getAvgValue()) - Double.valueOf((stdevValue * 3)) + "" );

        cpk.setSigma(String.format("%." + decimalPlaces + "f",s));
        cpk.setSigmaF(String.format("%." + decimalPlaces + "f", v));
        //cpk.setStdev1("组内");
        //cpk.setStdev2(stdevValue + "");
        cpk.setStdev2(String.format("%." + decimalPlaces + "f", stdevValue));
        cpk.setStdev3(0 + "");

        // 计算CPK整体
        double cpkValue = calculateCpk(Double.valueOf(cpk.getUsl()), Double.valueOf(cpk.getLsl()), Double.valueOf(cpk.getAvgValue()), stdevValue);
        //cpk.setCpk1("组内");
        cpk.setCpk2( String.format("%." + decimalPlaces + "f", cpkValue));
        cpk.setCpk3(0 + "");

        // 计算 cp 制程 精密度
        double cpValue = calculateCp(Double.valueOf(cpk.getUsl()), Double.valueOf(cpk.getLsl()), Double.valueOf(cpk.getAvgValue()), stdevValue);
        //cpk.setCp1("组内");
        cpk.setCp2(String.format("%." + decimalPlaces + "f", cpValue));
        cpk.setCp3(0 + "");

        //计算 CPL 相对于下限规格的工序能力
        double cplValue = calculateCpl(Double.valueOf(cpk.getAvgValue()), Double.valueOf(cpk.getLsl()), stdevValue);
        //cpk.setCpl1("组内");
        cpk.setCpl2(String.format("%." + decimalPlaces + "f", cplValue));
        cpk.setCpl3(0 + "");

        // 计算 CPU 相对于上限规格的工序能力
        double cpuValue = calculateCpu(Double.valueOf(cpk.getUsl()), Double.valueOf(cpk.getAvgValue()), stdevValue);
        //cpk.setCpu1("组内");
        //cpk.setCpu2(cpuValue +"");
        cpk.setCpu2(String.format("%." + decimalPlaces + "f", cpuValue) +"");
        cpk.setCpu3(0 + "");

        // 计算 PPM 的整体值
        double[][] convertedData = convertToDoubleArray(split);
        double ppmBelowLSL = calculatePPMBelowLSL(convertedData, Double.valueOf(cpk.getLsl()), Integer.valueOf(cpk.getDataSum()));
        double ppmAboveUSL = calculatePPMAboveUSL(convertedData, Double.valueOf(cpk.getUsl()), Integer.valueOf(cpk.getDataSum()));
        double ppmTotle = calculatePPMTotle(convertedData, Double.valueOf(cpk.getLsl()), Double.valueOf(cpk.getUsl()), Integer.valueOf(cpk.getDataSum()));
        double caValue = calculateCA(convertedData, Double.valueOf(cpk.getLsl()), Double.valueOf(cpk.getUsl()));

        cpk.setCa1(String.format("%." + decimalPlaces + "f", caValue) +"");
        cpk.setPpmLsl2(String.format("%." + decimalPlaces + "f", ppmBelowLSL) +"");
        cpk.setPpmUls2(String.format("%." + decimalPlaces + "f", ppmAboveUSL) +"");
        cpk.setPpmTotle2(String.format("%." + decimalPlaces + "f", ppmTotle) +"");

        System.out.println("PPM < LSL: " + ppmBelowLSL);
        System.out.println("PPM > USL: " + ppmAboveUSL);
        System.out.println("PPM TOTLE: " + ppmTotle);
        System.out.println("Ca值: " + caValue);


        // 计算 超上限和下限的 数量和占比
        analyzeData(split, Double.valueOf(cpk.getUsl()), Double.valueOf(cpk.getLsl()),cpk);

        cpk.setCreateTime(DateUtils.getNowDate());
        cpk.setCreateBy(SecurityUtils.getUserId().toString());
        int i = cpkMapper.insertCpk(cpk);
        return cpk;
    }

    /**
     * 计算 最大值-最小值-平均值
     * @param data
     */
    private void sumAvgValue(String[] data,Cpk cpk) {
        String[] strArray = data;
        double sum = 0;
        double min = Integer.MAX_VALUE;
        double max = Integer.MIN_VALUE;

        for (String str : strArray) {
            double num = Double.valueOf(str);
            sum += num;
            if (num < min) {
                min = num;
            }
            if (num > max) {
                max = num;
            }
        }

        double avg = (double) sum / strArray.length;

        cpk.setMaxValue(max + "");
        cpk.setMinValue(min + "");
        cpk.setAvgValue(avg + "");
        System.out.println("Min: " + min);
        System.out.println("Max: " + max);
        System.out.println("Avg: " + avg);
    }

    /**
     * 计算标准差
     * @param data
     * @return
     */
    public static double calculateStandardDeviation(String[] data) {
        DescriptiveStatistics stats = new DescriptiveStatistics();
        for (String num : data) {
            stats.addValue(Double.valueOf(num));
        }
        return stats.getStandardDeviation();
    }

    /**
     * 计算cpk
     * @param usl
     * @param lsl
     * @param mean
     * @param stdev
     * @return
     */
    public static double calculateCpk(double usl, double lsl, double mean, double stdev) {
        double upperCpk = (usl - mean) / (3 * stdev);
        double lowerCpk = (mean - lsl) / (3 * stdev);
        return Math.min(upperCpk, lowerCpk);
    }


    /**
     * 计算 cp 制程 精密度
     * @param usl
     * @param lsl
     * @param mean
     * @param stdev
     * @return
     */
    public static double calculateCp(double usl, double lsl, double mean, double stdev) {

        // 判断 是双边规格还是 单边规格
        if(usl !=0 && lsl !=0){
            return (usl - lsl) / (6 * stdev);
        }else{
            // 判断仅上限  还是 仅下限
            if(usl == 0){
                return (usl - mean) / (3 * stdev);
            }else{
                return (mean - lsl) / (3 * stdev);
            }
        }
    }

    // 计算 CPL 相对于下限规格的工序能力
    public static double calculateCpl(double mean, double lsl, double stdev) {
        return (mean - lsl) / (3 * stdev);
    }

    // 计算 CPL 相对于上限规格的工序能力
    public static double calculateCpu(double usl, double mean, double stdev) {
        return (usl - mean) / (3 * stdev);
    }


    // 计算 超上限和显现的 数量和占比
    public static void analyzeData(String[] dataStr, double upperLimit, double lowerLimit,Cpk cpk) {
        double[] data = new double[dataStr.length];
        for (int i = 0; i < dataStr.length; i++) {
            data[i] = Double.parseDouble(dataStr[i]);
        }

        int countAboveUpperLimit = 0;
        int countBelowLowerLimit = 0;
        int countOutliers = 0;

        for (double value : data) {
            if (value > upperLimit) {
                countAboveUpperLimit++;
            }
            if (value < lowerLimit) {
                countBelowLowerLimit++;
            }
        }

        countOutliers = countAboveUpperLimit + countBelowLowerLimit;

        int totalCount = data.length;

        double percentageAboveUpperLimit = (double) countAboveUpperLimit / totalCount * 100;
        double percentageBelowLowerLimit = (double) countBelowLowerLimit / totalCount * 100;
        double percentageOutliers = (double) countOutliers / totalCount * 100;

        System.out.println("超过上限 " + upperLimit + " 的数量: " + countAboveUpperLimit);
        System.out.println("低于下限 " + lowerLimit + " 的数量: " + countBelowLowerLimit);
        System.out.println("超规格的数量: " + countOutliers);
        System.out.println("超过上限 " + upperLimit + " 的数量占总样本数的百分比: " + percentageAboveUpperLimit + "%");
        System.out.println("低于下限 " + lowerLimit + " 的数量占总样本数的百分比: " + percentageBelowLowerLimit + "%");
        System.out.println("超规格的数量占总样本数的百分比: " + percentageOutliers + "%");

        cpk.setAttr1(countAboveUpperLimit + "_" + percentageAboveUpperLimit);
        cpk.setAttr2(countBelowLowerLimit + "_" + percentageBelowLowerLimit);
        cpk.setAttr3(countOutliers + "_" + percentageOutliers);

        // 计算 PPM < LSL
        //cpk.setPpmLsl2("暂无");
        cpk.setPpmLsl3((Double.valueOf(percentageBelowLowerLimit * 10000) + ""));

        // 计算 PPM > USL
        //cpk.setPpmUls2("暂无");
        cpk.setPpmUls3((Double.valueOf(percentageAboveUpperLimit * 10000) + ""));

        // 计算 PPM Totle
        //cpk.setPpmTotle2("暂无");
        cpk.setPpmTotle3((Double.valueOf(percentageOutliers * 10000) + ""));


        //cpk.setAttr1(countAboveUpperLimit +"");
        //cpk.setAttr2(countBelowLowerLimit +"");
        //cpk.setAttr3(countOutliers +"");
    }


    public static double[][] convertToDoubleArray(String[] data) {
        int dataSize = data.length / 2 * 2; // 对数据数组长度进行偶数化处理
        double[][] convertedData = new double[dataSize / 2][2];

        for (int i = 0; i < dataSize; i += 2) {
            convertedData[i / 2][0] = Double.parseDouble(data[i]);
            convertedData[i / 2][1] = Double.parseDouble(data[i + 1]);
        }

        return convertedData;
    }

    public static double calculatePPMBelowLSL(double[][] data, double lsl, int totalSamples) {
        int count = 0;

        for (double[] dataPoint : data) {
            for (double value : dataPoint) {
                if (value < lsl) {
                    count++;
                }
            }
        }

        double ppmBelowLSL = (int) ((count / (double) totalSamples) * 1000000);
        return ppmBelowLSL;
    }

    public static int calculatePPMAboveUSL(double[][] data, double usl, int totalSamples) {
        int count = 0;

        for (double[] dataPoint : data) {
            for (double value : dataPoint) {
                if (value > usl) {
                    count++;
                }
            }
        }

        int ppmAboveUSL = (int) ((count / (double) totalSamples) * 1000000);
        return ppmAboveUSL;
    }

    public static int calculatePPMTotle(double[][] data, double lsl, double usl, int totalSamples) {
        int count = 0;

        for (double[] dataPoint : data) {
            for (double value : dataPoint) {
                if (value < lsl || value > usl) {
                    count++;
                }
            }
        }

        int ppmTotle = (int) ((count / (double) (totalSamples * 2)) * 1000000);
        return ppmTotle;
    }

    public static double calculateCA(double[][] data, double lsl, double usl) {
        double sum = 0.0;

        for (double[] dataPoint : data) {
            for (double value : dataPoint) {
                double deviation = Math.max(value - usl, lsl - value);
                sum += deviation * deviation;
            }
        }

        double caValue = Math.sqrt(sum / (data.length * 2));
        return caValue;
    }

}

cpkmMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.cpk.CpkMapper">

    <resultMap type="Cpk" id="CpkResult">
        <result property="id"    column="id"    />
        <result property="data"    column="data"    />
        <result property="dataSum"    column="data_sum"    />
        <result property="sonGroup"    column="son_group"    />
        <result property="avgValue"    column="avg_value"    />
        <result property="maxValue"    column="max_value"    />
        <result property="minValue"    column="min_value"    />
        <result property="usl"    column="usl"    />
        <result property="targetValue"    column="target_value"    />
        <result property="lsl"    column="lsl"    />
        <result property="sigma"    column="sigma"    />
        <result property="sigma"    column="sigma_"    />
        <result property="xsCount"    column="xs_count"    />
        <result property="dataCount"    column="data_count"    />
        <result property="types"    column="types"    />
        <result property="stdev1"    column="stdev1"    />
        <result property="stdev2"    column="stdev2"    />
        <result property="stdev3"    column="stdev3"    />
        <result property="cpk1"    column="cpk1"    />
        <result property="cpk2"    column="cpk2"    />
        <result property="cpk3"    column="cpk3"    />
        <result property="cp1"    column="cp1"    />
        <result property="cp2"    column="cp2"    />
        <result property="cp3"    column="cp3"    />
        <result property="cpl1"    column="cpl1"    />
        <result property="cpl2"    column="cpl2"    />
        <result property="cpl3"    column="cpl3"    />
        <result property="cpu1"    column="cpu1"    />
        <result property="cpu2"    column="cpu2"    />
        <result property="cpu3"    column="cpu3"    />
        <result property="ppmLsl1"    column="ppm_lsl1"    />
        <result property="ppmLsl2"    column="ppm_lsl2"    />
        <result property="ppmLsl3"    column="ppm_lsl3"    />
        <result property="ppmUls1"    column="ppm_uls1"    />
        <result property="ppmUls2"    column="ppm_uls2"    />
        <result property="ppmUls3"    column="ppm_uls3"    />
        <result property="ppmTotle1"    column="ppm_totle1"    />
        <result property="ppmTotle2"    column="ppm_totle2"    />
        <result property="ppmTotle3"    column="ppm_totle3"    />
        <result property="ca1"    column="ca1"    />
        <result property="ca2"    column="ca2"    />
        <result property="ca3"    column="ca3"    />
        <result property="attr1"    column="attr1"    />
        <result property="attr2"    column="attr2"    />
        <result property="attr3"    column="attr3"    />
        <result property="attr4"    column="attr4"    />
        <result property="attr5"    column="attr5"    />
        <result property="attr6"    column="attr6"    />
        <result property="attr7"    column="attr7"    />
        <result property="attr8"    column="attr8"    />
        <result property="attr9"    column="attr9"    />
        <result property="attr10"    column="attr10"    />
        <result property="createBy"    column="create_by"    />
        <result property="createTime"    column="create_time"    />
        <result property="updateBy"    column="update_by"    />
        <result property="updateTime"    column="update_time"    />
    </resultMap>

    <sql id="selectCpkVo">
        select id, data, data_sum, son_group, avg_value, max_value, min_value, usl, target_value, lsl, sigma, sigma_, xs_count, data_count, types, stdev1, stdev2, stdev3, cpk1, cpk2, cpk3, cp1, cp2, cp3, cpl1, cpl2, cpl3, cpu1, cpu2, cpu3, ppm_lsl1, ppm_lsl2, ppm_lsl3, ppm_uls1, ppm_uls2, ppm_uls3, ppm_totle1, ppm_totle2, ppm_totle3, ca1, ca2, ca3, attr1, attr2, attr3, attr4, attr5, attr6, attr7, attr8, attr9, attr10, create_by, create_time, update_by, update_time from cmc_cpk
    </sql>

    <select id="selectCpkList" parameterType="Cpk" resultMap="CpkResult">
        <include refid="selectCpkVo"/>
        <where>
            <if test="id != null "> and id = #{id}</if>
            <if test="data != null  and data != ''"> and data = #{data}</if>
            <if test="dataSum != null  and dataSum != ''"> and data_sum = #{dataSum}</if>
            <if test="sonGroup != null  and sonGroup != ''"> and son_group = #{sonGroup}</if>
            <if test="avgValue != null  and avgValue != ''"> and avg_value = #{avgValue}</if>
            <if test="maxValue != null  and maxValue != ''"> and max_value = #{maxValue}</if>
            <if test="minValue != null  and minValue != ''"> and min_value = #{minValue}</if>
            <if test="usl != null  and usl != ''"> and usl = #{usl}</if>
            <if test="targetValue != null  and targetValue != ''"> and target_value = #{targetValue}</if>
            <if test="lsl != null  and lsl != ''"> and lsl = #{lsl}</if>
            <if test="sigma != null  and sigma != ''"> and sigma = #{sigma}</if>
            <if test="sigma != null  and sigma != ''"> and sigma_ = #{sigma}</if>
            <if test="xsCount != null  and xsCount != ''"> and xs_count = #{xsCount}</if>
            <if test="dataCount != null  and dataCount != ''"> and data_count = #{dataCount}</if>
            <if test="types != null  and types != ''"> and types = #{types}</if>
            <if test="stdev1 != null  and stdev1 != ''"> and stdev1 = #{stdev1}</if>
            <if test="stdev2 != null  and stdev2 != ''"> and stdev2 = #{stdev2}</if>
            <if test="stdev3 != null  and stdev3 != ''"> and stdev3 = #{stdev3}</if>
            <if test="cpk1 != null  and cpk1 != ''"> and cpk1 = #{cpk1}</if>
            <if test="cpk2 != null  and cpk2 != ''"> and cpk2 = #{cpk2}</if>
            <if test="cpk3 != null  and cpk3 != ''"> and cpk3 = #{cpk3}</if>
            <if test="cp1 != null  and cp1 != ''"> and cp1 = #{cp1}</if>
            <if test="cp2 != null  and cp2 != ''"> and cp2 = #{cp2}</if>
            <if test="cp3 != null  and cp3 != ''"> and cp3 = #{cp3}</if>
            <if test="cpl1 != null  and cpl1 != ''"> and cpl1 = #{cpl1}</if>
            <if test="cpl2 != null  and cpl2 != ''"> and cpl2 = #{cpl2}</if>
            <if test="cpl3 != null  and cpl3 != ''"> and cpl3 = #{cpl3}</if>
            <if test="cpu1 != null  and cpu1 != ''"> and cpu1 = #{cpu1}</if>
            <if test="cpu2 != null  and cpu2 != ''"> and cpu2 = #{cpu2}</if>
            <if test="cpu3 != null  and cpu3 != ''"> and cpu3 = #{cpu3}</if>
            <if test="ppmLsl1 != null  and ppmLsl1 != ''"> and ppm_lsl1 = #{ppmLsl1}</if>
            <if test="ppmLsl2 != null  and ppmLsl2 != ''"> and ppm_lsl2 = #{ppmLsl2}</if>
            <if test="ppmLsl3 != null  and ppmLsl3 != ''"> and ppm_lsl3 = #{ppmLsl3}</if>
            <if test="ppmUls1 != null  and ppmUls1 != ''"> and ppm_uls1 = #{ppmUls1}</if>
            <if test="ppmUls2 != null  and ppmUls2 != ''"> and ppm_uls2 = #{ppmUls2}</if>
            <if test="ppmUls3 != null  and ppmUls3 != ''"> and ppm_uls3 = #{ppmUls3}</if>
            <if test="ppmTotle1 != null  and ppmTotle1 != ''"> and ppm_totle1 = #{ppmTotle1}</if>
            <if test="ppmTotle2 != null  and ppmTotle2 != ''"> and ppm_totle2 = #{ppmTotle2}</if>
            <if test="ppmTotle3 != null  and ppmTotle3 != ''"> and ppm_totle3 = #{ppmTotle3}</if>
            <if test="ca1 != null  and ca1 != ''"> and ca1 = #{ca1}</if>
            <if test="ca2 != null  and ca2 != ''"> and ca2 = #{ca2}</if>
            <if test="ca3 != null  and ca3 != ''"> and ca3 = #{ca3}</if>
            <if test="attr1 != null  and attr1 != ''"> and attr1 = #{attr1}</if>
            <if test="attr2 != null  and attr2 != ''"> and attr2 = #{attr2}</if>
            <if test="attr3 != null  and attr3 != ''"> and attr3 = #{attr3}</if>
            <if test="attr4 != null  and attr4 != ''"> and attr4 = #{attr4}</if>
            <if test="attr5 != null  and attr5 != ''"> and attr5 = #{attr5}</if>
            <if test="attr6 != null  and attr6 != ''"> and attr6 = #{attr6}</if>
            <if test="attr7 != null  and attr7 != ''"> and attr7 = #{attr7}</if>
            <if test="attr8 != null  and attr8 != ''"> and attr8 = #{attr8}</if>
            <if test="attr9 != null  and attr9 != ''"> and attr9 = #{attr9}</if>
            <if test="attr10 != null  and attr10 != ''"> and attr10 = #{attr10}</if>
            <if test="createBy != null  and createBy != ''"> and create_by = #{createBy}</if>
            <if test="updateBy != null  and updateBy != ''"> and update_by = #{updateBy}</if>
        </where>
    </select>

    <select id="selectCpkById" parameterType="Long" resultMap="CpkResult">
        <include refid="selectCpkVo"/>
        where id = #{id}
    </select>

    <insert id="insertCpk" parameterType="Cpk" useGeneratedKeys="true" keyProperty="id">
        insert into cmc_cpk
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="data != null">data,</if>
            <if test="dataSum != null">data_sum,</if>
            <if test="sonGroup != null">son_group,</if>
            <if test="avgValue != null">avg_value,</if>
            <if test="maxValue != null">max_value,</if>
            <if test="minValue != null">min_value,</if>
            <if test="usl != null">usl,</if>
            <if test="targetValue != null">target_value,</if>
            <if test="lsl != null">lsl,</if>
            <if test="sigma != null">sigma,</if>
            <if test="sigma != null">sigma_,</if>
            <if test="xsCount != null">xs_count,</if>
            <if test="dataCount != null">data_count,</if>
            <if test="types != null">types,</if>
            <if test="stdev1 != null">stdev1,</if>
            <if test="stdev2 != null">stdev2,</if>
            <if test="stdev3 != null">stdev3,</if>
            <if test="cpk1 != null">cpk1,</if>
            <if test="cpk2 != null">cpk2,</if>
            <if test="cpk3 != null">cpk3,</if>
            <if test="cp1 != null">cp1,</if>
            <if test="cp2 != null">cp2,</if>
            <if test="cp3 != null">cp3,</if>
            <if test="cpl1 != null">cpl1,</if>
            <if test="cpl2 != null">cpl2,</if>
            <if test="cpl3 != null">cpl3,</if>
            <if test="cpu1 != null">cpu1,</if>
            <if test="cpu2 != null">cpu2,</if>
            <if test="cpu3 != null">cpu3,</if>
            <if test="ppmLsl1 != null">ppm_lsl1,</if>
            <if test="ppmLsl2 != null">ppm_lsl2,</if>
            <if test="ppmLsl3 != null">ppm_lsl3,</if>
            <if test="ppmUls1 != null">ppm_uls1,</if>
            <if test="ppmUls2 != null">ppm_uls2,</if>
            <if test="ppmUls3 != null">ppm_uls3,</if>
            <if test="ppmTotle1 != null">ppm_totle1,</if>
            <if test="ppmTotle2 != null">ppm_totle2,</if>
            <if test="ppmTotle3 != null">ppm_totle3,</if>
            <if test="ca1 != null">ca1,</if>
            <if test="ca2 != null">ca2,</if>
            <if test="ca3 != null">ca3,</if>
            <if test="attr1 != null">attr1,</if>
            <if test="attr2 != null">attr2,</if>
            <if test="attr3 != null">attr3,</if>
            <if test="attr4 != null">attr4,</if>
            <if test="attr5 != null">attr5,</if>
            <if test="attr6 != null">attr6,</if>
            <if test="attr7 != null">attr7,</if>
            <if test="attr8 != null">attr8,</if>
            <if test="attr9 != null">attr9,</if>
            <if test="attr10 != null">attr10,</if>
            <if test="createBy != null">create_by,</if>
            <if test="createTime != null">create_time,</if>
            <if test="updateBy != null">update_by,</if>
            <if test="updateTime != null">update_time,</if>
         </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="data != null">#{data},</if>
            <if test="dataSum != null">#{dataSum},</if>
            <if test="sonGroup != null">#{sonGroup},</if>
            <if test="avgValue != null">#{avgValue},</if>
            <if test="maxValue != null">#{maxValue},</if>
            <if test="minValue != null">#{minValue},</if>
            <if test="usl != null">#{usl},</if>
            <if test="targetValue != null">#{targetValue},</if>
            <if test="lsl != null">#{lsl},</if>
            <if test="sigma != null">#{sigma},</if>
            <if test="sigma != null">#{sigma},</if>
            <if test="xsCount != null">#{xsCount},</if>
            <if test="dataCount != null">#{dataCount},</if>
            <if test="types != null">#{types},</if>
            <if test="stdev1 != null">#{stdev1},</if>
            <if test="stdev2 != null">#{stdev2},</if>
            <if test="stdev3 != null">#{stdev3},</if>
            <if test="cpk1 != null">#{cpk1},</if>
            <if test="cpk2 != null">#{cpk2},</if>
            <if test="cpk3 != null">#{cpk3},</if>
            <if test="cp1 != null">#{cp1},</if>
            <if test="cp2 != null">#{cp2},</if>
            <if test="cp3 != null">#{cp3},</if>
            <if test="cpl1 != null">#{cpl1},</if>
            <if test="cpl2 != null">#{cpl2},</if>
            <if test="cpl3 != null">#{cpl3},</if>
            <if test="cpu1 != null">#{cpu1},</if>
            <if test="cpu2 != null">#{cpu2},</if>
            <if test="cpu3 != null">#{cpu3},</if>
            <if test="ppmLsl1 != null">#{ppmLsl1},</if>
            <if test="ppmLsl2 != null">#{ppmLsl2},</if>
            <if test="ppmLsl3 != null">#{ppmLsl3},</if>
            <if test="ppmUls1 != null">#{ppmUls1},</if>
            <if test="ppmUls2 != null">#{ppmUls2},</if>
            <if test="ppmUls3 != null">#{ppmUls3},</if>
            <if test="ppmTotle1 != null">#{ppmTotle1},</if>
            <if test="ppmTotle2 != null">#{ppmTotle2},</if>
            <if test="ppmTotle3 != null">#{ppmTotle3},</if>
            <if test="ca1 != null">#{ca1},</if>
            <if test="ca2 != null">#{ca2},</if>
            <if test="ca3 != null">#{ca3},</if>
            <if test="attr1 != null">#{attr1},</if>
            <if test="attr2 != null">#{attr2},</if>
            <if test="attr3 != null">#{attr3},</if>
            <if test="attr4 != null">#{attr4},</if>
            <if test="attr5 != null">#{attr5},</if>
            <if test="attr6 != null">#{attr6},</if>
            <if test="attr7 != null">#{attr7},</if>
            <if test="attr8 != null">#{attr8},</if>
            <if test="attr9 != null">#{attr9},</if>
            <if test="attr10 != null">#{attr10},</if>
            <if test="createBy != null">#{createBy},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateBy != null">#{updateBy},</if>
            <if test="updateTime != null">#{updateTime},</if>
         </trim>
    </insert>

    <update id="updateCpk" parameterType="Cpk">
        update cmc_cpk
        <trim prefix="SET" suffixOverrides=",">
            <if test="data != null">data = #{data},</if>
            <if test="dataSum != null">data_sum = #{dataSum},</if>
            <if test="sonGroup != null">son_group = #{sonGroup},</if>
            <if test="avgValue != null">avg_value = #{avgValue},</if>
            <if test="maxValue != null">max_value = #{maxValue},</if>
            <if test="minValue != null">min_value = #{minValue},</if>
            <if test="usl != null">usl = #{usl},</if>
            <if test="targetValue != null">target_value = #{targetValue},</if>
            <if test="lsl != null">lsl = #{lsl},</if>
            <if test="sigma != null">sigma = #{sigma},</if>
            <if test="sigma != null">sigma_ = #{sigma},</if>
            <if test="xsCount != null">xs_count = #{xsCount},</if>
            <if test="dataCount != null">data_count = #{dataCount},</if>
            <if test="types != null">types = #{types},</if>
            <if test="stdev1 != null">stdev1 = #{stdev1},</if>
            <if test="stdev2 != null">stdev2 = #{stdev2},</if>
            <if test="stdev3 != null">stdev3 = #{stdev3},</if>
            <if test="cpk1 != null">cpk1 = #{cpk1},</if>
            <if test="cpk2 != null">cpk2 = #{cpk2},</if>
            <if test="cpk3 != null">cpk3 = #{cpk3},</if>
            <if test="cp1 != null">cp1 = #{cp1},</if>
            <if test="cp2 != null">cp2 = #{cp2},</if>
            <if test="cp3 != null">cp3 = #{cp3},</if>
            <if test="cpl1 != null">cpl1 = #{cpl1},</if>
            <if test="cpl2 != null">cpl2 = #{cpl2},</if>
            <if test="cpl3 != null">cpl3 = #{cpl3},</if>
            <if test="cpu1 != null">cpu1 = #{cpu1},</if>
            <if test="cpu2 != null">cpu2 = #{cpu2},</if>
            <if test="cpu3 != null">cpu3 = #{cpu3},</if>
            <if test="ppmLsl1 != null">ppm_lsl1 = #{ppmLsl1},</if>
            <if test="ppmLsl2 != null">ppm_lsl2 = #{ppmLsl2},</if>
            <if test="ppmLsl3 != null">ppm_lsl3 = #{ppmLsl3},</if>
            <if test="ppmUls1 != null">ppm_uls1 = #{ppmUls1},</if>
            <if test="ppmUls2 != null">ppm_uls2 = #{ppmUls2},</if>
            <if test="ppmUls3 != null">ppm_uls3 = #{ppmUls3},</if>
            <if test="ppmTotle1 != null">ppm_totle1 = #{ppmTotle1},</if>
            <if test="ppmTotle2 != null">ppm_totle2 = #{ppmTotle2},</if>
            <if test="ppmTotle3 != null">ppm_totle3 = #{ppmTotle3},</if>
            <if test="ca1 != null">ca1 = #{ca1},</if>
            <if test="ca2 != null">ca2 = #{ca2},</if>
            <if test="ca3 != null">ca3 = #{ca3},</if>
            <if test="attr1 != null">attr1 = #{attr1},</if>
            <if test="attr2 != null">attr2 = #{attr2},</if>
            <if test="attr3 != null">attr3 = #{attr3},</if>
            <if test="attr4 != null">attr4 = #{attr4},</if>
            <if test="attr5 != null">attr5 = #{attr5},</if>
            <if test="attr6 != null">attr6 = #{attr6},</if>
            <if test="attr7 != null">attr7 = #{attr7},</if>
            <if test="attr8 != null">attr8 = #{attr8},</if>
            <if test="attr9 != null">attr9 = #{attr9},</if>
            <if test="attr10 != null">attr10 = #{attr10},</if>
            <if test="createBy != null">create_by = #{createBy},</if>
            <if test="createTime != null">create_time = #{createTime},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
        </trim>
        where id = #{id}
    </update>

    <delete id="deleteCpkById" parameterType="Long">
        delete from cmc_cpk where id = #{id}
    </delete>

    <delete id="deleteCpkByIds" parameterType="String">
        delete from cmc_cpk where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>