528 lines
25 KiB
Vue
528 lines
25 KiB
Vue
<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> |