factory_web/src/views/enm_report/quality.vue

528 lines
25 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-header>
<div class="left-panel">
<el-select
v-model="query.belong_dept"
placeholder="车间"
clearable
@change="deptChange"
class="headerSearch"
>
<el-option
v-for="item in deptOptions"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
<el-select
v-model="query.type"
placeholder="查询类型"
clearable
class="headerSearch"
@change="typeCange"
>
<el-option
v-for="item in options"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
<el-date-picker
v-model="query.year"
type="year"
value-format="YYYY"
format="YYYY"
placeholder="年份"
class="headerSearch"
v-if="query.type==1"
/>
<el-date-picker
v-model="query.month"
type="month"
value-format="YYYY-MM"
format="YYYY-MM"
placeholder="月份"
class="headerSearch"
v-if="query.type==0"
/>
<el-button
type="primary"
icon="el-icon-search"
@click="getTableData"
></el-button>
<el-button
type="primary"
@click="exportExcel()"
:loading = "exportLoading"
v-auth="'export_excel'"
>导出xlsx
</el-button>
<el-button
type="primary"
@click="handlePrint"
>打印
</el-button>
</div>
</el-header>
<el-card style="margin-top:5px">
<div class="tableContainer">
<table border="1" cellspacing="0" :key="timeStamp" id="myTable" class="myTable">
<thead class="myTableHead">
<tr>
<th rowspan="41">日期</th>
<th :colspan="header4.length">{{tableName}}</th>
</tr>
<tr>
<th :colspan="item2.lengths*4" v-for="(item2,index) in header2Obj" :key="index">{{ item2.name }}</th>
</tr>
<tr>
<th colspan="4" v-for="item3 in header3" :key="item3">{{item3}}</th>
</tr>
<tr>
<th v-for="item4 in header4" :key="item4">{{item4}}</th>
</tr>
</thead>
<tr v-for="(row, rowIndex) in tableDatas3" :key="rowIndex">
<td
v-for="(cell, cellIndex) in row"
:key="cellIndex"
:class="getCellClass(cell, cellIndex)"
class="numCell"
@click="handleCellClick(cell, rowIndex, cellIndex)"
>
{{ cell }}
</td>
</tr>
</table>
</div>
<el-dialog
title="设置合格率的阈值"
v-model="dialogVisible"
width="30%"
@close="resetDialog"
>
<div>
<label>当前阈值:</label>
<el-input v-model="currentThreshold" placeholder="请输入合格率阈值" style="width: 200px;"></el-input>
</div>
<template #footer>
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="updateThreshold"> </el-button>
</template>
</el-dialog>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
timeStamp:0,
query:{
type:0,
year:'',
month:'',
search_type:'',
},
options:[
{id:0,name:'日报表'},
{id:1,name:'月报表'},
],
titleLength:1,
mgroupOptions:[],
currentThreshold: 80, // 当前编辑的阈值
tableTime:'',
deptName:'',
typeName:'质检日报表',
tableName:'',
// tableDatas:[
// ['原料车间','辅料','细度', , , , , , ],
// ['原料车间','辅料','Fe2O3', , , , , , ],
// ['原料车间','辅料','水分', , , , , , ],
// ['原料车间','干混生料','细度', , , , , , ],
// ['原料车间','干混生料','Fe2O3', , , , , , ],
// ['原料车间','干混生料','水分', , , , , , ],
// ['原料车间','干混生料','CaO', , , , , , ],
// ['烧成车间','入窑生料','CaO', , , , , , ],
// ['烧成车间','入窑生料','Fe2O3', , , , , , ],
// ['烧成车间','入窑生料','细度'],
// ['烧成车间','入窑生料','水分'],
// ['烧成车间','熟料','立升重'],
// ['烧成车间','熟料','f-CaO'],
// ['烧成车间','煤粉','细度'],
// ['烧成车间','煤粉','水分'],
// ['水泥车间','出磨水泥','比表面积'],
// ['水泥车间','出磨水泥','SO3'],
// ['水泥车间','出磨水泥','掺量'],
// ],
tableDatas3:[],
exportLoading:false,
header2:[],
header3:[],
header4:[],
tableData:[],
header2Obj:[],
deptOptions:[],
dialogVisible: false, // 控制对话框显示
currentColumnIndex: null, // 当前编辑的列索引
// thresholds: {}, // 存储每列的阈值key 为列索引
thresholdobj:{},
materialTestItemMap:{},
currentMaterialNameClass: '',
currentMaterialName: '', // 当前物料名称
currentTestItemName: '', // 当前检测项名称
currentTestItemNameClass: '', // 当前检测项名称
};
},
mounted() {
var myDate = new Date();
let month = myDate.getMonth()+1;
let days = myDate.getDate()-1;
if(month<10){
month = '0'+month;
}
if(days<10){
days = '0'+days;
}
this.query.month = myDate.getFullYear()+'-'+month
this.query.day = myDate.getFullYear()+'-'+month+'-'+days;
this.getGroup();
},
methods: {
typeCange(value){
let that = this;
if(value==1){
this.typeName = '质检日报表'
}else if(value==0){
this.typeName = '质检月报表'
}
that.tableName = that.deptName+that.typeName;
},
updateThreshold() {
const num = parseFloat(this.currentThreshold);
if (!isNaN(num)){
const key = `${this.currentMaterialName}-${this.currentTestItemName}`;
const mapEntry = this.materialTestItemMap[key];
if (!mapEntry) {
return;
}
const payload = {
material_id: mapEntry.material_id,
testitem_id: mapEntry.testitem_id,
rate_pass_t: num,
update_start_time: mapEntry.update_start_time,
update_end_time: mapEntry.update_end_time,
};
this.$API.qm.updateQuastatGoal.post(payload)
.then((res) => {
this.$message.success("阈值更新成功");
// this.thresholds[this.currentColumnIndex] = res.rate_pass_t; // 更新本地阈值
this.dialogVisible = false; // 关闭对话框
})
.catch((error) => {
this.$message.error("阈值更新失败:" + error.message);
});
}else {
this.$message.error("请输入有效的阈值例如80%");
}
},
// 关闭对话框时重置状态
resetDialog() {
this.currentColumnIndex = null;
this.currentThreshold = "";
},
// 动态样式计算
getCellClass(cell, cellIndex) {
let that = this;
if (typeof cell === 'string' && cell.includes('%')) {
// 假设合格率在每组数据的第四列
const cellValue = String(cell);
const value = parseFloat(cellValue.replace("%", ""));
this.currentColumnIndex = cellIndex;
const header4Index = cellIndex - 1; // 假设第 0 列是日期列
const header3Index = Math.floor(header4Index / 4);
let cumulativeLength = 0;
let header2Index = -1;
for (let i = 0; i < this.header2Obj.length; i++) {
cumulativeLength += this.header2Obj[i].lengths * 4;
if (header4Index < cumulativeLength) {
header2Index = i;
break;
}
}
if (header2Index !== -1 && header3Index !== -1){
that.currentMaterialNameClass = this.header2Obj[header2Index].name; // header2Obj
that.currentTestItemNameClass = this.header3[header3Index]; // header3
}else {
this.currentMaterialNameClass = '';
this.currentTestItemNameClass = '';
}
const keyName = `${that.currentMaterialNameClass}-${that.currentTestItemNameClass}`;
const rate_g = that.thresholdobj[keyName] || 0;
if (rate_g >= value) {
return 'red-text';
} else {
return 'green-text';
}
}
return "";
},
deptChange(e){
let that = this;
that.deptOptions.forEach(item=>{
if(item.id==e){
that.deptName = item.name;
that.tableName = item.name+that.typeName;
}
})
},
getGroup() {
let that = this;
that.$API.system.dept.list.req({ page_size: 3 , type:'dept'}).then(res=>{
that.deptOptions = res.results;
that.deptName = res.results[0].name;
that.tableName =that.deptName+that.typeName;
that.query.belong_dept = res.results[0].id;
this.getTableData();
});
},
handleCellClick(cell, rowIndex, cellIndex){
let that = this;
this.currentColumnIndex = cellIndex;
const header4Index = cellIndex - 1 ; // 假设第 0 列是日期列
const header3Index = Math.floor(header4Index / 4) ;
let cumulativeLength = 0;
let header2Index = -1;
// 根据每个物料有多少个检测项,计算检测项目开始结束索引是否在当前列中
for (let i = 0; i < this.header2Obj.length; i++) {
cumulativeLength += this.header2Obj[i].lengths * 4;
if (header4Index < cumulativeLength) {
header2Index = i;
break;
}
}
if (header2Index !== -1 && header3Index !== -1){
that.currentMaterialName = this.header2Obj[header2Index].name; // header2Obj
that.currentTestItemName = this.header3[header3Index]; // header3
}else {
this.currentMaterialName = '';
this.currentTestItemName = '';
}
const keyName = `${that.currentMaterialName}-${that.currentTestItemName}`;
this.currentThreshold = that.thresholdobj[keyName] || 0;
this.dialogVisible = true;
},
getTableData(){
let that = this;
that.tableDatas3 = [];
that.materialTestItemMap = {};
that.header3 = [];
debugger;
if(that.deptName=='原料车间'){
that.header2Obj=[{name:'辅料',lengths:3},{name:'干混生料',lengths:4}];
that.header2 = ['辅料','干混生料'];//物料
// that.header3 = ['细度','Fe2O3','水分','细度','Fe2O3','水分','CaO'];//检测项
// that.header4 = ['平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率'];//检测项
}else if(that.deptName=='烧成车间'){
that.header2Obj=[{name:'入窑生料',lengths:4},{name:'熟料',lengths:4}];
that.header2 = ['入窑生料','熟料'];//物料
// that.header3 = ['CaO','Fe2O3','细度','水分','立升重','f-CaO','细度','水分'];//检测项
// that.header4 = ['平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率'];//检测项
}else{
that.header2Obj=[{name:'出磨水泥',lengths:3}];
that.header2 = ['出磨水泥'];//物料
// that.header3 = ['比表面积','SO3','掺量'];//检测项
// that.header4 = ['平均值','检次','合次','合格率','平均值','检次','合次','合格率','平均值','检次','合次','合格率'];//检测项
}
let params = {page: 0};
let arr = [];
let update_start_time = '';
let update_end_time = '';
if(that.query.type==0){//日
arr = that.query.month.split('-');
params.year_s = arr[0];
params.month_s = arr[1];
params.type = 'day_s'
}else if(that.query.type==1){//月
params.type = 'month_s'
params.year_s = that.query.year;
}
params.mgroup__belong_dept = that.query.belong_dept;
if(params.month_s){
const updateStartDate = new Date(params.year_s, params.month_s - 1, 1); // 月份从 0 开始
const updateEndDate = new Date(params.year_s, params.month_s, 0);
update_start_time = updateStartDate.toISOString().split('T')[0]; // 格式化为 'YYYY-MM-DD'
update_end_time = updateEndDate.toISOString().split('T')[0]; //
}else if(params.year_s){
const updateStartDate = new Date(params.year_s, 0, 1); // 1 月 1 日
const updateEndDate = new Date(params.year_s, 11, 31); // 12 月 31 日
update_start_time = updateStartDate.toISOString().split('T')[0]; // 格式化为 'YYYY-MM-DD'
update_end_time = updateEndDate.toISOString().split('T')[0];
}
this.$API.enm.enstat.req(params).then((res) => {
let data = res;
let wrapArr = [];
let innerArr = [];
let ind = 0;
//1、将相同日期或月份/年份的数据放到一组
let header2=[],header2Obj=[],header3=[],header4=[];
data.forEach(item => {
item.qua_data.forEach((qua)=>{
let key = `${qua.material_name}-${qua.testitem_name}`;
if (!that.materialTestItemMap[key]) {
that.materialTestItemMap[key] = {
material_id: qua.material,
testitem_id: qua.testitem,
update_start_time:update_start_time,
update_end_time:update_end_time
};
}
})
if(that.query.type==0){//日统计
ind = item.day_s-1;
}else if(that.query.type==1){//月统计
ind = item.month_s-1;
}
if(wrapArr[ind]){
}else{
wrapArr[ind] = [];
}
if(that.deptName=='原料车间'){
if (item.mgroup_name=='生料工序(二次配料)'){
wrapArr[ind][0]=item
}else if(item.mgroup_name=='原料磨'){
wrapArr[ind][1]=item
}
}else if(that.deptName=='烧成车间'){
if(item.mgroup_name=='回转窑'){
wrapArr[ind][1]=item
}else if(item.mgroup_name=='煤磨'){
wrapArr[ind][0]=item
}
}else{
wrapArr[ind].push(item)
}
});
wrapArr = wrapArr.filter(item => item && item.length > 0);
wrapArr.forEach((item1,index1)=>{
if(item1!=undefined){//一天的数据
let itemArr = [];
// 物料名称_检测项为唯一标识
let header2tem=[],header2Objtem=[],header3tem=[],header4tem=[];
let time =item1[0].day_s!=null? item1[0].year_s+'.'+item1[0].month_s+'.'+item1[0].day_s:item1[0].year_s+'.'+item1[0].month_s;
itemArr.push(time)
//遍历每个工段
item1.forEach(item2=>{
let data2 =item2.qua_data;
//遍历一个工段的物料检验数据
data2.forEach((item3,index3)=>{
//item3一个检验数据
if(header2tem.indexOf(item3.material_name)>-1){
let indexObj = header2tem.indexOf(item3.material_name);
header2Objtem[indexObj].lengths = header2Objtem[indexObj].lengths+1;
}else{
header2tem.push(item3.material_name);
header2Objtem.push({name:item3.material_name,lengths:1})
}
header3tem.push(item3.testitem_name)
header4tem.push('平均值')
header4tem.push('检次')
header4tem.push('合次')
header4tem.push('合格率')
let indexObj = header2tem.indexOf(item3.material_name);
if(indexObj>0&&index3==0){
let inde = indexObj-1;
let ind =header2Objtem[inde].lengths*4+1;
if(item3.val_avg){
itemArr[ind] = Number(item3.val_avg).toFixed(2);
}else{
itemArr[ind] = 0;
}
itemArr.push(item3.num_test)
itemArr.push(item3.num_ok)
let pass = 0;
if (item3.rate_pass){
pass = Number(item3.rate_pass).toFixed(2)+ '%';
itemArr.push(pass)
}else{
pass = Number(item3.rate_pass).toFixed(2) + '%';
itemArr.push(pass)
}
if(!that.thresholdobj[item3.material_name+"-"+item3.testitem_name]){
that.thresholdobj[item3.material_name+"-"+item3.testitem_name] = item3.rate_g;
}
}else{
itemArr.push(Number(item3.val_avg).toFixed(2));
itemArr.push(item3.num_test);
itemArr.push(item3.num_ok)
let pass = Number(item3.rate_pass).toFixed(2);
pass= pass+'%';
if(!that.thresholdobj[item3.material_name+"-"+item3.testitem_name]){
that.thresholdobj[item3.material_name+"-"+item3.testitem_name] = item3.rate_g;
}
itemArr.push(pass)
}
that.titleLength =itemArr.length;
})
})
innerArr.push(itemArr)
if(header2tem.length>header2.length){
header2 = header2tem;
}
if(header2Objtem.length>header2Obj.length){
header2Obj=header2Objtem;
}
if(header3tem.length>header3.length){
header3 = header3tem;
}
if(header4tem.length>header4.length){
header4 = header4tem;
}
}
})
if(header2Obj.length>0){
that.header2Obj=header2Obj;
}
that.header2 = header2.length>0?header2:that.header2;//物料
if(header3.length>0){
that.header3 =header3;//检测项
}
if(header4.length>0){
that.header4 = header4;
}
innerArr.forEach(item=>{
if(item.length>1){
that.tableDatas3.push(item)
}
})
});
},
handlePrint() {
this.$PRINT('#myReport');
},
exportExcel() {
this.exportLoading = true;
this.$XLSX('#myTable', this.tableName)
this.exportLoading = false;
},
}
};
</script>
<style>
.tableContainer{
overflow-x: scroll;
}
.red-text {
color: red;
}
.green-text {
color: green;
}
</style>