效果图:
前端代码:
父组件
<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>