生产
This commit is contained in:
@@ -47,15 +47,15 @@ const tableProps = [
|
||||
prop: 'equipmentName',
|
||||
label: '设备',
|
||||
},
|
||||
{
|
||||
prop: 'size',
|
||||
label: '规格',
|
||||
showOverflowtooltip: true,
|
||||
},
|
||||
{
|
||||
prop: 'process',
|
||||
label: '产品工艺',
|
||||
},
|
||||
// {
|
||||
// prop: 'size',
|
||||
// label: '规格',
|
||||
// showOverflowtooltip: true,
|
||||
// },
|
||||
// {
|
||||
// prop: 'process',
|
||||
// label: '产品工艺',
|
||||
// },
|
||||
{
|
||||
prop: 'standardCt',
|
||||
label: '标准节拍pcs/min',
|
||||
|
||||
@@ -72,16 +72,6 @@ export default {
|
||||
dateLabelList: [],
|
||||
optionArrUrl: [getProductionLinePage],
|
||||
formConfig: [
|
||||
{
|
||||
type: 'select',
|
||||
label: '产线',
|
||||
selectOptions: [],
|
||||
param: 'lineIds',
|
||||
defaultSelect: [],
|
||||
multiple: true,
|
||||
filterable: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
type: 'datePicker',
|
||||
label: '时间',
|
||||
@@ -92,7 +82,17 @@ export default {
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
param: 'time',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '产线',
|
||||
selectOptions: [],
|
||||
param: 'lineIds',
|
||||
defaultSelect: [],
|
||||
multiple: true,
|
||||
filterable: true,
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
btnName: '查询',
|
||||
@@ -113,7 +113,7 @@ export default {
|
||||
};
|
||||
this.optionArrUrl.forEach((item, index) => {
|
||||
item(params).then((response) => {
|
||||
this.formConfig[index].selectOptions = response.data.list;
|
||||
this.formConfig[1].selectOptions = response.data.list;
|
||||
// this.formConfig[0].defaultSelect = response.data.list[0].id
|
||||
// this.$set(this.formConfig[0], 'defaultSelect', response.data.list[0].id)
|
||||
});
|
||||
|
||||
@@ -279,7 +279,8 @@ export default {
|
||||
filterable: true,
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// {
|
||||
// select: true,
|
||||
// label: '设备分组',
|
||||
|
||||
@@ -92,7 +92,7 @@ export default {
|
||||
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
|
||||
},
|
||||
{ prop: 'name', label: '设备类型名称' },
|
||||
{ prop: 'code', label: '检测类型编码' },
|
||||
{ prop: 'code', label: '设备类型编码' },
|
||||
{ prop: 'remark', label: '备注' },
|
||||
],
|
||||
searchBarFormConfig: [
|
||||
|
||||
@@ -66,16 +66,15 @@
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="完成单位产品用时" prop="processTime">
|
||||
<el-input :disabled="isdetail" v-model="dataForm.processTime" placeholder="请输入完成单位产品用时" />
|
||||
<el-form-item label="完成单位产品用时(S)" prop="processTime">
|
||||
<el-input :disabled="isdetail" v-model="dataForm.processTime" placeholder="请输入完成单位产品用时(S)" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label=" 加工属性" prop="processType">
|
||||
<el-select v-model="dataForm.processType" clearable style="width: 100%" :disabled="isdetail"
|
||||
placeholder="请选择加工属性">
|
||||
<el-option v-for="dict in processTypeList" :key="dict.id" :label="dict.label"
|
||||
:value="dict.id" />
|
||||
<el-form-item label=" 产品工艺" prop="processType">
|
||||
<el-select multiple v-model="dataForm.processType" clearable style="width: 100%" :disabled="isdetail"
|
||||
placeholder="请选择产品工艺">
|
||||
<el-option v-for="dict in processTypeList" :key="dict.id" :label="dict.label" :value="dict.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
@@ -1,139 +1,142 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:visible.sync="visible"
|
||||
:width="'35%'"
|
||||
:append-to-body="true"
|
||||
:close-on-click-modal="false"
|
||||
class="dialog">
|
||||
<template #title>
|
||||
<slot name="title">
|
||||
<div class="titleStyle">
|
||||
{{ !dataForm.id ? '新增' : '编辑' }}
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
<el-dialog v-loading="isLoading" loading-text="处理中..." loading-spinner="el-icon-loading"
|
||||
loading-background="rgba(255, 255, 255, 0.7)" :visible.sync="visible" :width="'35%'" :append-to-body="true"
|
||||
:close-on-click-modal="false" class="dialog">
|
||||
<template #title>
|
||||
<slot name="title">
|
||||
<div class="titleStyle">
|
||||
{{ !dataForm.id ? '新增' : '编辑' }}
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<el-form
|
||||
ref="dataForm"
|
||||
:model="dataForm"
|
||||
:rules="dataRule"
|
||||
label-width="100px"
|
||||
@keyup.enter.native="dataFormSubmit()">
|
||||
<el-form-item label="属性名" prop="name">
|
||||
<el-input
|
||||
v-model="dataForm.name"
|
||||
placeholder="请输入属性名"
|
||||
clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="属性值" prop="value">
|
||||
<el-input
|
||||
v-model="dataForm.value"
|
||||
placeholder="请输入属性值"
|
||||
clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form ref="dataForm" :model="dataForm" :rules="dataRule" label-width="100px"
|
||||
@keyup.enter.native="dataFormSubmit()">
|
||||
<el-form-item label="属性名" prop="name">
|
||||
<el-input v-model="dataForm.name" placeholder="请输入属性名" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="属性值" prop="value">
|
||||
<el-input v-model="dataForm.value" placeholder="请输入属性值" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row style="text-align: right">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
<el-row style="text-align: right">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button :loading="isLoading" type="primary" @click="dataFormSubmit()">确定</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
createProductAttr,
|
||||
updateProductAttr,
|
||||
getProductAttr,
|
||||
createProductAttr,
|
||||
updateProductAttr,
|
||||
getProductAttr,
|
||||
} from '@/api/core/base/productAttr';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
productId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
dataForm: {
|
||||
id: 0,
|
||||
name: '',
|
||||
value: '',
|
||||
},
|
||||
dataRule: {
|
||||
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init(id) {
|
||||
this.dataForm.id = id || '';
|
||||
this.visible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].resetFields();
|
||||
if (this.dataForm.id) {
|
||||
getProductAttr(this.dataForm.id).then((res) => {
|
||||
const { name, value } = res.data;
|
||||
this.dataForm.name = name;
|
||||
this.dataForm.value = value;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 表单提交
|
||||
dataFormSubmit() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
// 修改的提交
|
||||
if (this.dataForm.id) {
|
||||
updateProductAttr({
|
||||
...this.dataForm,
|
||||
productId: this.productId,
|
||||
}).then((response) => {
|
||||
this.$modal.msgSuccess('修改成功');
|
||||
this.visible = false;
|
||||
this.$emit('refreshDataList');
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 添加的提交
|
||||
createProductAttr({
|
||||
...this.dataForm,
|
||||
productId: this.productId,
|
||||
}).then((response) => {
|
||||
this.$modal.msgSuccess('新增成功');
|
||||
this.visible = false;
|
||||
this.$emit('refreshDataList');
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
props: {
|
||||
productId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
isLoading: false,
|
||||
dataForm: {
|
||||
id: 0,
|
||||
name: '',
|
||||
value: '',
|
||||
},
|
||||
dataRule: {
|
||||
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init(id) {
|
||||
this.dataForm.id = id || '';
|
||||
this.visible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].resetFields();
|
||||
if (this.dataForm.id) {
|
||||
getProductAttr(this.dataForm.id).then((res) => {
|
||||
const { name, value } = res.data;
|
||||
this.dataForm.name = name;
|
||||
this.dataForm.value = value;
|
||||
}).catch(err => {
|
||||
console.error('获取属性详情失败:', err);
|
||||
this.$modal.msgError('获取数据失败,请重试');
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 表单提交(优化加载状态和错误处理)
|
||||
async dataFormSubmit() {
|
||||
// 先验证表单
|
||||
const valid = await new Promise((resolve) => {
|
||||
this.$refs['dataForm'].validate((isValid) => resolve(isValid));
|
||||
});
|
||||
|
||||
if (!valid) return;
|
||||
|
||||
this.isLoading = true; // 开始加载
|
||||
|
||||
try {
|
||||
if (this.dataForm.id) {
|
||||
// 编辑操作
|
||||
await updateProductAttr({
|
||||
...this.dataForm,
|
||||
productId: this.productId,
|
||||
});
|
||||
this.$modal.msgSuccess('修改成功');
|
||||
} else {
|
||||
// 新增操作
|
||||
await createProductAttr({
|
||||
...this.dataForm,
|
||||
productId: this.productId,
|
||||
});
|
||||
this.$modal.msgSuccess('新增成功');
|
||||
}
|
||||
this.visible = false;
|
||||
this.$emit('refreshDataList');
|
||||
} catch (error) {
|
||||
// 错误处理
|
||||
console.error('提交失败:', error);
|
||||
this.$modal.msgError('操作失败,请重试');
|
||||
} finally {
|
||||
// 无论成功失败,都关闭加载状态
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dialog >>> .el-dialog__body {
|
||||
padding: 30px 24px;
|
||||
.dialog>>>.el-dialog__body {
|
||||
padding: 30px 24px;
|
||||
}
|
||||
.dialog >>> .el-dialog__header {
|
||||
font-size: 16px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
font-weight: 500;
|
||||
padding: 13px 24px;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
|
||||
.dialog>>>.el-dialog__header {
|
||||
font-size: 16px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
font-weight: 500;
|
||||
padding: 13px 24px;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
}
|
||||
.dialog >>> .el-dialog__header .titleStyle::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background-color: #0b58ff;
|
||||
border-radius: 1px;
|
||||
margin-right: 8px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
|
||||
.dialog>>>.el-dialog__header .titleStyle::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background-color: #0b58ff;
|
||||
border-radius: 1px;
|
||||
margin-right: 8px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -262,6 +262,14 @@ export default {
|
||||
tooltip: {
|
||||
valueFormatter: (value) => `${value} %`,
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
distance: 6,
|
||||
fontSize: 11,
|
||||
color: '#333333',
|
||||
formatter: (params) => `${params.value}` // 显示单位
|
||||
},
|
||||
data: this.barData.map((item) => item.processingRatio),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<el-tabs v-model="activeLabel" :stretch="true" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="'全部数据'" name="table">
|
||||
<base-table-s ref="lineCurrentShiftTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'"
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData" :max-height="210" />
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData" :max-height="300" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
|
||||
<div style="height: 230px;" v-if="activeLabel == 'graph'" class="graph">
|
||||
@@ -57,7 +57,7 @@
|
||||
<el-tabs v-model="activeLabelDay" :stretch="true" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="'全部数据'" name="table">
|
||||
<base-table-s ref="lineTodayTable" style="margin-bottom: 16px;" v-if="activeLabelDay == 'table'"
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData2" :max-height="210" />
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData2" :max-height="300" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
|
||||
<div style="height: 230px;" v-if="activeLabelDay == 'graph'" class="graph">
|
||||
@@ -71,9 +71,55 @@
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-inner" v-if="listQuery.timeType === 3">
|
||||
<!-- 当班数据(占1/2剩余高度) -->
|
||||
<div class="content-card energyOverlimitLog">
|
||||
<span class="blue-block"></span>
|
||||
<span class="tip">上一班数据</span>
|
||||
<el-row style="margin-top: 10px;">
|
||||
<el-col class="custom-tabs">
|
||||
<el-tabs v-model="activeLabel" :stretch="true" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="'全部数据'" name="table">
|
||||
<base-table-s ref="lineCurrentShiftTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'"
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData" :max-height="300" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
|
||||
<div style="height: 230px;" v-if="activeLabel == 'graph'" class="graph">
|
||||
<barChart v-if="tableData && tableData.length > 0" ref="barChart" height="230px"
|
||||
:bar-data="tableData" />
|
||||
<div v-else class="no-data-bg"></div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- 当天数据(占1/2剩余高度) -->
|
||||
<div class="content-card energyOverlimitLog">
|
||||
<span class="blue-block"></span>
|
||||
<span class="tip">当天数据</span>
|
||||
<el-row style="margin-top: 10px;">
|
||||
<el-col class="custom-tabs">
|
||||
<el-tabs v-model="activeLabelDay" :stretch="true" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="'全部数据'" name="table">
|
||||
<base-table-s ref="lineTodayTable" style="margin-bottom: 16px;" v-if="activeLabelDay == 'table'"
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData2" :max-height="300" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
|
||||
<div style="height: 230px;" v-if="activeLabelDay == 'graph'" class="graph">
|
||||
<barChart v-if="tableData2 && tableData2.length > 0" ref="barChart" height="230px"
|
||||
:bar-data="tableData2" />
|
||||
<div v-else class="no-data-bg"></div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3.2 时间维度为“自定义”时的内容(两个平分高度的div) -->
|
||||
<div class="content-inner" v-else>
|
||||
<div class="content-inner" v-if="listQuery.timeType === 2">
|
||||
<div class="content-card energyOverlimitLog">
|
||||
<span class="blue-block"></span>
|
||||
<span class="tip" v-if="listQuery.startTime && listQuery.endTime">
|
||||
@@ -86,7 +132,7 @@
|
||||
<span class="tip" v-else>生产表格数据 </span>
|
||||
<div class="graph">
|
||||
<base-table-s ref="lineCustomTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'" :page="1"
|
||||
:limit="100" :table-props="tableProps" :max-height="210" :table-data="tableDataCustom" />
|
||||
:limit="100" :table-props="tableProps" :max-height="300" :table-data="tableDataCustom" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -113,7 +159,7 @@
|
||||
<span class="tip">当班数据</span>
|
||||
<base-table-s ref="productCurrentShiftTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'"
|
||||
:page="1" :limit="100" :table-props="productTableProps" :table-data="productTableData"
|
||||
:max-height="210" />
|
||||
:max-height="300" />
|
||||
</div>
|
||||
|
||||
<!-- 当天数据(占1/2剩余高度) -->
|
||||
@@ -122,7 +168,7 @@
|
||||
<span class="tip">当天数据</span>
|
||||
<base-table-s ref="productTodayTable" style="margin-bottom: 16px;" v-if="activeLabelDay == 'table'"
|
||||
:page="1" :limit="100" :table-props="productTablePropsDay" :table-data="productTableDataDay"
|
||||
:max-height="210" />
|
||||
:max-height="300" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -142,7 +188,7 @@
|
||||
</span>
|
||||
<span class="tip" v-else>生产表格数据 </span>
|
||||
<base-table-s ref="productCustomTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'" :page="1"
|
||||
:limit="100" :table-props="productTableProps" :table-data="productTableData" :max-height="210" />
|
||||
:limit="100" :table-props="productTableProps" :table-data="productTableData" :max-height="300" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -154,7 +200,7 @@
|
||||
import { parseTime } from '@/filter/code-filter';
|
||||
import {
|
||||
getLineAuto, getPdList, getPdlAutoReportNewSearchNow, getProductAuto,
|
||||
getProcessAutoReportGroup, getProcessAutoReportDay, getProcessAutoReportNew
|
||||
getProcessAutoReportGroup, getProcessAutoReportDay, getProcessAutoReportNew, getPdlAutoReportNewSearchLastGroup
|
||||
} from '@/api/core/monitoring/auto';
|
||||
import { getFactoryPage } from '@/api/core/base/factory';
|
||||
import * as XLSX from 'xlsx';
|
||||
@@ -165,11 +211,11 @@ import ButtonNav from '@/components/ButtonNav';
|
||||
import { listData } from '@/api/system/dict/data';
|
||||
// 表格列配置
|
||||
const tableProps = [
|
||||
// {
|
||||
// prop: 'factoryName',
|
||||
// label: '工厂',
|
||||
// fixed: true
|
||||
// },
|
||||
{
|
||||
prop: 'factoryName',
|
||||
label: '工厂',
|
||||
fixed: true
|
||||
},
|
||||
{
|
||||
prop: 'lineName',
|
||||
label: '产线',
|
||||
@@ -368,15 +414,27 @@ export default {
|
||||
productTableDataDay: [],
|
||||
tableDataCustom: [],
|
||||
list: [], // 折线图数据
|
||||
timeTypeOptions: {
|
||||
productLine: [ // 按产线监控(包含上一班)
|
||||
{ id: 1, name: '当天' },
|
||||
{ id: 2, name: '自定义' },
|
||||
{ id: 3, name: '上一班' }
|
||||
],
|
||||
product: [ // 按产品监控(不含上一班)
|
||||
{ id: 1, name: '当天' },
|
||||
{ id: 2, name: '自定义' }
|
||||
]
|
||||
},
|
||||
formConfig: [
|
||||
{
|
||||
type: 'select',
|
||||
label: '时间维度',
|
||||
selectOptions: [
|
||||
{ id: 1, name: '当天' },
|
||||
{ id: 2, name: '自定义' }
|
||||
{ id: 2, name: '自定义' },
|
||||
{ id: 3, name: '上一班' }
|
||||
],
|
||||
width: 80,
|
||||
width: 100,
|
||||
onchange: true,
|
||||
// defaultSelect: 1,
|
||||
clearable: false,
|
||||
@@ -437,6 +495,7 @@ export default {
|
||||
{ id: 3, name: '月' },
|
||||
{ id: 4, name: '年' }
|
||||
],
|
||||
onchange: true,
|
||||
width: 80,
|
||||
param: 'reportType'
|
||||
},
|
||||
@@ -467,6 +526,13 @@ export default {
|
||||
productTableProps() {
|
||||
// 当班数据的完整表头(基础列 + 当班动态表头)
|
||||
const baseColumns = [
|
||||
{
|
||||
prop: 'sizes',
|
||||
label: '规格',
|
||||
width: 105,
|
||||
showOverflowtooltip: true,
|
||||
fixed: true
|
||||
},
|
||||
{
|
||||
prop: 'process',
|
||||
label: '产品工艺',
|
||||
@@ -476,7 +542,8 @@ export default {
|
||||
prop: 'processType',
|
||||
label: '产品类型',
|
||||
filter: (val) => (val != 1 ? '面板' : '背板'),
|
||||
fixed: true
|
||||
fixed: true,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
prop: 'factoryName',
|
||||
@@ -513,13 +580,16 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.buttonNav) {
|
||||
this.$refs.buttonNav.currentMenu = '按产线监控';
|
||||
this.formConfig[0].selectOptions = this.timeTypeOptions.productLine;
|
||||
}
|
||||
if (this.$refs.searchBarForm) {
|
||||
// this.$refs.searchBarForm.formInline.timeVal = [
|
||||
// yesterday.getTime(),
|
||||
// end.getTime()
|
||||
// ];
|
||||
|
||||
this.$refs.searchBarForm.formInline.timeType = 1
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -576,18 +646,26 @@ export default {
|
||||
|
||||
// 3. 执行公共重置
|
||||
resetCommon();
|
||||
|
||||
// if (this.activeName === 'productLine') {
|
||||
// } else {
|
||||
// }
|
||||
// 4. 根据类型设置差异化的表单配置(仅处理不同的部分)
|
||||
if (isProductLine) {
|
||||
// 按产线监控:显示产线,隐藏产品工艺和类型
|
||||
// 按产线监控:显示产线,隐藏产品工艺和类型,时间维度包含上一班
|
||||
this.formConfig[0].selectOptions = this.timeTypeOptions.productLine; // 恢复上一班选项
|
||||
this.formConfig[3].type = 'select'; // 显示产线
|
||||
this.formConfig[4].type = ''; // 隐藏产品工艺
|
||||
this.formConfig[5].type = ''; // 隐藏产品类型
|
||||
this.getDayDataList();
|
||||
|
||||
} else {
|
||||
// 按产品监控:显示产品工艺和类型,隐藏产线
|
||||
// 按产品监控:显示产品工艺和类型,隐藏产线,时间维度移除上一班
|
||||
this.formConfig[0].selectOptions = this.timeTypeOptions.product; // 不含上一班
|
||||
this.formConfig[3].type = ''; // 隐藏产线
|
||||
this.formConfig[4].type = 'select'; // 显示产品工艺
|
||||
this.formConfig[5].type = 'select'; // 显示产品类型
|
||||
this.getProductList();
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
@@ -601,6 +679,12 @@ export default {
|
||||
{ ref: 'lineCurrentShiftTable', name: '产线监控_当班数据' },
|
||||
{ ref: 'lineTodayTable', name: '产线监控_当天数据' }
|
||||
], '产线监控_当班及当天数据汇总'); // 传入自定义汇总文件名
|
||||
} else if (this.listQuery.timeType === 1) {
|
||||
// 产线-当天:导出当班 + 当天两个表格(自定义汇总文件名)
|
||||
this.exportMultipleTables([
|
||||
{ ref: 'lineCurrentShiftTable', name: '产线监控_上一班数据' },
|
||||
{ ref: 'lineTodayTable', name: '产线监控_当天数据' }
|
||||
], '产线监控_当班及当天数据汇总'); // 传入自定义汇总文件名
|
||||
} else {
|
||||
// 产线-自定义:导出一个表格(自定义文件名)
|
||||
this.exportSingleTable('lineCustomTable', '产线监控_自定义时间数据');
|
||||
@@ -801,31 +885,126 @@ export default {
|
||||
this.formConfig[2].selectOptions = res.data.list || [];
|
||||
});
|
||||
},
|
||||
getWeekTimeRange(date) {
|
||||
const targetDate = new Date(date);
|
||||
const day = targetDate.getDay() || 7; // 周日转为7
|
||||
const year = targetDate.getFullYear();
|
||||
const month = targetDate.getMonth();
|
||||
const dateNum = targetDate.getDate();
|
||||
|
||||
// 本周一 00:00:00
|
||||
const startDate = new Date(year, month, dateNum - day + 1);
|
||||
startDate.setHours(0, 0, 0, 0);
|
||||
|
||||
// 本周日 23:59:59
|
||||
const endDate = new Date(year, month, dateNum - day + 7);
|
||||
endDate.setHours(23, 59, 59, 999);
|
||||
|
||||
return {
|
||||
startTime: startDate.getTime(),
|
||||
endTime: endDate.getTime()
|
||||
};
|
||||
},
|
||||
|
||||
// 辅助函数:获取本年的开始和结束时间戳(1月1日00:00:00 到 12月31日23:59:59)
|
||||
getYearTimeRange(date) {
|
||||
const targetDate = new Date(date);
|
||||
const year = targetDate.getFullYear();
|
||||
|
||||
// 本年1月1日 00:00:00
|
||||
const startDate = new Date(year, 0, 1);
|
||||
startDate.setHours(0, 0, 0, 0);
|
||||
|
||||
// 本年12月31日 23:59:59
|
||||
const endDate = new Date(year, 11, 31);
|
||||
endDate.setHours(23, 59, 59, 999);
|
||||
|
||||
return {
|
||||
startTime: startDate.getTime(),
|
||||
endTime: endDate.getTime()
|
||||
};
|
||||
},
|
||||
// 搜索/导出按钮点击
|
||||
buttonClick(val) {
|
||||
if (this.activeName === 'productLine') {
|
||||
this.listQuery.pageNo = 1;
|
||||
this.listQuery.pageSize = 10;
|
||||
this.listQuery.factoryId = val.factoryId || undefined;
|
||||
this.listQuery.process = val.process ? val.process : [];
|
||||
this.listQuery.lineId = val.lineId ? val.lineId : [];
|
||||
this.listQuery.processType = val.processType ? val.processType : [];
|
||||
this.listQuery.reportType = val.reportType || undefined;
|
||||
this.listQuery.timeType = val.timeType || undefined;
|
||||
this.listQuery.searchType = val.searchType || undefined;
|
||||
|
||||
// 处理不同时间选择类型
|
||||
if (val.timeVal) {
|
||||
this.listQuery.startTime = val.timeVal[0];
|
||||
this.listQuery.endTime = val.timeVal[1];
|
||||
} else if (val.timeValWeek) {
|
||||
// 周选择器
|
||||
const { startTime, endTime } = this.getWeekTimeRange(val.timeValWeek);
|
||||
this.listQuery.startTime = startTime;
|
||||
this.listQuery.endTime = endTime;
|
||||
} else if (val.timeValMonth) {
|
||||
// 月选择器
|
||||
this.listQuery.startTime = val.timeValMonth[0];
|
||||
this.listQuery.endTime = val.timeValMonth[1];
|
||||
} else if (val.timeValYear) {
|
||||
// 年选择器
|
||||
const { startTime, endTime } = this.getYearTimeRange(val.timeValYear);
|
||||
this.listQuery.startTime = startTime;
|
||||
this.listQuery.endTime = endTime;
|
||||
} else {
|
||||
this.listQuery.startTime = undefined;
|
||||
this.listQuery.endTime = undefined;
|
||||
}
|
||||
} else {
|
||||
this.listQuery.pageNo = 1;
|
||||
this.listQuery.pageSize = 10;
|
||||
this.listQuery.factoryId = val.factoryId || []
|
||||
this.listQuery.process = val.process ? val.process : [];
|
||||
this.listQuery.lineId = undefined;
|
||||
this.listQuery.processType = val.processType ? val.processType : [];
|
||||
this.listQuery.reportType = val.reportType || undefined;
|
||||
this.listQuery.timeType = val.timeType || undefined;
|
||||
this.listQuery.searchType = val.searchType || undefined;
|
||||
|
||||
// 处理不同时间选择类型
|
||||
if (val.timeVal) {
|
||||
this.listQuery.startTime = val.timeVal[0];
|
||||
this.listQuery.endTime = val.timeVal[1];
|
||||
} else if (val.timeValWeek) {
|
||||
// 周选择器
|
||||
const { startTime, endTime } = this.getWeekTimeRange(val.timeValWeek);
|
||||
this.listQuery.startTime = startTime;
|
||||
this.listQuery.endTime = endTime;
|
||||
} else if (val.timeValMonth) {
|
||||
// 月选择器
|
||||
this.listQuery.startTime = val.timeValMonth[0];
|
||||
this.listQuery.endTime = val.timeValMonth[1];
|
||||
} else if (val.timeValYear) {
|
||||
// 年选择器
|
||||
const { startTime, endTime } = this.getYearTimeRange(val.timeValYear);
|
||||
this.listQuery.startTime = startTime;
|
||||
this.listQuery.endTime = endTime;
|
||||
} else {
|
||||
this.listQuery.startTime = undefined;
|
||||
this.listQuery.endTime = undefined;
|
||||
}
|
||||
}
|
||||
switch (val.btnName) {
|
||||
case 'search':
|
||||
this.listQuery.pageNo = 1;
|
||||
this.listQuery.pageSize = 10;
|
||||
this.listQuery.factoryId = val.factoryId || undefined;
|
||||
this.listQuery.process = val.process ? val.process : [];
|
||||
this.listQuery.lineId = val.lineId ? val.lineId : [];
|
||||
this.listQuery.processType = val.processType ? val.processType : [];
|
||||
this.listQuery.reportType = val.reportType || undefined;
|
||||
this.listQuery.timeType = val.timeType || undefined;
|
||||
this.listQuery.searchType = val.searchType || undefined;
|
||||
this.listQuery.startTime = val.timeVal ? val.timeVal[0] : undefined;
|
||||
this.listQuery.endTime = val.timeVal ? val.timeVal[1] : undefined;
|
||||
if (this.activeName === 'productLine') {
|
||||
if (this.listQuery.timeType === 1) {
|
||||
this.getDayDataList();
|
||||
} else if (this.listQuery.timeType === 3) {
|
||||
this.getLastDayDataList();
|
||||
} else {
|
||||
this.getDataList();
|
||||
}
|
||||
} else {
|
||||
this.getProductList();
|
||||
|
||||
}
|
||||
break;
|
||||
case 'export':
|
||||
@@ -834,6 +1013,9 @@ export default {
|
||||
case 'reset':
|
||||
this.$refs.searchBarForm.resetForm();
|
||||
this.$refs.searchBarForm.formInline.timeType = 1;
|
||||
this.formConfig[0].selectOptions = this.activeName === 'productLine'
|
||||
? this.timeTypeOptions.productLine
|
||||
: this.timeTypeOptions.product;
|
||||
this.listQuery = {
|
||||
pageSize: 100,
|
||||
pageNo: 1,
|
||||
@@ -842,12 +1024,9 @@ export default {
|
||||
};
|
||||
if (this.activeName === 'productLine') {
|
||||
this.getDayDataList();
|
||||
|
||||
} else {
|
||||
this.getProductList();
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
console.log(val);
|
||||
@@ -1097,6 +1276,28 @@ export default {
|
||||
return [...lineColumns, totalColumn];
|
||||
},
|
||||
// 为当天时调用的接口
|
||||
getLastDayDataList() {
|
||||
getPdlAutoReportNewSearchLastGroup().then((response) => {
|
||||
this.tableData = response.data.classData.map((item, index) => {
|
||||
item.originalLossNum = item.original?.lossNum;
|
||||
item.originalLossArea = item.original?.lossArea;
|
||||
item.edgeLossNum = item.edge?.lossNum;
|
||||
item.edgeLossArea = item.edge?.lossArea;
|
||||
item.drillLossNum = item.drill?.lossNum;
|
||||
item.drillLossArea = item.drill?.lossArea;
|
||||
item.coatingLossNum = item.coating?.lossNum;
|
||||
item.coatingLossArea = item.coating?.lossArea;
|
||||
item.silkLossNum = item.silk?.lossNum;
|
||||
item.silkLossArea = item.silk?.lossArea;
|
||||
item.temperingLossNum = item.tempering?.lossNum;
|
||||
item.temperingLossArea = item.tempering?.lossArea;
|
||||
item.packingLossNum = item.packing?.lossNum;
|
||||
item.packingLossArea = item.packing?.lossArea;
|
||||
return item;
|
||||
});
|
||||
// console.log(this.tableData, this.tableData2);
|
||||
});
|
||||
},
|
||||
getDayDataList() {
|
||||
getPdlAutoReportNewSearchNow().then((response) => {
|
||||
this.tableData = response.data.classData.map((item, index) => {
|
||||
@@ -1156,24 +1357,21 @@ export default {
|
||||
console.log(value);
|
||||
|
||||
this.listQuery.timeType = value;
|
||||
if (value === 1) {
|
||||
// 切换为“当天”:隐藏查询类型、报表类型、时间范围
|
||||
if (value === 2) {
|
||||
// 切换为“自定义”:显示查询类型和时间范围
|
||||
this.formConfig[1].type = 'select';
|
||||
this.$refs.searchBarForm.formInline.timeType = value;
|
||||
this.listQuery.timeType = value;
|
||||
this.formConfig[7].type = 'datePicker';
|
||||
} else {
|
||||
this.formConfig[1].type = '';
|
||||
this.formConfig[6].type = '';
|
||||
this.formConfig[7].type = '';
|
||||
this.$refs.searchBarForm.formInline.timeType = value;
|
||||
this.listQuery.timeType = value;
|
||||
|
||||
this.$refs.searchBarForm.formInline.searchType = undefined;
|
||||
this.$refs.searchBarForm.formInline.reportType = undefined;
|
||||
this.$refs.searchBarForm.formInline.timeVal = undefined;
|
||||
} else {
|
||||
// 切换为“自定义”:显示查询类型和时间范围
|
||||
this.formConfig[1].type = 'select';
|
||||
this.$refs.searchBarForm.formInline.timeType = value;
|
||||
this.listQuery.timeType = value;
|
||||
|
||||
this.formConfig[7].type = 'datePicker';
|
||||
}
|
||||
} else if (param === 'searchType') {
|
||||
if (value === 1) {
|
||||
@@ -1187,7 +1385,74 @@ export default {
|
||||
this.formConfig[7].type = 'datePicker';
|
||||
}
|
||||
} else if (param === 'reportType') {
|
||||
this.$refs.searchBarForm.formInline.timeVal = undefined;
|
||||
if (this.$refs.searchBarForm && this.$refs.searchBarForm.formInline) {
|
||||
const formInline = this.$refs.searchBarForm.formInline;
|
||||
// 精准判断:只有字段存在时,才置为undefined(不存在则不处理)
|
||||
if ('timeVal' in formInline) {
|
||||
formInline.timeVal = undefined;
|
||||
}
|
||||
if ('timeValWeek' in formInline) {
|
||||
formInline.timeValWeek = undefined;
|
||||
}
|
||||
if ('timeValMonth' in formInline) {
|
||||
formInline.timeValMonth = undefined;
|
||||
}
|
||||
if ('timeValYear' in formInline) {
|
||||
formInline.timeValYear = undefined;
|
||||
}
|
||||
}
|
||||
this.listQuery.startTime = undefined;
|
||||
this.listQuery.endTime = undefined;
|
||||
if (value === 1) {
|
||||
this.formConfig[7] = {
|
||||
type: 'datePicker',
|
||||
label: '时间范围',
|
||||
dateType: 'datetimerange',
|
||||
format: 'yyyy-MM-dd HH:mm:ss',
|
||||
valueFormat: 'timestamp',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
param: 'timeVal',
|
||||
width: 350
|
||||
};
|
||||
} else if (value === 2) {
|
||||
this.formConfig[7] = {
|
||||
type: 'datePicker',
|
||||
label: '时间范围',
|
||||
dateType: 'week',
|
||||
placeholder: '选择日期',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'yyyy-MM-dd',
|
||||
param: 'timeValWeek',
|
||||
width: 250,
|
||||
};
|
||||
} else if (value === 3) {
|
||||
this.formConfig[7] = {
|
||||
type: 'datePicker',
|
||||
label: '时间范围',
|
||||
dateType: 'monthrange',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'timestamp',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
param: 'timeValMonth',
|
||||
defaultTime: ['00:00:00', '23:59:59'],
|
||||
width: 250,
|
||||
};
|
||||
} else if (value === 4) {
|
||||
this.formConfig[7] = {
|
||||
type: 'datePicker',
|
||||
label: '时间范围',
|
||||
dateType: 'year',
|
||||
placeholder: '选择年份',
|
||||
format: 'yyyy',
|
||||
valueFormat: 'timestamp',
|
||||
param: 'timeValYear',
|
||||
width: 250,
|
||||
};
|
||||
}
|
||||
} else if (param === 'factoryId') {
|
||||
// 切换工厂时刷新产线列表
|
||||
this.listQuery.lineId = [];
|
||||
@@ -1234,7 +1499,7 @@ export default {
|
||||
.content-wrapper {
|
||||
// flex: 1;
|
||||
width: 100%;
|
||||
height: calc(100vh - 303px);
|
||||
height: calc(100vh - 280px);
|
||||
// overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ const tableProps = [
|
||||
},
|
||||
{
|
||||
prop: 'palletNum',
|
||||
label: '下片托数'
|
||||
label: '一托玻璃数量/片'
|
||||
},
|
||||
{
|
||||
prop: 'startTime',
|
||||
@@ -92,7 +92,7 @@ const tableProps = [
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
prop: 'outputNum',
|
||||
prop: 'length',
|
||||
label: '玻璃长度/mm'
|
||||
},
|
||||
{
|
||||
@@ -314,9 +314,10 @@ export default {
|
||||
case 'search':
|
||||
this.listQuery.pageNo = 1;
|
||||
this.listQuery.pageSize = 10;
|
||||
this.listQuery.productId = val.productId ? val.productId : undefined;
|
||||
this.listQuery.startTime = val.timeVal ? val.timeVal[0]: undefined;
|
||||
this.listQuery.endTime = val.timeVal ? val.timeVal[1]: undefined;
|
||||
this.listQuery.productionLineId = val.productionLineId ? val.productionLineId : undefined;
|
||||
this.listQuery.thick = val.thick ? val.thick : undefined;
|
||||
this.listQuery.startTime = val.timeVal ? val.timeVal[0] : undefined;
|
||||
this.listQuery.endTime = val.timeVal ? val.timeVal[1] : undefined;
|
||||
|
||||
//this.listQuery.reportEndTime = val.timeVal ? [new Date(val.timeVal[1]).getTime()] : undefined;
|
||||
this.getDataList();
|
||||
|
||||
@@ -77,7 +77,7 @@ const tableProps = [
|
||||
},
|
||||
{
|
||||
prop: 'palletNum',
|
||||
label: '下片托数'
|
||||
label: '一托玻璃数量/片'
|
||||
},
|
||||
{
|
||||
prop: 'startTime',
|
||||
@@ -92,7 +92,7 @@ const tableProps = [
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
prop: 'outputNum',
|
||||
prop: 'length',
|
||||
label: '玻璃长度/mm'
|
||||
},
|
||||
{
|
||||
|
||||
@@ -262,6 +262,14 @@ export default {
|
||||
tooltip: {
|
||||
valueFormatter: (value) => `${value} %`,
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
distance: 6,
|
||||
fontSize: 11,
|
||||
color: '#333333',
|
||||
formatter: (params) => `${params.value}` // 显示单位
|
||||
},
|
||||
data: this.barData.map((item) => item.processingRatio),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<el-tabs v-model="activeLabel" :stretch="true" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="'全部数据'" name="table">
|
||||
<base-table-s ref="lineCurrentShiftTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'"
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData" :max-height="210" />
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData" :max-height="300" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
|
||||
<div style="height: 230px;" v-if="activeLabel == 'graph'" class="graph">
|
||||
@@ -57,7 +57,7 @@
|
||||
<el-tabs v-model="activeLabelDay" :stretch="true" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="'全部数据'" name="table">
|
||||
<base-table-s ref="lineTodayTable" style="margin-bottom: 16px;" v-if="activeLabelDay == 'table'"
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData2" :max-height="210" />
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData2" :max-height="300" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
|
||||
<div style="height: 230px;" v-if="activeLabelDay == 'graph'" class="graph">
|
||||
@@ -71,22 +71,68 @@
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-inner" v-if="listQuery.timeType === 3">
|
||||
<!-- 当班数据(占1/2剩余高度) -->
|
||||
<div class="content-card energyOverlimitLog">
|
||||
<span class="blue-block"></span>
|
||||
<span class="tip">上一班数据</span>
|
||||
<el-row style="margin-top: 10px;">
|
||||
<el-col class="custom-tabs">
|
||||
<el-tabs v-model="activeLabel" :stretch="true" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="'全部数据'" name="table">
|
||||
<base-table-s ref="lineCurrentShiftTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'"
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData" :max-height="300" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
|
||||
<div style="height: 230px;" v-if="activeLabel == 'graph'" class="graph">
|
||||
<barChart v-if="tableData && tableData.length > 0" ref="barChart" height="230px"
|
||||
:bar-data="tableData" />
|
||||
<div v-else class="no-data-bg"></div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- 当天数据(占1/2剩余高度) -->
|
||||
<div class="content-card energyOverlimitLog">
|
||||
<span class="blue-block"></span>
|
||||
<span class="tip">当天数据</span>
|
||||
<el-row style="margin-top: 10px;">
|
||||
<el-col class="custom-tabs">
|
||||
<el-tabs v-model="activeLabelDay" :stretch="true" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="'全部数据'" name="table">
|
||||
<base-table-s ref="lineTodayTable" style="margin-bottom: 16px;" v-if="activeLabelDay == 'table'"
|
||||
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData2" :max-height="300" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
|
||||
<div style="height: 230px;" v-if="activeLabelDay == 'graph'" class="graph">
|
||||
<barChart v-if="tableData2 && tableData2.length > 0" ref="barChart" height="230px"
|
||||
:bar-data="tableData2" />
|
||||
<div v-else class="no-data-bg"></div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3.2 时间维度为“自定义”时的内容(两个平分高度的div) -->
|
||||
<div class="content-inner" v-else>
|
||||
<div class="content-inner" v-if="listQuery.timeType === 2">
|
||||
<div class="content-card energyOverlimitLog">
|
||||
<span class="blue-block"></span>
|
||||
<span class="tip" v-if="listQuery.startTime && listQuery.endTime">
|
||||
<span>{{ reportTypeMap[listQuery.reportType] }}</span>
|
||||
<span>
|
||||
{{ parseTime(listQuery.startTime) }} 至{{
|
||||
parseTime(listQuery.endTime) }}
|
||||
parseTime(listQuery.endTime) }}
|
||||
</span>
|
||||
</span>
|
||||
<span class="tip" v-else>生产表格数据 </span>
|
||||
<div class="graph">
|
||||
<base-table-s ref="lineCustomTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'" :page="1"
|
||||
:limit="100" :table-props="tableProps" :max-height="210" :table-data="tableDataCustom" />
|
||||
:limit="100" :table-props="tableProps" :max-height="300" :table-data="tableDataCustom" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -113,7 +159,7 @@
|
||||
<span class="tip">当班数据</span>
|
||||
<base-table-s ref="productCurrentShiftTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'"
|
||||
:page="1" :limit="100" :table-props="productTableProps" :table-data="productTableData"
|
||||
:max-height="210" />
|
||||
:max-height="300" />
|
||||
</div>
|
||||
|
||||
<!-- 当天数据(占1/2剩余高度) -->
|
||||
@@ -122,7 +168,7 @@
|
||||
<span class="tip">当天数据</span>
|
||||
<base-table-s ref="productTodayTable" style="margin-bottom: 16px;" v-if="activeLabelDay == 'table'"
|
||||
:page="1" :limit="100" :table-props="productTablePropsDay" :table-data="productTableDataDay"
|
||||
:max-height="210" />
|
||||
:max-height="300" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -142,7 +188,7 @@
|
||||
</span>
|
||||
<span class="tip" v-else>生产表格数据 </span>
|
||||
<base-table-s ref="productCustomTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'" :page="1"
|
||||
:limit="100" :table-props="productTableProps" :table-data="productTableData" :max-height="210" />
|
||||
:limit="100" :table-props="productTableProps" :table-data="productTableData" :max-height="300" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -154,7 +200,7 @@
|
||||
import { parseTime } from '@/filter/code-filter';
|
||||
import {
|
||||
getLineAuto, getPdList, getPdlAutoReportNewSearchNow, getProductAuto,
|
||||
getProcessAutoReportGroup, getProcessAutoReportDay, getProcessAutoReportNew
|
||||
getProcessAutoReportGroup, getProcessAutoReportDay, getProcessAutoReportNew, getPdlAutoReportNewSearchLastGroup
|
||||
} from '@/api/core/monitoring/auto';
|
||||
import { getFactoryPage } from '@/api/core/base/factory';
|
||||
import * as XLSX from 'xlsx';
|
||||
@@ -165,11 +211,11 @@ import ButtonNav from '@/components/ButtonNav';
|
||||
import { listData } from '@/api/system/dict/data';
|
||||
// 表格列配置
|
||||
const tableProps = [
|
||||
// {
|
||||
// prop: 'factoryName',
|
||||
// label: '工厂',
|
||||
// fixed: true
|
||||
// },
|
||||
{
|
||||
prop: 'factoryName',
|
||||
label: '工厂',
|
||||
fixed: true
|
||||
},
|
||||
{
|
||||
prop: 'lineName',
|
||||
label: '产线',
|
||||
@@ -368,15 +414,27 @@ export default {
|
||||
productTableDataDay: [],
|
||||
tableDataCustom: [],
|
||||
list: [], // 折线图数据
|
||||
timeTypeOptions: {
|
||||
productLine: [ // 按产线监控(包含上一班)
|
||||
{ id: 1, name: '当天' },
|
||||
{ id: 2, name: '自定义' },
|
||||
{ id: 3, name: '上一班' }
|
||||
],
|
||||
product: [ // 按产品监控(不含上一班)
|
||||
{ id: 1, name: '当天' },
|
||||
{ id: 2, name: '自定义' }
|
||||
]
|
||||
},
|
||||
formConfig: [
|
||||
{
|
||||
type: 'select',
|
||||
label: '时间维度',
|
||||
selectOptions: [
|
||||
{ id: 1, name: '当天' },
|
||||
{ id: 2, name: '自定义' }
|
||||
{ id: 2, name: '自定义' },
|
||||
{ id: 3, name: '上一班' }
|
||||
],
|
||||
width: 80,
|
||||
width: 100,
|
||||
onchange: true,
|
||||
// defaultSelect: 1,
|
||||
clearable: false,
|
||||
@@ -438,6 +496,7 @@ export default {
|
||||
{ id: 4, name: '年' }
|
||||
],
|
||||
width: 80,
|
||||
onchange: true,
|
||||
param: 'reportType'
|
||||
},
|
||||
{
|
||||
@@ -513,17 +572,20 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.buttonNav) {
|
||||
this.$refs.buttonNav.currentMenu = '按产品监控';
|
||||
this.formConfig[0].selectOptions = this.timeTypeOptions.product;
|
||||
}
|
||||
if (this.$refs.searchBarForm) {
|
||||
// this.$refs.searchBarForm.formInline.timeVal = [
|
||||
// yesterday.getTime(),
|
||||
// end.getTime()
|
||||
// ];
|
||||
|
||||
this.$refs.searchBarForm.formInline.timeType = 1
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
this.getProductList();
|
||||
this.getDayDataList();
|
||||
this.getPdLineList();
|
||||
const queryParams = {
|
||||
pageNo: 1,
|
||||
@@ -579,15 +641,21 @@ export default {
|
||||
|
||||
// 4. 根据类型设置差异化的表单配置(仅处理不同的部分)
|
||||
if (isProductLine) {
|
||||
// 按产线监控:显示产线,隐藏产品工艺和类型
|
||||
// 按产线监控:显示产线,隐藏产品工艺和类型,时间维度包含上一班
|
||||
this.formConfig[0].selectOptions = this.timeTypeOptions.productLine; // 恢复上一班选项
|
||||
this.formConfig[3].type = 'select'; // 显示产线
|
||||
this.formConfig[4].type = ''; // 隐藏产品工艺
|
||||
this.formConfig[5].type = ''; // 隐藏产品类型
|
||||
this.getDayDataList();
|
||||
|
||||
} else {
|
||||
// 按产品监控:显示产品工艺和类型,隐藏产线
|
||||
// 按产品监控:显示产品工艺和类型,隐藏产线,时间维度移除上一班
|
||||
this.formConfig[0].selectOptions = this.timeTypeOptions.product; // 不含上一班
|
||||
this.formConfig[3].type = ''; // 隐藏产线
|
||||
this.formConfig[4].type = 'select'; // 显示产品工艺
|
||||
this.formConfig[5].type = 'select'; // 显示产品类型
|
||||
this.getProductList();
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
@@ -596,48 +664,52 @@ export default {
|
||||
// 按产线监控
|
||||
if (this.activeName === 'productLine') {
|
||||
if (this.listQuery.timeType === 1) {
|
||||
// 产线-当天:导出当班 + 当天两个表格
|
||||
// 产线-当天:导出当班 + 当天两个表格(自定义汇总文件名)
|
||||
this.exportMultipleTables([
|
||||
{ ref: 'lineCurrentShiftTable', name: '产线监控_当班数据' },
|
||||
{ ref: 'lineTodayTable', name: '产线监控_当天数据' }
|
||||
]);
|
||||
], '产线监控_当班及当天数据汇总'); // 传入自定义汇总文件名
|
||||
} else if (this.listQuery.timeType === 1) {
|
||||
// 产线-当天:导出当班 + 当天两个表格(自定义汇总文件名)
|
||||
this.exportMultipleTables([
|
||||
{ ref: 'lineCurrentShiftTable', name: '产线监控_上一班数据' },
|
||||
{ ref: 'lineTodayTable', name: '产线监控_当天数据' }
|
||||
], '产线监控_当班及当天数据汇总'); // 传入自定义汇总文件名
|
||||
} else {
|
||||
// 产线-自定义:导出一个表格
|
||||
// 产线-自定义:导出一个表格(自定义文件名)
|
||||
this.exportSingleTable('lineCustomTable', '产线监控_自定义时间数据');
|
||||
}
|
||||
}
|
||||
// 按产品监控
|
||||
else {
|
||||
if (this.listQuery.timeType === 1) {
|
||||
// 产品-当天:导出当班 + 当天两个表格
|
||||
// 产品-当天:导出当班 + 当天两个表格(自定义汇总文件名)
|
||||
this.exportMultipleTables([
|
||||
{ ref: 'productCurrentShiftTable', name: '产品监控_当班数据' },
|
||||
{ ref: 'productTodayTable', name: '产品监控_当天数据' }
|
||||
]);
|
||||
], '产品监控_当班及当天数据汇总'); // 传入自定义汇总文件名
|
||||
} else {
|
||||
// 产品-自定义:导出一个表格
|
||||
// 产品-自定义:导出一个表格(自定义文件名)
|
||||
this.exportSingleTable('productCustomTable', '产品监控_自定义时间数据');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 导出单个表格
|
||||
// 导出单个表格(保持原有逻辑,文件名由调用方传入,已区分不同场景)
|
||||
exportSingleTable(refName, fileName) {
|
||||
const table = this.getTableDom(refName);
|
||||
if (!table) return;
|
||||
|
||||
// 克隆表格并移除固定列
|
||||
const clonedTable = table.cloneNode(true);
|
||||
this.removeFixedColumns(clonedTable);
|
||||
this.adjustTableForExport(clonedTable);
|
||||
|
||||
// 转换为工作簿并导出
|
||||
const workbook = XLSX.utils.table_to_book(clonedTable);
|
||||
const fullName = `${fileName}_${this.formatDate()}.xlsx`;
|
||||
XLSX.writeFile(workbook, fullName);
|
||||
},
|
||||
|
||||
// 导出多个表格(同一个Excel的不同sheet)
|
||||
exportMultipleTables(tables) {
|
||||
// 导出多个表格(新增自定义汇总文件名参数,适配不同选项卡)
|
||||
exportMultipleTables(tables, customSummaryName) {
|
||||
const workbook = XLSX.utils.book_new();
|
||||
let hasValidTable = false;
|
||||
|
||||
@@ -646,11 +718,9 @@ export default {
|
||||
if (!table) return;
|
||||
|
||||
hasValidTable = true;
|
||||
// 克隆表格并移除固定列
|
||||
const clonedTable = table.cloneNode(true);
|
||||
this.removeFixedColumns(clonedTable);
|
||||
this.adjustTableForExport(clonedTable);
|
||||
|
||||
// 转换为sheet并添加到工作簿
|
||||
const worksheet = XLSX.utils.table_to_sheet(clonedTable);
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, name);
|
||||
});
|
||||
@@ -660,31 +730,128 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// 导出包含多个sheet的Excel
|
||||
const fullName = `生产监控数据汇总_${this.formatDate()}.xlsx`;
|
||||
// 动态生成汇总文件名:自定义名称 + 日期
|
||||
const fullName = `${customSummaryName}_${this.formatDate()}.xlsx`;
|
||||
XLSX.writeFile(workbook, fullName);
|
||||
},
|
||||
|
||||
// 辅助方法:获取表格DOM元素
|
||||
// 辅助方法:获取表格DOM元素(包含表头)
|
||||
getTableDom(refName) {
|
||||
const tableComponent = this.$refs[refName];
|
||||
if (!tableComponent) {
|
||||
this.$message.warning(`未找到${refName}表格`);
|
||||
return null;
|
||||
}
|
||||
// 获取表格组件内部的el-table DOM
|
||||
const tableDom = tableComponent.$el.querySelector('.el-table__body-wrapper table');
|
||||
if (!tableDom) {
|
||||
// 获取完整表格容器(包含表头和表体)
|
||||
const tableContainer = tableComponent.$el.querySelector('.el-table');
|
||||
if (!tableContainer) {
|
||||
this.$message.warning(`${refName}表格数据为空`);
|
||||
return null;
|
||||
}
|
||||
return tableDom;
|
||||
return tableContainer;
|
||||
},
|
||||
|
||||
// 辅助方法:移除固定列(避免重复导出)
|
||||
removeFixedColumns(table) {
|
||||
const fixedColumns = table.querySelectorAll('.el-table__fixed, .el-table__fixed-right');
|
||||
fixedColumns.forEach(col => col.remove());
|
||||
// 重点修复:调整表格结构(解决表头重复问题)
|
||||
adjustTableForExport(tableContainer) {
|
||||
// 1. 移除空表格提示和分页等无关元素
|
||||
const emptyCells = tableContainer.querySelectorAll('.el-table__empty-block, .el-pagination');
|
||||
emptyCells.forEach(cell => cell.remove());
|
||||
|
||||
// 2. 定位核心元素
|
||||
const mainTable = tableContainer.querySelector('.el-table__body-wrapper table'); // 主表体
|
||||
const fixedLeft = tableContainer.querySelector('.el-table__fixed'); // 左固定列容器
|
||||
const fixedRight = tableContainer.querySelector('.el-table__fixed-right'); // 右固定列容器
|
||||
|
||||
// 3. 提取所有表头行(支持多级表头,按层级收集)
|
||||
const allHeaderRows = []; // 存储所有层级的表头行(每行是一个单元格数组)
|
||||
|
||||
// 辅助函数:提取某个容器内的所有表头行(处理多级表头)
|
||||
const extractHeaderRows = (container) => {
|
||||
const headerWrapper = container?.querySelector('.el-table__header-wrapper table');
|
||||
if (!headerWrapper) return [];
|
||||
const thead = headerWrapper.querySelector('thead');
|
||||
if (!thead) return [];
|
||||
// 多级表头可能有多个tr(行)
|
||||
const headerRows = Array.from(thead.querySelectorAll('tr'));
|
||||
return headerRows.map(row => Array.from(row.querySelectorAll('th'))); // 每行的单元格数组
|
||||
};
|
||||
|
||||
// 收集左固定列的表头行(可能有多层)
|
||||
const fixedLeftHeaderRows = extractHeaderRows(fixedLeft);
|
||||
// 收集主表头的表头行(可能有多层)
|
||||
const mainHeaderRows = extractHeaderRows(tableContainer);
|
||||
// 收集右固定列的表头行(可能有多层)
|
||||
const fixedRightHeaderRows = extractHeaderRows(fixedRight);
|
||||
|
||||
// 4. 合并表头行(按层级对齐,左固定列 → 主表头 → 右固定列)
|
||||
// 确定最大表头层级(多级表头的行数)
|
||||
const maxLevel = Math.max(
|
||||
fixedLeftHeaderRows.length,
|
||||
mainHeaderRows.length,
|
||||
fixedRightHeaderRows.length
|
||||
);
|
||||
|
||||
// 按层级合并每行的单元格
|
||||
for (let i = 0; i < maxLevel; i++) {
|
||||
const rowCells = [];
|
||||
// 左固定列当前层级的单元格(不足则补空)
|
||||
rowCells.push(...(fixedLeftHeaderRows[i] || []));
|
||||
// 主表头当前层级的单元格(不足则补空)
|
||||
rowCells.push(...(mainHeaderRows[i] || []));
|
||||
// 右固定列当前层级的单元格(不足则补空)
|
||||
rowCells.push(...(fixedRightHeaderRows[i] || []));
|
||||
allHeaderRows.push(rowCells);
|
||||
}
|
||||
|
||||
// 5. 清理所有原有表头和固定列容器(避免干扰)
|
||||
tableContainer.querySelectorAll('thead').forEach(thead => thead.remove());
|
||||
tableContainer.querySelectorAll('.el-table__header-wrapper').forEach(wrapper => wrapper.remove());
|
||||
[fixedLeft, fixedRight].forEach(container => container?.remove());
|
||||
|
||||
// 6. 构建唯一表头并添加到主表体(支持多级表头)
|
||||
if (mainTable && allHeaderRows.length > 0) {
|
||||
const newThead = document.createElement('thead');
|
||||
// 按层级添加表头行
|
||||
allHeaderRows.forEach(cells => {
|
||||
const newTr = document.createElement('tr');
|
||||
cells.forEach(cell => {
|
||||
// 复制单元格(避免DOM残留引用问题)
|
||||
const clonedCell = cell.cloneNode(true);
|
||||
newTr.appendChild(clonedCell);
|
||||
});
|
||||
newThead.appendChild(newTr);
|
||||
});
|
||||
// 将新表头插入主表体最前面
|
||||
mainTable.insertBefore(newThead, mainTable.firstChild);
|
||||
}
|
||||
|
||||
// 7. 合并固定列数据到主表体(仅处理tbody数据)
|
||||
// 合并左固定列数据
|
||||
if (fixedLeft && mainTable) {
|
||||
const fixedLeftRows = fixedLeft.querySelectorAll('.el-table__body-wrapper tbody tr');
|
||||
const mainRows = mainTable.querySelectorAll('tbody tr');
|
||||
fixedLeftRows.forEach((fixedRow, index) => {
|
||||
if (mainRows[index]) {
|
||||
const fixedCells = Array.from(fixedRow.querySelectorAll('td'));
|
||||
fixedCells.forEach(cell => {
|
||||
mainRows[index].insertBefore(cell.cloneNode(true), mainRows[index].firstChild);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 合并右固定列数据
|
||||
if (fixedRight && mainTable) {
|
||||
const fixedRightRows = fixedRight.querySelectorAll('.el-table__body-wrapper tbody tr');
|
||||
const mainRows = mainTable.querySelectorAll('tbody tr');
|
||||
fixedRightRows.forEach((fixedRow, index) => {
|
||||
if (mainRows[index]) {
|
||||
const fixedCells = Array.from(fixedRow.querySelectorAll('td'));
|
||||
fixedCells.forEach(cell => {
|
||||
mainRows[index].appendChild(cell.cloneNode(true));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 辅助方法:格式化日期(用于文件名)
|
||||
@@ -698,7 +865,6 @@ export default {
|
||||
String(date.getMinutes()).padStart(2, '0')
|
||||
].join('');
|
||||
},
|
||||
|
||||
// 获取产线和工厂列表
|
||||
getPdLineList() {
|
||||
getPdList().then(res => {
|
||||
@@ -712,28 +878,85 @@ export default {
|
||||
|
||||
// 搜索/导出按钮点击
|
||||
buttonClick(val) {
|
||||
if (this.activeName === 'productLine') {
|
||||
this.listQuery.pageNo = 1;
|
||||
this.listQuery.pageSize = 10;
|
||||
this.listQuery.factoryId = val.factoryId || undefined;
|
||||
this.listQuery.process = val.process ? val.process : [];
|
||||
this.listQuery.lineId = val.lineId ? val.lineId : [];
|
||||
this.listQuery.processType = val.processType ? val.processType : [];
|
||||
this.listQuery.reportType = val.reportType || undefined;
|
||||
this.listQuery.timeType = val.timeType || undefined;
|
||||
this.listQuery.searchType = val.searchType || undefined;
|
||||
|
||||
// 处理不同时间选择类型
|
||||
if (val.timeVal) {
|
||||
this.listQuery.startTime = val.timeVal[0];
|
||||
this.listQuery.endTime = val.timeVal[1];
|
||||
} else if (val.timeValWeek) {
|
||||
// 周选择器
|
||||
const { startTime, endTime } = this.getWeekTimeRange(val.timeValWeek);
|
||||
this.listQuery.startTime = startTime;
|
||||
this.listQuery.endTime = endTime;
|
||||
} else if (val.timeValMonth) {
|
||||
// 月选择器
|
||||
this.listQuery.startTime = val.timeValMonth[0];
|
||||
this.listQuery.endTime = val.timeValMonth[1];
|
||||
} else if (val.timeValYear) {
|
||||
// 年选择器
|
||||
const { startTime, endTime } = this.getYearTimeRange(val.timeValYear);
|
||||
this.listQuery.startTime = startTime;
|
||||
this.listQuery.endTime = endTime;
|
||||
} else {
|
||||
this.listQuery.startTime = undefined;
|
||||
this.listQuery.endTime = undefined;
|
||||
}
|
||||
} else {
|
||||
this.listQuery.pageNo = 1;
|
||||
this.listQuery.pageSize = 10;
|
||||
this.listQuery.factoryId = val.factoryId || []
|
||||
this.listQuery.process = val.process ? val.process : [];
|
||||
this.listQuery.lineId = undefined;
|
||||
this.listQuery.processType = val.processType ? val.processType : [];
|
||||
this.listQuery.reportType = val.reportType || undefined;
|
||||
this.listQuery.timeType = val.timeType || undefined;
|
||||
this.listQuery.searchType = val.searchType || undefined;
|
||||
|
||||
// 处理不同时间选择类型
|
||||
if (val.timeVal) {
|
||||
this.listQuery.startTime = val.timeVal[0];
|
||||
this.listQuery.endTime = val.timeVal[1];
|
||||
} else if (val.timeValWeek) {
|
||||
// 周选择器
|
||||
const { startTime, endTime } = this.getWeekTimeRange(val.timeValWeek);
|
||||
this.listQuery.startTime = startTime;
|
||||
this.listQuery.endTime = endTime;
|
||||
} else if (val.timeValMonth) {
|
||||
// 月选择器
|
||||
this.listQuery.startTime = val.timeValMonth[0];
|
||||
this.listQuery.endTime = val.timeValMonth[1];
|
||||
} else if (val.timeValYear) {
|
||||
// 年选择器
|
||||
const { startTime, endTime } = this.getYearTimeRange(val.timeValYear);
|
||||
this.listQuery.startTime = startTime;
|
||||
this.listQuery.endTime = endTime;
|
||||
} else {
|
||||
this.listQuery.startTime = undefined;
|
||||
this.listQuery.endTime = undefined;
|
||||
}
|
||||
}
|
||||
switch (val.btnName) {
|
||||
case 'search':
|
||||
this.listQuery.pageNo = 1;
|
||||
this.listQuery.pageSize = 10;
|
||||
this.listQuery.factoryId = val.factoryId || undefined;
|
||||
this.listQuery.process = val.process ? val.process : [];
|
||||
this.listQuery.lineId = val.lineId ? val.lineId : [];
|
||||
this.listQuery.processType = val.processType ? val.processType : [];
|
||||
this.listQuery.reportType = val.reportType || undefined;
|
||||
this.listQuery.timeType = val.timeType || undefined;
|
||||
this.listQuery.searchType = val.searchType || undefined;
|
||||
this.listQuery.startTime = val.timeVal ? val.timeVal[0] : undefined;
|
||||
this.listQuery.endTime = val.timeVal ? val.timeVal[1] : undefined;
|
||||
if (this.activeName === 'productLine') {
|
||||
if (this.listQuery.timeType === 1) {
|
||||
this.getDayDataList();
|
||||
} else if (this.listQuery.timeType === 3) {
|
||||
this.getLastDayDataList();
|
||||
} else {
|
||||
this.getDataList();
|
||||
}
|
||||
} else {
|
||||
this.getProductList();
|
||||
|
||||
this.getProductList();
|
||||
}
|
||||
break;
|
||||
case 'export':
|
||||
@@ -742,6 +965,9 @@ export default {
|
||||
case 'reset':
|
||||
this.$refs.searchBarForm.resetForm();
|
||||
this.$refs.searchBarForm.formInline.timeType = 1;
|
||||
this.formConfig[0].selectOptions = this.activeName === 'productLine'
|
||||
? this.timeTypeOptions.productLine
|
||||
: this.timeTypeOptions.product;
|
||||
this.listQuery = {
|
||||
pageSize: 100,
|
||||
pageNo: 1,
|
||||
@@ -750,12 +976,9 @@ export default {
|
||||
};
|
||||
if (this.activeName === 'productLine') {
|
||||
this.getDayDataList();
|
||||
|
||||
} else {
|
||||
this.getProductList();
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
console.log(val);
|
||||
@@ -763,8 +986,8 @@ export default {
|
||||
},
|
||||
|
||||
getDataList() {
|
||||
if(!this.listQuery.startTime &&!this.listQuery.endTime ){
|
||||
return this.$modal.msgError('请选择时间');
|
||||
if (!this.listQuery.startTime && !this.listQuery.endTime) {
|
||||
return this.$modal.msgError('请选择时间');
|
||||
}
|
||||
this.dataListLoading = true;
|
||||
// const arr = ['日', '周', '月', '年'];
|
||||
@@ -798,7 +1021,7 @@ export default {
|
||||
console.log('resGroup');
|
||||
if (this.listQuery.timeType === 2) {
|
||||
const resGroup = await getProcessAutoReportNew(this.listQuery);
|
||||
console.log('resGroup',resGroup);
|
||||
console.log('resGroup', resGroup);
|
||||
|
||||
// 格式化数据:lineDetList提取到外层,键名加lineId前缀
|
||||
const formatData = (rawList) => {
|
||||
@@ -827,7 +1050,7 @@ export default {
|
||||
|
||||
// 处理当班和当天数据(分别存储)
|
||||
this.productTableData = formatData(resGroup.data.list); // 当班数据
|
||||
console.log(this.productTableData,'productTableData');
|
||||
console.log(this.productTableData, 'productTableData');
|
||||
|
||||
// --------------------------
|
||||
// 生成当班数据的动态表头
|
||||
@@ -1005,6 +1228,28 @@ export default {
|
||||
return [...lineColumns, totalColumn];
|
||||
},
|
||||
// 为当天时调用的接口
|
||||
getLastDayDataList() {
|
||||
getPdlAutoReportNewSearchLastGroup().then((response) => {
|
||||
this.tableData = response.data.classData.map((item, index) => {
|
||||
item.originalLossNum = item.original?.lossNum;
|
||||
item.originalLossArea = item.original?.lossArea;
|
||||
item.edgeLossNum = item.edge?.lossNum;
|
||||
item.edgeLossArea = item.edge?.lossArea;
|
||||
item.drillLossNum = item.drill?.lossNum;
|
||||
item.drillLossArea = item.drill?.lossArea;
|
||||
item.coatingLossNum = item.coating?.lossNum;
|
||||
item.coatingLossArea = item.coating?.lossArea;
|
||||
item.silkLossNum = item.silk?.lossNum;
|
||||
item.silkLossArea = item.silk?.lossArea;
|
||||
item.temperingLossNum = item.tempering?.lossNum;
|
||||
item.temperingLossArea = item.tempering?.lossArea;
|
||||
item.packingLossNum = item.packing?.lossNum;
|
||||
item.packingLossArea = item.packing?.lossArea;
|
||||
return item;
|
||||
});
|
||||
// console.log(this.tableData, this.tableData2);
|
||||
});
|
||||
},
|
||||
getDayDataList() {
|
||||
getPdlAutoReportNewSearchNow().then((response) => {
|
||||
this.tableData = response.data.classData.map((item, index) => {
|
||||
@@ -1060,28 +1305,26 @@ export default {
|
||||
|
||||
// 搜索栏下拉选择变化
|
||||
handleSearchBarChanged({ param, value }) {
|
||||
console.log(value, param);
|
||||
if (param === 'timeType') {
|
||||
console.log(value);
|
||||
|
||||
this.listQuery.timeType = value;
|
||||
if (value === 1) {
|
||||
// 切换为“当天”:隐藏查询类型、报表类型、时间范围
|
||||
if (value === 2) {
|
||||
// 切换为“自定义”:显示查询类型和时间范围
|
||||
this.formConfig[1].type = 'select';
|
||||
this.$refs.searchBarForm.formInline.timeType = value;
|
||||
this.listQuery.timeType = value;
|
||||
this.formConfig[7].type = 'datePicker';
|
||||
} else {
|
||||
this.formConfig[1].type = '';
|
||||
this.formConfig[6].type = '';
|
||||
this.formConfig[7].type = '';
|
||||
this.$refs.searchBarForm.formInline.timeType = value;
|
||||
this.listQuery.timeType = value;
|
||||
|
||||
this.$refs.searchBarForm.formInline.searchType = undefined;
|
||||
this.$refs.searchBarForm.formInline.reportType = undefined;
|
||||
this.$refs.searchBarForm.formInline.timeVal = undefined;
|
||||
} else {
|
||||
// 切换为“自定义”:显示查询类型和时间范围
|
||||
this.formConfig[1].type = 'select';
|
||||
this.$refs.searchBarForm.formInline.timeType = value;
|
||||
this.listQuery.timeType = value;
|
||||
|
||||
this.formConfig[7].type = 'datePicker';
|
||||
}
|
||||
} else if (param === 'searchType') {
|
||||
if (value === 1) {
|
||||
@@ -1095,7 +1338,74 @@ export default {
|
||||
this.formConfig[7].type = 'datePicker';
|
||||
}
|
||||
} else if (param === 'reportType') {
|
||||
this.$refs.searchBarForm.formInline.timeVal = undefined;
|
||||
if (this.$refs.searchBarForm && this.$refs.searchBarForm.formInline) {
|
||||
const formInline = this.$refs.searchBarForm.formInline;
|
||||
// 精准判断:只有字段存在时,才置为undefined(不存在则不处理)
|
||||
if ('timeVal' in formInline) {
|
||||
formInline.timeVal = undefined;
|
||||
}
|
||||
if ('timeValWeek' in formInline) {
|
||||
formInline.timeValWeek = undefined;
|
||||
}
|
||||
if ('timeValMonth' in formInline) {
|
||||
formInline.timeValMonth = undefined;
|
||||
}
|
||||
if ('timeValYear' in formInline) {
|
||||
formInline.timeValYear = undefined;
|
||||
}
|
||||
}
|
||||
this.listQuery.startTime = undefined;
|
||||
this.listQuery.endTime = undefined;
|
||||
if (value === 1) {
|
||||
this.formConfig[7] = {
|
||||
type: 'datePicker',
|
||||
label: '时间范围',
|
||||
dateType: 'datetimerange',
|
||||
format: 'yyyy-MM-dd HH:mm:ss',
|
||||
valueFormat: 'timestamp',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
param: 'timeVal',
|
||||
width: 350
|
||||
};
|
||||
} else if (value === 2) {
|
||||
this.formConfig[7] = {
|
||||
type: 'datePicker',
|
||||
label: '时间范围',
|
||||
dateType: 'week',
|
||||
placeholder: '选择日期',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'yyyy-MM-dd',
|
||||
param: 'timeValWeek',
|
||||
width: 250,
|
||||
};
|
||||
} else if (value === 3) {
|
||||
this.formConfig[7] = {
|
||||
type: 'datePicker',
|
||||
label: '时间范围',
|
||||
dateType: 'monthrange',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'timestamp',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
param: 'timeValMonth',
|
||||
defaultTime: ['00:00:00', '23:59:59'],
|
||||
width: 250,
|
||||
};
|
||||
} else if (value === 4) {
|
||||
this.formConfig[7] = {
|
||||
type: 'datePicker',
|
||||
label: '时间范围',
|
||||
dateType: 'year',
|
||||
placeholder: '选择年份',
|
||||
format: 'yyyy',
|
||||
valueFormat: 'timestamp',
|
||||
param: 'timeValYear',
|
||||
width: 250,
|
||||
};
|
||||
}
|
||||
} else if (param === 'factoryId') {
|
||||
// 切换工厂时刷新产线列表
|
||||
this.listQuery.lineId = [];
|
||||
@@ -1142,7 +1452,7 @@ export default {
|
||||
.content-wrapper {
|
||||
// flex: 1;
|
||||
width: 100%;
|
||||
height: calc(100vh - 303px);
|
||||
height: calc(100vh - 280px);
|
||||
// overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
<!--
|
||||
* @Author: Do not edit
|
||||
* @Date: 2023-08-29 14:59:29
|
||||
* @LastEditTime: 2024-12-02 13:44:47
|
||||
* @LastEditors: zwq
|
||||
* @Description:
|
||||
-->
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- :isFold="true" 控制展开 -->
|
||||
<search-bar :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick" />
|
||||
<search-bar :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick"
|
||||
@select-changed="selectType" />
|
||||
<base-table v-if="tableData.length" class="right-aside" v-loading="dataListLoading" :table-props="tableProps"
|
||||
:page="listQuery.pageNo" :limit="listQuery.pageSize" :table-data="tableData">
|
||||
<method-btn v-if="tableBtn.length" slot="handleBtn" :width="120" label="操作" :method-list="tableBtn"
|
||||
@@ -17,34 +11,47 @@
|
||||
<div v-else class="no-data-bg"></div>
|
||||
<pagination :limit.sync="listQuery.pageSize" :page.sync="listQuery.pageNo" :total="listQuery.total"
|
||||
@pagination="getDataList" />
|
||||
<!-- <el-dialog
|
||||
title="提示"
|
||||
:visible.sync="dialogVisible"
|
||||
width="30%"
|
||||
:before-close="handleClose">
|
||||
<el-button type="primary" @click="exportXlsx">xlsx</el-button>
|
||||
<el-button type="success" @click="exportPdf">pdf</el-button>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog> -->
|
||||
<add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue';
|
||||
import AddOrUpdate from './add-or-updata';
|
||||
|
||||
import { parseTime } from '../../mixins/code-filter';
|
||||
import { getCostOriginRadioHisData, getPdList } from '@/api/core/monitoring/index'
|
||||
import * as XLSX from 'xlsx'
|
||||
import FileSaver from 'file-saver'
|
||||
import jsPDF from 'jspdf'
|
||||
import html2canvas from 'html2canvas'
|
||||
import { getCostOriginRadioHisData, getPdList } from '@/api/core/monitoring/index';
|
||||
import { exportCostOriginRadioHisData } from '../../../../api/core/monitoring';
|
||||
|
||||
const tableProps = [
|
||||
// Vue2 中注册全局方法(如果需要)
|
||||
Vue.prototype.$download = Vue.prototype.$download || {
|
||||
excel: (response, fileName) => {
|
||||
const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const aLink = document.createElement('a');
|
||||
aLink.style.display = 'none';
|
||||
aLink.href = url;
|
||||
aLink.setAttribute('download', fileName);
|
||||
document.body.appendChild(aLink);
|
||||
aLink.click();
|
||||
document.body.removeChild(aLink);
|
||||
window.URL.revokeObjectURL(url);
|
||||
}
|
||||
};
|
||||
|
||||
Vue.prototype.$modal = Vue.prototype.$modal || {
|
||||
confirm: (message) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (window.confirm(message)) {
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const tableProps = [
|
||||
{
|
||||
prop: 'reportType',
|
||||
label: '报表类型'
|
||||
@@ -52,12 +59,11 @@ const tableProps = [
|
||||
{
|
||||
prop: 'time',
|
||||
label: '日期',
|
||||
// filter: parseTime,
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
{
|
||||
prop: 'bindObjectName',
|
||||
label: '产线'
|
||||
label: '产线'
|
||||
},
|
||||
{
|
||||
prop: 'thick',
|
||||
@@ -67,11 +73,11 @@ const tableProps = [
|
||||
prop: 'speed',
|
||||
label: '在线速度'
|
||||
},
|
||||
{
|
||||
{
|
||||
prop: 'width',
|
||||
label: '掰边宽度'
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
prop: 'inArea',
|
||||
label: '拉引量/㎡'
|
||||
},
|
||||
@@ -79,21 +85,83 @@ const tableProps = [
|
||||
prop: 'outArea',
|
||||
label: '下片面积/㎡'
|
||||
},
|
||||
{
|
||||
{
|
||||
prop: 'ratio',
|
||||
label: '良品率'
|
||||
},
|
||||
label: '良品率/%'
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 工具函数:获取选择时间所在周的起始和结束时间(Vue2 兼容)
|
||||
* @param {String|Date} selectTime - 选择的时间(支持格式:yyyy-MM-dd、yyyy-MM-dd HH:mm:ss 或 Date 对象)
|
||||
* @returns {Array} [startDate, endDate] - 所在周周一 00:00:00 至 周日 23:59:59(Date 对象)
|
||||
*/
|
||||
function getSelectedWeekRange(selectTime) {
|
||||
// 兼容 String 类型时间和 Date 对象,统一转为 Date 实例
|
||||
const targetDate = new Date(selectTime);
|
||||
// 处理无效日期(若传入非法时间,返回当前时间的本周范围)
|
||||
// if (isNaN(targetDate.getTime())) {
|
||||
// console.warn('传入的时间格式无效,将使用当前时间计算本周范围');
|
||||
// return getCurrentWeekRange(); // 可根据需求改为抛出错误或返回空
|
||||
// }
|
||||
|
||||
const day = targetDate.getDay() || 7; // 周日为 7(避免周日 -0 天仍为周日)
|
||||
const start = new Date(targetDate);
|
||||
start.setDate(targetDate.getDate() - day + 1); // 计算所在周的周一
|
||||
start.setHours(0, 0, 0, 0); // 重置时分秒为 00:00:00.000
|
||||
|
||||
const end = new Date(start);
|
||||
end.setDate(start.getDate() + 6); // 周一 +6 天 = 周日
|
||||
end.setHours(23, 59, 59, 999); // 重置时分秒为 23:59:59.999
|
||||
|
||||
return [start, end];
|
||||
}
|
||||
|
||||
/**
|
||||
* 工具函数:获取选择时间所在年的起始和结束时间(Vue2 兼容)
|
||||
* @param {String|Date} selectTime - 选择的时间(支持格式:yyyy-MM-dd、yyyy-MM-dd HH:mm:ss 或 Date 对象)
|
||||
* @returns {Array} [startDate, endDate] - 所在年 1月1日 00:00:00 至 12月31日 23:59:59(Date 对象)
|
||||
*/
|
||||
function getSelectedYearRange(selectTime) {
|
||||
// 兼容 String 类型时间和 Date 对象,统一转为 Date 实例
|
||||
const targetDate = new Date(selectTime);
|
||||
// 处理无效日期(若传入非法时间,返回当前时间的本年范围)
|
||||
// if (isNaN(targetDate.getTime())) {
|
||||
// console.warn('传入的时间格式无效,将使用当前时间计算本年范围');
|
||||
// return getCurrentYearRange(); // 可根据需求改为抛出错误或返回空
|
||||
// }
|
||||
|
||||
const year = targetDate.getFullYear(); // 获取选择时间的年份
|
||||
const start = new Date(year, 0, 1); // 所在年 1月1日(月份从 0 开始)
|
||||
start.setHours(0, 0, 0, 0); // 重置时分秒为 00:00:00.000
|
||||
|
||||
const end = new Date(year, 11, 31); // 所在年 12月31日(11 代表 12 月)
|
||||
end.setHours(23, 59, 59, 999); // 重置时分秒为 23:59:59.999
|
||||
|
||||
return [start, end];
|
||||
}
|
||||
|
||||
// 格式化时间为 yyyy-MM-dd HH:mm:ss(Vue2 兼容)
|
||||
function formatDateTime(date) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AddOrUpdate
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
urlOptions: {
|
||||
getDataListURL: getCostOriginRadioHisData
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
urlOptions: {
|
||||
getDataListURL: getCostOriginRadioHisData
|
||||
},
|
||||
tableData: [],
|
||||
listQuery: {
|
||||
pageSize: 10,
|
||||
@@ -101,181 +169,366 @@ export default {
|
||||
total: 1,
|
||||
bindObjectId: undefined,
|
||||
statisticType: undefined,
|
||||
startTime: undefined,
|
||||
endTime: undefined
|
||||
},
|
||||
pdLineList:[],
|
||||
pdLineList: [],
|
||||
exportLoading: false,
|
||||
dataListLoading: false,
|
||||
selectedList: [],
|
||||
dialogVisible: false,
|
||||
selectedList: [],
|
||||
dialogVisible: false,
|
||||
addOrEditTitle: '',
|
||||
addOrUpdateVisible: false,
|
||||
tableProps,
|
||||
tableProps,
|
||||
tableBtn: [
|
||||
{
|
||||
type: 'edit',
|
||||
btnName: '编辑',
|
||||
},
|
||||
].filter((v) => v),
|
||||
tableData: [],
|
||||
fileName: '',
|
||||
].filter(v => v),
|
||||
fileName: '',
|
||||
formConfig: [
|
||||
{
|
||||
type: 'select',
|
||||
label: '维度',
|
||||
label: '报表类型',
|
||||
onchange: true,
|
||||
selectOptions: [
|
||||
{
|
||||
id: '0',
|
||||
name:'班组'
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
name: '日'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '周'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: '月'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
name: '年'
|
||||
}
|
||||
{ id: '0', name: '班组' },
|
||||
{ id: '1', name: '日' },
|
||||
{ id: '2', name: '周' },
|
||||
{ id: '3', name: '月' },
|
||||
{ id: '4', name: '年' }
|
||||
],
|
||||
param: 'statisticType'
|
||||
param: 'statisticType',
|
||||
index: 1,
|
||||
extraOptions: [
|
||||
{
|
||||
parent: 'statisticType',
|
||||
type: 'datePicker',
|
||||
label: '统计时间',
|
||||
dateType: 'daterange',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
param: 'timeVal',
|
||||
defaultTime: ['00:00:00', '23:59:59'],
|
||||
defaultSelect: [],
|
||||
width: 250,
|
||||
key: 'datePicker-0', // 唯一 key,触发重新渲染
|
||||
appendToBody: true // 优化定位:挂载到 body 下
|
||||
},
|
||||
// 日 - 日期范围选择
|
||||
{
|
||||
parent: 'statisticType',
|
||||
type: 'datePicker',
|
||||
label: '统计时间',
|
||||
dateType: 'daterange',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
param: 'timeValDay',
|
||||
defaultTime: ['00:00:00', '23:59:59'],
|
||||
defaultSelect: [],
|
||||
width: 250,
|
||||
key: 'datePicker-1', // 唯一 key,触发重新渲染
|
||||
appendToBody: true // 优化定位:挂载到 body 下
|
||||
},
|
||||
// 周 - 单个日期选择(自动获取本周范围)
|
||||
{
|
||||
parent: 'statisticType',
|
||||
type: 'datePicker',
|
||||
label: '统计时间',
|
||||
dateType: 'week',
|
||||
placeholder: '选择日期',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'yyyy-MM-dd',
|
||||
param: 'timeValWeek',
|
||||
width: 250,
|
||||
key: 'datePicker-2', // 唯一 key,触发重新渲染
|
||||
appendToBody: true // 优化定位:挂载到 body 下
|
||||
},
|
||||
// 月 - 日期范围选择
|
||||
{
|
||||
parent: 'statisticType',
|
||||
type: 'datePicker',
|
||||
label: '统计时间',
|
||||
dateType: 'monthrange',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
param: 'timeValMonth',
|
||||
defaultTime: ['00:00:00', '23:59:59'],
|
||||
width: 250,
|
||||
key: 'datePicker-3', // 唯一 key,触发重新渲染
|
||||
appendToBody: true // 优化定位:挂载到 body 下
|
||||
},
|
||||
// 年 - 单个日期选择(自动获取本年范围)
|
||||
{
|
||||
parent: 'statisticType',
|
||||
type: 'datePicker',
|
||||
label: '统计时间',
|
||||
dateType: 'year',
|
||||
placeholder: '选择年份',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'yyyy-MM-dd',
|
||||
param: 'timeValYear',
|
||||
width: 250,
|
||||
key: 'datePicker-4', // 唯一 key,触发重新渲染
|
||||
appendToBody: true // 优化定位:挂载到 body 下
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '产线',
|
||||
selectOptions: [],
|
||||
{
|
||||
type: 'select',
|
||||
label: '产线',
|
||||
selectOptions: [],
|
||||
param: 'bindObjectId'
|
||||
},
|
||||
|
||||
{
|
||||
type: 'datePicker',
|
||||
label: '统计开始时间',
|
||||
dateType: 'daterange',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: "yyyy-MM-dd HH:mm:ss",
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
param: 'timeVal',
|
||||
defaultTime: ['00:00:00', '23:59:59'],
|
||||
defaultSelect: []
|
||||
{
|
||||
type: 'button',
|
||||
btnName: '查询',
|
||||
name: 'search',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
btnName: '查询',
|
||||
name: 'search',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
type: 'separate',
|
||||
},
|
||||
{
|
||||
// type: this.$auth.hasPermi('base:factory:export') ? 'button' : '',
|
||||
type: 'button',
|
||||
btnName: '导出',
|
||||
name: 'export',
|
||||
color: 'warning',
|
||||
}
|
||||
],
|
||||
};
|
||||
},
|
||||
{
|
||||
type: 'separate',
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
btnName: '导出',
|
||||
name: 'export',
|
||||
color: 'warning',
|
||||
}
|
||||
],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
// 监听报表类型变化,强制刷新日期选择器
|
||||
'listQuery.statisticType'(newVal, oldVal) {
|
||||
if (newVal !== oldVal && this.$refs.searchBarForm) {
|
||||
// 触发 search-bar 组件重新渲染(如果 search-bar 支持)
|
||||
if (this.$refs.searchBarForm.$forceUpdate) {
|
||||
this.$refs.searchBarForm.$forceUpdate();
|
||||
}
|
||||
// 延迟重置定位,确保 DOM 已更新
|
||||
setTimeout(() => {
|
||||
const datePickerEl = this.$refs.searchBarForm.$el.querySelector('.el-date-picker');
|
||||
if (datePickerEl) {
|
||||
// 触发 Element UI 日期选择器重新计算定位(内部方法)
|
||||
const datePickerInstance = datePickerEl.__vue__;
|
||||
if (datePickerInstance && datePickerInstance.updatePopper) {
|
||||
datePickerInstance.updatePopper();
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$refs.searchBarForm.formInline.statisticType = '1';
|
||||
// Vue2 中 $refs 需在 $nextTick 中访问(确保 DOM 渲染完成)
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.searchBarForm) {
|
||||
this.$refs.searchBarForm.formInline.statisticType = '1';
|
||||
}
|
||||
});
|
||||
this.listQuery.statisticType = '1';
|
||||
this.getDataList()
|
||||
this.getPdLineList()
|
||||
},
|
||||
this.getDataList();
|
||||
this.getPdLineList();
|
||||
},
|
||||
methods: {
|
||||
selectType(val) {
|
||||
// 报表类型切换时的回调(如需扩展可在此添加逻辑)
|
||||
console.log('报表类型切换:', val);
|
||||
},
|
||||
handleClick(val) {
|
||||
console.log(val);
|
||||
console.log('操作按钮点击:', val);
|
||||
if (val.type === 'edit') {
|
||||
this.addOrUpdateVisible= true
|
||||
this.addOrUpdateVisible = true;
|
||||
// Vue2 中 $nextTick 确保子组件已渲染
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addOrUpdate.init(val.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getPdLineList() {
|
||||
getPdList().then((res) => {
|
||||
this.formConfig[1].selectOptions = res.data || []
|
||||
this.pdLineList = res.data || []; // 保存产线数据
|
||||
})
|
||||
},
|
||||
selectChange(val) {
|
||||
console.log(val)
|
||||
this.selectedList = val
|
||||
},
|
||||
buttonClick(val) {
|
||||
console.log('val', val);
|
||||
|
||||
switch (val.btnName) {
|
||||
case 'search':
|
||||
this.listQuery.pageNo = 1;
|
||||
this.listQuery.pageSize = 10;
|
||||
this.listQuery.bindObjectId = val.bindObjectId ? val.bindObjectId : undefined;
|
||||
this.listQuery.statisticType = val.statisticType ? val.statisticType : undefined;
|
||||
this.listQuery.startTime = val.timeVal ? val.timeVal[0]: undefined;
|
||||
this.listQuery.endTime = val.timeVal ? val.timeVal[1]: undefined;
|
||||
|
||||
//this.listQuery.reportEndTime = val.timeVal ? [new Date(val.timeVal[1]).getTime()] : undefined;
|
||||
this.getDataList();
|
||||
break;
|
||||
case 'export':
|
||||
this.handleExport();
|
||||
break;
|
||||
default:
|
||||
console.log(val);
|
||||
}
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true;
|
||||
this.urlOptions.getDataListURL(this.listQuery).then(response => {
|
||||
const arr = ['班组','日', '周', '月', '年'];
|
||||
this.tableData = response.data?.list?.map((item) => {
|
||||
item.reportType = arr[this.listQuery.statisticType];
|
||||
item.statisticType = this.listQuery.statisticType
|
||||
|
||||
// 匹配 bindObjectName
|
||||
const targetLine = this.pdLineList.find(line => line.id === item.bindObjectId);
|
||||
item.bindObjectName = targetLine ? targetLine.name : ''; // 赋值名称,无匹配则为空
|
||||
return item;
|
||||
});
|
||||
this.listQuery.total = response.data.total;
|
||||
this.dataListLoading = false;
|
||||
getPdLineList() {
|
||||
getPdList().then(res => {
|
||||
// Vue2 中数组赋值需确保响应式
|
||||
this.$set(this.formConfig[1], 'selectOptions', res.data || []);
|
||||
this.pdLineList = res.data || [];
|
||||
}).catch(err => {
|
||||
console.error('获取产线列表失败:', err);
|
||||
});
|
||||
},
|
||||
// 每页数
|
||||
selectChange(val) {
|
||||
console.log('选择变更:', val);
|
||||
this.selectedList = val;
|
||||
},
|
||||
buttonClick(val) {
|
||||
console.log('头部按钮点击:', val);
|
||||
switch (val.btnName) {
|
||||
case 'search':
|
||||
this.listQuery.pageNo = 1;
|
||||
this.listQuery.pageSize = 10;
|
||||
this.listQuery.bindObjectId = val.bindObjectId ? val.bindObjectId : undefined;
|
||||
this.listQuery.statisticType = val.statisticType ? val.statisticType : undefined;
|
||||
|
||||
// 处理不同时间维度的时间范围
|
||||
this.handleTimeRange(val);
|
||||
|
||||
this.getDataList();
|
||||
break;
|
||||
case 'export':
|
||||
this.handleExport();
|
||||
break;
|
||||
default:
|
||||
console.log('未知按钮:', val);
|
||||
}
|
||||
},
|
||||
// 处理不同时间维度的时间范围
|
||||
handleTimeRange(val) {
|
||||
const statisticType = val.statisticType;
|
||||
const timeVal = val.timeVal;
|
||||
|
||||
const timeValDay = val.timeValDay;
|
||||
|
||||
const timeValWeek = val.timeValWeek;
|
||||
const timeValMonth = val.timeValMonth;
|
||||
const timeValYear = val.timeValYear;
|
||||
|
||||
|
||||
// 重置时间参数
|
||||
this.listQuery.startTime = undefined;
|
||||
this.listQuery.endTime = undefined;
|
||||
|
||||
switch (statisticType) {
|
||||
case '0': // 班组 - 沿用原时间范围
|
||||
if (timeVal && timeVal.length === 2) {
|
||||
this.listQuery.startTime = timeVal[0];
|
||||
this.listQuery.endTime = timeVal[1];
|
||||
}
|
||||
break;
|
||||
case '1': // 日 - 沿用原时间范围
|
||||
if (timeValDay && timeValDay.length === 2) {
|
||||
this.listQuery.startTime = timeValDay[0];
|
||||
this.listQuery.endTime = timeValDay[1];
|
||||
}
|
||||
break;
|
||||
case '3': // 月 - 沿用原时间范围
|
||||
if (timeValMonth && timeValMonth.length === 2) {
|
||||
this.listQuery.startTime = timeValMonth[0];
|
||||
this.listQuery.endTime = timeValMonth[1];
|
||||
}
|
||||
break;
|
||||
case '2': // 周 - 自动计算本周范围
|
||||
if (timeValWeek) {
|
||||
const [start, end] = getSelectedWeekRange(timeValWeek);
|
||||
this.listQuery.startTime = formatDateTime(start);
|
||||
this.listQuery.endTime = formatDateTime(end);
|
||||
}
|
||||
break;
|
||||
case '4': // 年 - 自动计算本年范围
|
||||
if (timeValYear) {
|
||||
const [start, end] = getSelectedYearRange(timeValYear);
|
||||
this.listQuery.startTime = formatDateTime(start);
|
||||
this.listQuery.endTime = formatDateTime(end);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true;
|
||||
this.urlOptions.getDataListURL(this.listQuery)
|
||||
.then(response => {
|
||||
const arr = ['班组', '日', '周', '月', '年'];
|
||||
// Vue2 中数组赋值确保响应式
|
||||
this.tableData = (response.data?.list || []).map(item => {
|
||||
item.reportType = arr[this.listQuery.statisticType] || '';
|
||||
item.statisticType = this.listQuery.statisticType;
|
||||
|
||||
// 匹配产线名称
|
||||
const targetLine = this.pdLineList.find(line => line.id === item.bindObjectId);
|
||||
item.bindObjectName = targetLine ? targetLine.name : '';
|
||||
|
||||
return item;
|
||||
});
|
||||
this.listQuery.total = response.data?.total || 0;
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('获取数据失败:', err);
|
||||
this.tableData = [];
|
||||
this.listQuery.total = 0;
|
||||
})
|
||||
.finally(() => {
|
||||
this.dataListLoading = false;
|
||||
});
|
||||
},
|
||||
// 每页数变更
|
||||
sizeChangeHandle(val) {
|
||||
this.listQuery.pageSize = val;
|
||||
this.listQuery.pageNo = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 当前页
|
||||
// 当前页变更
|
||||
currentChangeHandle(val) {
|
||||
this.listQuery.pageNo = val;
|
||||
this.getDataList();
|
||||
},
|
||||
// 导出处理
|
||||
handleExport() {
|
||||
// 处理查询参数
|
||||
let params = { ...this.listQuery };
|
||||
params.pageNo = undefined;
|
||||
params.pageSize = undefined;
|
||||
this.$modal.confirm('是否确认导出原片报表?').then(() => {
|
||||
this.exportLoading = true;
|
||||
return exportCostOriginRadioHisData(params);
|
||||
}).then(response => {
|
||||
this.$download.excel(response, '原片报表.xls');
|
||||
this.exportLoading = false;
|
||||
}).catch(() => { });
|
||||
const params = { ...this.listQuery };
|
||||
// 移除分页参数
|
||||
delete params.pageNo;
|
||||
delete params.pageSize;
|
||||
delete params.total;
|
||||
|
||||
this.$modal.confirm('是否确认导出原片报表?')
|
||||
.then(() => {
|
||||
this.exportLoading = true;
|
||||
return exportCostOriginRadioHisData(params);
|
||||
})
|
||||
.then(response => {
|
||||
this.$download.excel(response, '原片报表.xls');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('导出失败:', err);
|
||||
})
|
||||
.finally(() => {
|
||||
this.exportLoading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
// Vue2 中监听数据变化(如需)
|
||||
watch: {
|
||||
'listQuery.statisticType'(newVal) {
|
||||
console.log('报表类型变更:', newVal);
|
||||
// 可添加类型变更后的额外逻辑
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.app-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.no-data-bg {
|
||||
height: 400px;
|
||||
background-color: #f5f7fa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.right-aside {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
274
src/views/core/monitoring/rawFilmReport/searchBar.vue
Normal file
274
src/views/core/monitoring/rawFilmReport/searchBar.vue
Normal file
@@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<div class="searchBarBox divHeight" ref="searchBarRef" :style="{ paddingRight: isFold ? '55px' : '0px' }">
|
||||
<el-form :inline="true" ref="searchBarForm" :model="formInline" class="searchBar">
|
||||
<span class="blue-block" v-if="removeBlue ? false : true"></span>
|
||||
<template v-for="item in formConfig">
|
||||
<el-form-item v-if="item.type !== ''" :key="item.param" :label="item.label ? item.label : ''"
|
||||
:required="item.required ? item.required : false">
|
||||
<el-input v-if="item.type === 'input'" v-model="formInline[item.param]"
|
||||
:size="item.size ? item.size : 'small'" clearable :disabled="item.disabled ? item.disabled : false"
|
||||
:style="item.width ? 'width:' + item.width + 'px' : 'width:200px'"
|
||||
:placeholder="item.placeholder ? item.placeholder : ''" />
|
||||
<el-select v-if="item.type === 'select'" v-model="formInline[item.param]"
|
||||
:size="item.size ? item.size : 'small'" :filterable="item.filterable ? item.filterable : false"
|
||||
:multiple="item.multiple ? item.multiple : false" :clearable="item.clearable === false ? false : true"
|
||||
:style="item.width ? 'width:' + item.width + 'px' : 'width:200px'" :placeholder="item.label" @change="
|
||||
item.onchange
|
||||
? $emit('select-changed', {
|
||||
param: item.param,
|
||||
value: formInline[item.param]
|
||||
})
|
||||
: null
|
||||
">
|
||||
<el-option v-for="(sub, i) in item.selectOptions" :key="i"
|
||||
:label="item.labelField ? sub[item.labelField] : sub['name']"
|
||||
:value="item.valueField ? sub[item.valueField] : sub['id']" />
|
||||
</el-select>
|
||||
<el-date-picker v-if="item.type === 'datePicker'" :key="item.param" :size="item.size ? item.size : 'small'"
|
||||
v-model="formInline[item.param]" :type="item.dateType" :format="item.format ? item.format : 'yyyy-MM-dd'"
|
||||
:value-format="item.valueFormat ? item.valueFormat : null" :default-time="item.defaultTime || null"
|
||||
:range-separator="item.rangeSeparator || null" :start-placeholder="item.startPlaceholder || null"
|
||||
:end-placeholder="item.endPlaceholder || null" :placeholder="item.placeholder"
|
||||
:picker-options="item.pickerOptions ? item.pickerOptions : null"
|
||||
:clearable="item.clearable === false ? false : true"
|
||||
:style="item.width ? 'width:' + item.width + 'px' : (item.dateType === 'datetimerange' ? 'width:340px' : (item.dateType === 'daterange' ? 'width:220px' : 'width:140px'))" />
|
||||
<el-autocomplete v-if="item.type === 'autocomplete'" v-model="formInline[item.param]"
|
||||
:value-key="item.valueKey ? item.valueKey : 'value'" :size="item.size ? item.size : 'small'"
|
||||
:fetch-suggestions="item.querySearch" :placeholder="item.placeholder"
|
||||
:clearable="item.clearable === false ? false : true"
|
||||
:style="item.width ? 'width:' + item.width + 'px' : 'width:200px'" filterable />
|
||||
<el-cascader v-if="item.type === 'cascader'" v-model="formInline[item.param]" :options="item.selectOptions"
|
||||
:props="item.cascaderProps" :size="item.size ? item.size : 'small'"
|
||||
:clearable="item.clearable === false ? false : true"
|
||||
:show-all-levels="item.showAllLevels === false ? false : true"
|
||||
:collapse-tags="item.collapseTags === true ? true : false"
|
||||
:style="item.width ? 'width:' + item.width + 'px' : 'width:200px'" @change="
|
||||
item.onChange
|
||||
? $emit('cascader-change', {
|
||||
param: item.param,
|
||||
value: formInline[item.param]
|
||||
})
|
||||
: null
|
||||
"></el-cascader>
|
||||
<el-button v-if="item.type === 'button'" :type="item.color" :size="item.size ? item.size : 'small'"
|
||||
:plain="item.plain ? item.plain : false" :round="item.round ? item.round : false"
|
||||
@click="headBtnClick(item.name)">{{ item.btnName }}</el-button>
|
||||
<span v-if="item.type === 'separate'" class="separateStyle"></span>
|
||||
<!-- 可用于显示其他按钮 -->
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item>
|
||||
<slot></slot>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span v-if="isFold" class="foldClass" @click='switchMode'>
|
||||
{{ isExpand ? '收起' : '展开' }}
|
||||
<i class="iconfont" :class="isExpand ? 'icon-upward' : 'icon-downward'"></i>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'SearchBar',
|
||||
props: {
|
||||
formConfigs: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
},
|
||||
removeBlue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isFold: {// 多行模式(默认否)
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const formInline = {}
|
||||
const formConfig = this.formConfigs
|
||||
let hasExtraOptions = false
|
||||
for (const obj of formConfig) {
|
||||
if (obj.type !== 'button') {
|
||||
if (obj.defaultSelect === false || obj.defaultSelect === 0) {
|
||||
formInline[obj.param] = obj.defaultSelect
|
||||
} else {
|
||||
formInline[obj.param] = obj.defaultSelect || '' // defaultSelect下拉框默认选中项
|
||||
}
|
||||
}
|
||||
if (obj.extraOptions) {
|
||||
hasExtraOptions = true
|
||||
}
|
||||
}
|
||||
return {
|
||||
formInline,
|
||||
formConfig,
|
||||
hasExtraOptions,
|
||||
isExpand: false // 是否展开(默认否)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
formConfig: {
|
||||
handler() {
|
||||
for (const obj of this.formConfig) {
|
||||
if (obj.defaultSelect) {
|
||||
this.formInline[obj.param] = obj.defaultSelect
|
||||
} else if (obj.defaultSelect === null) {
|
||||
// 需要手动从外部清除选项缓存的情况,确保在外部配置项中可直接设置null
|
||||
this.formInline[obj.param] = ''
|
||||
}
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
formInline: {
|
||||
handler: function () {
|
||||
this.$forceUpdate()
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.init()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
if (this.hasExtraOptions) {
|
||||
// 如果有额外参数就处理,如果没有就算了
|
||||
for (const obj of this.formConfig) {
|
||||
if (obj.extraOptions) {
|
||||
// 注: 对obj.extraOptions的选择是互斥的!
|
||||
this.$watch(
|
||||
`formInline.${obj.param}`,
|
||||
function (newVal) {
|
||||
let deleteCount = 0
|
||||
if (obj.index + 1 < this.formConfig.length) {
|
||||
// 如果obj不是最后一个配置
|
||||
const nextConfig = this.formConfig[obj.index + 1]
|
||||
if (nextConfig.parent && nextConfig.parent === obj.param)
|
||||
deleteCount = 1
|
||||
}
|
||||
const currentConfig = Object.assign(
|
||||
{},
|
||||
obj.extraOptions[newVal]
|
||||
)
|
||||
this.formConfig.splice(
|
||||
obj.index + 1,
|
||||
deleteCount,
|
||||
currentConfig
|
||||
)
|
||||
// 修改 formInline
|
||||
this.$set(this.formInline, currentConfig.param, '')
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headBtnClick(btnName) {
|
||||
this.formInline.btnName = btnName
|
||||
this.$emit('headBtnClick', this.formInline)
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs.searchBarForm.resetFields()
|
||||
const formInline = {}
|
||||
const formConfig = this.formConfigs
|
||||
for (const obj of formConfig) {
|
||||
if (obj.type !== 'button') {
|
||||
if (obj.defaultSelect === false || obj.defaultSelect === 0) {
|
||||
formInline[obj.param] = obj.defaultSelect
|
||||
} else {
|
||||
formInline[obj.param] = obj.defaultSelect || '' // defaultSelect下拉框默认选中项
|
||||
}
|
||||
}
|
||||
}
|
||||
this.formInline = formInline
|
||||
},
|
||||
switchMode() {// 展开和收起切换
|
||||
this.isExpand = !this.isExpand
|
||||
const element = this.$refs.searchBarRef
|
||||
if (this.isExpand) {
|
||||
element.classList.remove('divHeight')
|
||||
} else {
|
||||
element.classList.add('divHeight')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.searchBarBox {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.searchBarBox::after {
|
||||
content: "";
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.divHeight {
|
||||
height: 45px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.searchBar .blue-block {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background-color: #0B58FF;
|
||||
border-radius: 1px;
|
||||
margin-right: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.searchBar .el-form-item {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.searchBar .el-date-editor .el-range__icon {
|
||||
font-size: 16px;
|
||||
color: #0B58FF;
|
||||
}
|
||||
|
||||
.searchBar .el-input__prefix .el-icon-date {
|
||||
font-size: 16px;
|
||||
color: #0B58FF;
|
||||
}
|
||||
|
||||
.searchBar .el-input__prefix .el-icon-time {
|
||||
font-size: 16px;
|
||||
color: #0B58FF;
|
||||
}
|
||||
|
||||
.searchBar .separateStyle {
|
||||
display: inline-block;
|
||||
width: 1px;
|
||||
height: 24px;
|
||||
background: #E8E8E8;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.searchBarBox .foldClass {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
right: 0;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: #0B58FF;
|
||||
}
|
||||
|
||||
.searchBarBox .foldClass .iconfont {
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user