|
|
@@ -1,1313 +0,0 @@
|
|
|
-<template>
|
|
|
- <div class="app-container">
|
|
|
- <!-- 头部操作区域 -->
|
|
|
- <el-card style="margin-bottom: 15px;">
|
|
|
- <el-row :gutter="15" align="middle">
|
|
|
- <!-- 时间选择 -->
|
|
|
- <el-col :span="8">
|
|
|
- <div style="display: flex; align-items: center; justify-content: center;">
|
|
|
- <el-button icon="ArrowLeft" @click="navigateDay(-1)" size="small" style="margin-right: 10px;"></el-button>
|
|
|
- <el-date-picker clearable
|
|
|
- v-model="queryParams.dataDate"
|
|
|
- type="date"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- placeholder="请选择日期"
|
|
|
- style="width: 120px"
|
|
|
- size="small"
|
|
|
- @change="handleQuery">
|
|
|
- </el-date-picker>
|
|
|
- <el-button icon="ArrowRight" @click="navigateDay(1)" size="small" style="margin-left: 10px;"></el-button>
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
-
|
|
|
- <!-- 设备类型和参数选择 -->
|
|
|
- <el-col :span="10">
|
|
|
- <div style="display: flex; align-items: center; flex-wrap: nowrap; gap: 10px;">
|
|
|
- <span style="white-space: nowrap;">设备类型:</span>
|
|
|
- <el-select v-model="selectedEquipmentType" placeholder="设备类型" size="small" @change="handleEquipmentTypeChange" clearable style="flex: 1; min-width: 100px;">
|
|
|
- <el-option
|
|
|
- v-for="item in equipmentTypeOptions"
|
|
|
- :key="item.typeId"
|
|
|
- :label="item.typeName"
|
|
|
- :value="item.typeId">
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
-
|
|
|
- <span style="white-space: nowrap; margin-left: 10px;">参数:</span>
|
|
|
- <el-select v-model="selectedEquipmentParam" placeholder="设备参数" size="small" @change="handleEquipmentParamChange" clearable style="flex: 1; min-width: 100px;">
|
|
|
- <el-option
|
|
|
- v-for="item in equipmentParamOptions"
|
|
|
- :key="item.paraCode"
|
|
|
- :label="item.paraName"
|
|
|
- :value="item.paraCode">
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
-
|
|
|
- <!-- 产线选择 -->
|
|
|
- <el-col :span="6">
|
|
|
- <div style="display: flex; align-items: center;">
|
|
|
- <span style="white-space: nowrap; margin-right: 10px;">产线:</span>
|
|
|
- <el-select
|
|
|
- v-model="selectedLines"
|
|
|
- multiple
|
|
|
- collapse-tags
|
|
|
- collapse-tags-tooltip
|
|
|
- placeholder="请选择产线"
|
|
|
- size="small"
|
|
|
- @change="handleLineSelectionChange"
|
|
|
- style="flex: 1;">
|
|
|
- <el-option
|
|
|
- v-for="line in allLines"
|
|
|
- :key="line"
|
|
|
- :label="line + '#产线'"
|
|
|
- :value="line">
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-card>
|
|
|
-
|
|
|
- <!-- 产线和设备选择详情区域 -->
|
|
|
- <el-card style="margin-bottom: 15px;" v-if="selectedLines.length > 0">
|
|
|
- <!-- 同产线设备对比(选择一条产线时) -->
|
|
|
- <div v-if="selectedLines.length === 1" style="display: flex; align-items: center; flex-wrap: wrap; gap: 15px; padding: 10px;">
|
|
|
- <span style="font-weight: bold;">同产线设备对比:</span>
|
|
|
- <span>{{ selectedLines[0] }}#产线</span>
|
|
|
- <el-select
|
|
|
- v-model="selectedMetrics[selectedLines[0] + '_0']"
|
|
|
- placeholder="设备1"
|
|
|
- size="small"
|
|
|
- @change="updateQueryData"
|
|
|
- style="width: 180px;"
|
|
|
- clearable>
|
|
|
- <el-option
|
|
|
- v-for="item in equipmentList[selectedLines[0]]"
|
|
|
- :key="item.id"
|
|
|
- :label="item.name"
|
|
|
- :value="item.id">
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- <span>VS</span>
|
|
|
- <el-select
|
|
|
- v-model="selectedMetrics[selectedLines[0] + '_1']"
|
|
|
- placeholder="设备2"
|
|
|
- size="small"
|
|
|
- @change="updateQueryData"
|
|
|
- style="width: 180px;"
|
|
|
- clearable>
|
|
|
- <el-option
|
|
|
- v-for="item in equipmentList[selectedLines[0]]"
|
|
|
- :key="item.id"
|
|
|
- :label="item.name"
|
|
|
- :value="item.id">
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 跨产线设备对比(选择两条产线时) -->
|
|
|
- <div v-if="selectedLines.length === 2" style="display: flex; align-items: center; flex-wrap: wrap; gap: 15px; padding: 10px;">
|
|
|
- <template v-for="(line, index) in selectedLines" :key="line">
|
|
|
- <div v-if="index > 0" style="width: 1px; height: 24px; background-color: #dcdfe6; margin: 0 10px;"></div>
|
|
|
- <span style="font-weight: bold;">{{ index === 0 ? '产线A' : '产线B' }}:</span>
|
|
|
- <span>{{ line }}#产线</span>
|
|
|
- <el-select
|
|
|
- v-model="selectedMetrics[line]"
|
|
|
- placeholder="请选择设备"
|
|
|
- size="small"
|
|
|
- @change="updateQueryData"
|
|
|
- style="width: 180px;"
|
|
|
- clearable>
|
|
|
- <el-option
|
|
|
- v-for="item in equipmentList[line]"
|
|
|
- :key="item.id"
|
|
|
- :label="item.name"
|
|
|
- :value="item.id">
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- </el-card>
|
|
|
-
|
|
|
- <!-- 折线图和表格左右布局 -->
|
|
|
- <el-row :gutter="15">
|
|
|
- <!-- 左侧折线图 -->
|
|
|
- <el-col :span="12">
|
|
|
- <el-card style="margin-bottom: 15px;">
|
|
|
- <div ref="chartRef0" style="width: 100%; height: 400px;"></div>
|
|
|
- </el-card>
|
|
|
- <el-card style="margin-bottom: 15px;">
|
|
|
- <el-table :data="rzLineList" height="400" :span-method="spanMethod" ref="tableRef0">
|
|
|
- <el-table-column label="小时" align="center" prop="hour" width="60" />
|
|
|
- <el-table-column label="设备" align="center" prop="deviceName" width="360" />
|
|
|
- <el-table-column :label="rzLineList.length>0 ? rzLineList[0].paraName : ''" align="center" >
|
|
|
- <template #default="scope">
|
|
|
- {{ scope.row.paraValue }}
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
-
|
|
|
- <!-- 右侧表格 -->
|
|
|
- <el-col :span="12">
|
|
|
- <el-card style="margin-bottom: 15px;">
|
|
|
- <div ref="chartRef1" style="width: 100%; height: 400px;"></div>
|
|
|
- </el-card>
|
|
|
- <el-card style="margin-bottom: 15px;">
|
|
|
- <el-table :data="rzLineList1" height="400" :span-method="spanMethod" ref="tableRef1">
|
|
|
- <el-table-column label="小时" align="center" prop="hour" width="60" />
|
|
|
- <el-table-column label="设备" align="center" prop="deviceName" width="360" />
|
|
|
- <el-table-column :label="rzLineList.length>0 ? rzLineList[0].paraName : ''" align="center" >
|
|
|
- <template #default="scope">
|
|
|
- {{ scope.row.paraValue }}
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
-
|
|
|
- <!-- 分钟级数据弹窗 -->
|
|
|
- <el-dialog
|
|
|
- :title="minuteDialogTitle"
|
|
|
- v-model="minuteDialogVisible"
|
|
|
- width="80%"
|
|
|
- :before-close="handleMinuteDialogClose"
|
|
|
- append-to-body
|
|
|
- >
|
|
|
- <el-row :gutter="15">
|
|
|
- <!-- 左侧分钟级折线图 -->
|
|
|
- <el-col :span="12">
|
|
|
- <el-card style="margin-bottom: 15px;">
|
|
|
- <div ref="minuteChartRef0" style="width: 100%; height: 400px;"></div>
|
|
|
- </el-card>
|
|
|
- <el-card style="margin-bottom: 15px;">
|
|
|
- <el-table :data="minuteTableData0" height="400">
|
|
|
- <el-table-column prop="time" label="分钟" width="100" align="center"></el-table-column>
|
|
|
- <el-table-column prop="value" :label="minuteDataLabel0" align="center"></el-table-column>
|
|
|
- </el-table>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
-
|
|
|
- <!-- 右侧分钟级折线图 -->
|
|
|
- <el-col :span="12">
|
|
|
- <el-card style="margin-bottom: 15px;">
|
|
|
- <div ref="minuteChartRef1" style="width: 100%; height: 400px;"></div>
|
|
|
- </el-card>
|
|
|
- <el-card style="margin-bottom: 15px;">
|
|
|
- <el-table :data="minuteTableData1" height="400">
|
|
|
- <el-table-column prop="time" label="分钟" width="100" align="center"></el-table-column>
|
|
|
- <el-table-column prop="value" :label="minuteDataLabel1" align="center"></el-table-column>
|
|
|
- </el-table>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-dialog>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup name="gyfx">
|
|
|
-import * as echarts from 'echarts';
|
|
|
-import { listRzLine, getRzLine, delRzLine, addRzLine, updateRzLine } from "@/api/dyeing/rzLine";
|
|
|
-import { listDeviceTypes } from "@/api/dyeing/gyfx"; // 添加导入listDeviceTypes接口
|
|
|
-import { listDevice } from "@/api/dye/device";
|
|
|
-import {listHour} from "@/api/dye/hour.js";
|
|
|
-import { ref, nextTick } from 'vue';
|
|
|
-import { initTableScrollSync } from "@/utils/tableSync.js"; // 引入表格滚动同步工具
|
|
|
-
|
|
|
-const { proxy } = getCurrentInstance();
|
|
|
-
|
|
|
-const rzLineList = ref([]);
|
|
|
-const rzLineList1 = ref([]);
|
|
|
-const open = ref(false);
|
|
|
-const loading = ref(true);
|
|
|
-const showSearch = ref(true);
|
|
|
-const ids = ref([]);
|
|
|
-const single = ref(true);
|
|
|
-const multiple = ref(true);
|
|
|
-const total = ref(0);
|
|
|
-const title = ref("");
|
|
|
-const chartRef0 = ref(null);
|
|
|
-const chartRef1 = ref(null);
|
|
|
-let chartInstance0 = null;
|
|
|
-let chartInstance1 = null;
|
|
|
-
|
|
|
-// 分钟级数据相关变量
|
|
|
-const minuteDialogVisible = ref(false);
|
|
|
-const minuteDialogTitle = ref('');
|
|
|
-// 左侧分钟级数据
|
|
|
-const minuteChartRef0 = ref(null);
|
|
|
-let minuteChartInstance0 = null;
|
|
|
-const minuteTableData0 = ref([]);
|
|
|
-const minuteDataLabel0 = ref('');
|
|
|
-// 右侧分钟级数据
|
|
|
-const minuteChartRef1 = ref(null);
|
|
|
-let minuteChartInstance1 = null;
|
|
|
-const minuteTableData1 = ref([]);
|
|
|
-const minuteDataLabel1 = ref('');
|
|
|
-
|
|
|
-// 表格引用和同步状态
|
|
|
-const tableRef0 = ref(null);
|
|
|
-const tableRef1 = ref(null);
|
|
|
-const isSyncing = ref(false); // 防止循环触发
|
|
|
-let cleanups = []; // 存储清理函数
|
|
|
-
|
|
|
-const data = reactive({
|
|
|
- form: {},
|
|
|
- queryParams: {
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 10000,
|
|
|
- dataDate: new Date(new Date().getTime() - 24 * 60 * 60 * 1000).Format('yyyy-MM-dd'),
|
|
|
- hour: null,
|
|
|
- lines: null,
|
|
|
- openRate: null,
|
|
|
- length: null,
|
|
|
- tmp: null,
|
|
|
- speed: null,
|
|
|
- energy: null,
|
|
|
- amp: null,
|
|
|
- createdBy: null,
|
|
|
- createdTime: null,
|
|
|
- updatedBy: null,
|
|
|
- updatedTime: null,
|
|
|
- remark: null
|
|
|
- },
|
|
|
- rules: {
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-const selectedEquipmentType = ref('');
|
|
|
-const selectedEquipmentParam = ref('');
|
|
|
-const selectedMetrics = ref({});
|
|
|
-const selectedLines = ref([]); // 多条产线选择
|
|
|
-const equipmentList = ref({});
|
|
|
-const equipmentTypeList = ref([]);
|
|
|
-const equipmentParamOptions = ref([]);
|
|
|
-const equipmentTypeOptions = ref([]);
|
|
|
-const allLines = ref(['1', '2', '3', '4', '5', '6', '7', '8']);
|
|
|
-const oldSelectLines = ref([]);
|
|
|
-
|
|
|
-const { queryParams, form, rules } = toRefs(data);
|
|
|
-
|
|
|
-// 按产线分组的数据
|
|
|
-const groupedRzLineList = computed(() => {
|
|
|
- const grouped = {};
|
|
|
- rzLineList.value.forEach(item => {
|
|
|
- if (!grouped[item.line]) {
|
|
|
- grouped[item.line] = [];
|
|
|
- }
|
|
|
- grouped[item.line].push(item);
|
|
|
- });
|
|
|
- // 按产线编号排序
|
|
|
- const sortedGrouped = {};
|
|
|
- Object.keys(grouped).sort().forEach(key => {
|
|
|
- sortedGrouped[key] = grouped[key];
|
|
|
- });
|
|
|
- return sortedGrouped;
|
|
|
-});
|
|
|
-
|
|
|
-// 合并单元格处理函数
|
|
|
-const spanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
|
|
- if (columnIndex === 0) { // 小时列
|
|
|
- // 获取当前行小时值
|
|
|
- const currentHour = row.hour;
|
|
|
-
|
|
|
- // 计算当前小时值第一次出现的位置
|
|
|
- let firstIndex = -1;
|
|
|
- for (let i = 0; i < rzLineList.value.length; i++) {
|
|
|
- if (rzLineList.value[i].hour === currentHour) {
|
|
|
- firstIndex = i;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 如果当前行是该小时值第一次出现的位置
|
|
|
- if (firstIndex === rowIndex) {
|
|
|
- // 计算该小时值连续出现的次数
|
|
|
- let spanCount = 0;
|
|
|
- for (let i = firstIndex; i < rzLineList.value.length; i++) {
|
|
|
- if (rzLineList.value[i].hour === currentHour) {
|
|
|
- spanCount++;
|
|
|
- } else {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- return [spanCount, 1];
|
|
|
- } else {
|
|
|
- // 如果不是第一次出现,隐藏该单元格
|
|
|
- return [0, 0];
|
|
|
- }
|
|
|
- }
|
|
|
- return [1, 1]; // 其他列不合并
|
|
|
-};
|
|
|
-function navigateDay(offset) {
|
|
|
- const currentDate = new Date(queryParams.value.dataDate);
|
|
|
- currentDate.setDate(currentDate.getDate() + offset);
|
|
|
- queryParams.value.dataDate = currentDate.toISOString().split('T')[0];
|
|
|
- handleQuery();
|
|
|
-}
|
|
|
-/** 查询染整线产线小时统计数据列表 */
|
|
|
-function getList() {
|
|
|
- // 先获取设备类型列表
|
|
|
- listDeviceTypes({pageSize: 10000}).then(response => {
|
|
|
- equipmentTypeList.value = response.rows;
|
|
|
- // 提取设备类型选项
|
|
|
- equipmentTypeOptions.value = response.rows.map(item => {
|
|
|
- return {
|
|
|
- typeId: item.typeId,
|
|
|
- typeName: item.typeName
|
|
|
- };
|
|
|
- });
|
|
|
-
|
|
|
- // 默认选择第一条设备类型
|
|
|
- if (response.rows.length > 0 && !selectedEquipmentType.value) {
|
|
|
- selectedEquipmentType.value = response.rows[0].typeId;
|
|
|
- // 触发设备类型变化事件,加载对应的参数
|
|
|
- handleEquipmentTypeChange(selectedEquipmentType.value);
|
|
|
- }
|
|
|
-
|
|
|
- // 初始化主表滚动同步
|
|
|
- nextTick(() => {
|
|
|
- initMainTableScrollSync();
|
|
|
- });
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-function difference(arr1, arr2) {
|
|
|
- const set2 = new Set(arr2);
|
|
|
- return arr1.filter(item => !set2.has(item));
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * 获取设备列表
|
|
|
- * @returns {void}
|
|
|
- */
|
|
|
-function getDeviceList(){
|
|
|
- // 检查是否选择了产线
|
|
|
- if (selectedLines.value.length === 0) {
|
|
|
- proxy.$modal.msgWarning("请至少选择一条产线进行对比");
|
|
|
- return;
|
|
|
- }
|
|
|
- if (selectedLines.value.length > 2) {
|
|
|
- let tmp = difference(selectedLines.value, oldSelectLines.value);
|
|
|
- selectedLines.value = selectedLines.value.filter(item => !tmp.includes(item));
|
|
|
- oldSelectLines.value = JSON.parse(JSON.stringify(selectedLines.value));
|
|
|
- proxy.$modal.msgWarning("最多只能选择两条产线进行对比");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理取消选择产线的情况
|
|
|
- if (selectedLines.value.length < oldSelectLines.value.length) {
|
|
|
- // 取消了一条产线
|
|
|
- let tmp = difference(oldSelectLines.value, selectedLines.value);
|
|
|
- // 清除取消产线的相关设备选择
|
|
|
- if (selectedMetrics.value[tmp[0]]) {
|
|
|
- selectedMetrics.value[tmp[0]] = '';
|
|
|
- }
|
|
|
- // 如果是单一产线情况,清除相关的设备选择
|
|
|
- if (selectedMetrics.value[tmp[0] + '_0']) selectedMetrics.value[tmp[0] + '_0'] = '';
|
|
|
- if (selectedMetrics.value[tmp[0] + '_1']) selectedMetrics.value[tmp[0] + '_1'] = '';
|
|
|
- updateQueryData();
|
|
|
- }
|
|
|
-
|
|
|
- // 检查是否选择了设备类型和参数
|
|
|
- if (!selectedEquipmentType.value) {
|
|
|
- proxy.$modal.msgError("请先选择设备类型");
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!selectedEquipmentParam.value) {
|
|
|
- proxy.$modal.msgError("请先选择设备参数");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 为所有选中的产线获取设备列表
|
|
|
- selectedLines.value.forEach(line => {
|
|
|
- listDevice({
|
|
|
- pageSize: 10000,
|
|
|
- pageNum: 1,
|
|
|
- paraCode: selectedEquipmentParam.value,
|
|
|
- typeId: selectedEquipmentType.value,
|
|
|
- line: line
|
|
|
- }).then(response => {
|
|
|
- // 提取设备参数选项
|
|
|
- equipmentList.value[line] = response.rows.map(item => {
|
|
|
- return {
|
|
|
- id: item.deviceId,
|
|
|
- name: item.deviceName
|
|
|
- };
|
|
|
- });
|
|
|
-
|
|
|
- // 默认选中第一台设备
|
|
|
- let needUpdateData = false;
|
|
|
- if (response.rows.length > 0) {
|
|
|
- // 如果是单条产线情况,设置同产线设备对比的第一台设备
|
|
|
- if (selectedLines.value.length === 1) {
|
|
|
- const lineKey = selectedLines.value[0];
|
|
|
- if (!selectedMetrics.value[lineKey + '_0']) {
|
|
|
- selectedMetrics.value[lineKey + '_0'] = response.rows[0].deviceId;
|
|
|
- needUpdateData = true;
|
|
|
- }
|
|
|
- }
|
|
|
- // 如果是两条产线情况,设置对应产线的第一台设备
|
|
|
- else if (selectedLines.value.length === 2) {
|
|
|
- if (!selectedMetrics.value[line]) {
|
|
|
- selectedMetrics.value[line] = response.rows[0].deviceId;
|
|
|
- needUpdateData = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 如果设置了默认设备,则更新数据
|
|
|
- if (needUpdateData) {
|
|
|
- updateQueryData();
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- oldSelectLines.value = JSON.parse(JSON.stringify(selectedLines.value));
|
|
|
- // 如果选择了产线,更新图表
|
|
|
- if (selectedLines.value.length >= 1 && Object.keys(selectedMetrics.value).length > 0) {
|
|
|
- // 检查是否所有产线都已设置设备,如果是则更新数据
|
|
|
- let allLinesHaveDevices = true;
|
|
|
- if (selectedLines.value.length === 1) {
|
|
|
- const lineKey = selectedLines.value[0];
|
|
|
- if (!selectedMetrics.value[lineKey + '_0']) {
|
|
|
- allLinesHaveDevices = false;
|
|
|
- }
|
|
|
- } else if (selectedLines.value.length === 2) {
|
|
|
- for (const line of selectedLines.value) {
|
|
|
- if (!selectedMetrics.value[line]) {
|
|
|
- allLinesHaveDevices = false;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (allLinesHaveDevices) {
|
|
|
- updateQueryData();
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-function updateQueryData() {
|
|
|
- initChart();
|
|
|
- rzLineList.value = [];
|
|
|
- rzLineList1.value = [];
|
|
|
-
|
|
|
- let queryPara = {
|
|
|
- paraCode: selectedEquipmentParam.value,
|
|
|
- typeId: selectedEquipmentType.value,
|
|
|
- dataDate: queryParams.value.dataDate,
|
|
|
- pageSize: 10000,
|
|
|
- pageNum: 1,
|
|
|
- };
|
|
|
-
|
|
|
- // 情况1:选择了一条产线,需要比较该产线下的两个设备
|
|
|
- if (selectedLines.value.length == 1) {
|
|
|
- const line = selectedLines.value[0];
|
|
|
- // 检查是否选择了两个设备进行对比
|
|
|
- if (selectedMetrics.value[line + '_0'] && selectedMetrics.value[line + '_1']) {
|
|
|
- // 查询第一个设备的数据
|
|
|
- queryPara['line'] = line;
|
|
|
- queryPara['deviceId'] = selectedMetrics.value[line + '_0'];
|
|
|
- listHour(queryPara).then(res => {
|
|
|
- rzLineList.value = res.rows;
|
|
|
- nextTick(() => {
|
|
|
- updateChart();
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- // 查询第二个设备的数据
|
|
|
- queryPara['deviceId'] = selectedMetrics.value[line + '_1'];
|
|
|
- listHour(queryPara).then(res => {
|
|
|
- rzLineList1.value = res.rows;
|
|
|
- nextTick(() => {
|
|
|
- updateChart1();
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- // 情况2:选择了两条产线,每条产线选择一个设备进行对比
|
|
|
- else if (selectedLines.value.length == 2) {
|
|
|
- // 查询第一条产线设备的数据
|
|
|
- if (selectedMetrics.value[selectedLines.value[0]]) {
|
|
|
- queryPara['line'] = selectedLines.value[0];
|
|
|
- queryPara['deviceId'] = selectedMetrics.value[selectedLines.value[0]];
|
|
|
- listHour(queryPara).then(res => {
|
|
|
- rzLineList.value = res.rows;
|
|
|
- nextTick(() => {
|
|
|
- updateChart();
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 查询第二条产线设备的数据
|
|
|
- if (selectedMetrics.value[selectedLines.value[1]]) {
|
|
|
- queryPara['line'] = selectedLines.value[1];
|
|
|
- queryPara['deviceId'] = selectedMetrics.value[selectedLines.value[1]];
|
|
|
- listHour(queryPara).then(res => {
|
|
|
- rzLineList1.value = res.rows;
|
|
|
- nextTick(() => {
|
|
|
- updateChart1();
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 初始化图表
|
|
|
-function initChart() {
|
|
|
- if (chartInstance0) {
|
|
|
- chartInstance0.dispose();
|
|
|
- }
|
|
|
- if (chartInstance1) {
|
|
|
- chartInstance1.dispose();
|
|
|
- }
|
|
|
- if (chartRef0.value) {
|
|
|
- chartInstance0 = echarts.init(chartRef0.value);
|
|
|
- }
|
|
|
- if (chartRef1.value) {
|
|
|
- chartInstance1 = echarts.init(chartRef1.value);
|
|
|
- }
|
|
|
- //建立图表联动
|
|
|
- if (chartInstance0 && chartInstance1) {
|
|
|
- echarts.connect([
|
|
|
- chartInstance0,
|
|
|
- chartInstance1,
|
|
|
- ]);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 初始化分钟级数据图表
|
|
|
-function initMinuteChart0(minuteData, targetData) {
|
|
|
- if (minuteChartInstance0) {
|
|
|
- minuteChartInstance0.dispose();
|
|
|
- }
|
|
|
-
|
|
|
- if (minuteChartRef0.value) {
|
|
|
- minuteChartInstance0 = echarts.init(minuteChartRef0.value);
|
|
|
-
|
|
|
- // 准备分钟级数据
|
|
|
- const timePoints = minuteData.map(item => item.time);
|
|
|
- const values = minuteData.map(item => item.value);
|
|
|
-
|
|
|
- const option = {
|
|
|
- title: {
|
|
|
- text: targetData.deviceName + ' ' + targetData.paraName,
|
|
|
- left: 'center'
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- formatter: function (params) {
|
|
|
- let result = params[0].axisValue + '分<br/>';
|
|
|
- params.forEach(param => {
|
|
|
- let valueText = '';
|
|
|
- valueText = param.value !== null ? param.value : '无数据';
|
|
|
- result += `<div style="display:flex;align-items:center;">
|
|
|
- <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${param.color};"></span>
|
|
|
- ${param.seriesName}: ${valueText}
|
|
|
- </div>`;
|
|
|
- });
|
|
|
- return result;
|
|
|
- }
|
|
|
- },
|
|
|
- legend:{
|
|
|
- top: 40 ,
|
|
|
- left: 'center',
|
|
|
- textStyle: {
|
|
|
- fontSize: 10
|
|
|
- },
|
|
|
- itemWidth: 10,
|
|
|
- itemHeight: 10
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '4%',
|
|
|
- top: '25%',
|
|
|
- bottom: 20,
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- boundaryGap: false,
|
|
|
- data: timePoints
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- type: 'value',
|
|
|
- name: targetData.paraName
|
|
|
- },
|
|
|
- series: [{
|
|
|
- name: targetData.deviceName + '-' + targetData.paraName,
|
|
|
- type: 'line',
|
|
|
- data: values,
|
|
|
- smooth: true,
|
|
|
- showSymbol: false
|
|
|
- }]
|
|
|
- };
|
|
|
-
|
|
|
- minuteChartInstance0.setOption(option);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 初始化分钟级数据图表1
|
|
|
-function initMinuteChart1(minuteData, targetData) {
|
|
|
- if (minuteChartInstance1) {
|
|
|
- minuteChartInstance1.dispose();
|
|
|
- }
|
|
|
-
|
|
|
- if (minuteChartRef1.value) {
|
|
|
- minuteChartInstance1 = echarts.init(minuteChartRef1.value);
|
|
|
-
|
|
|
- // 准备分钟级数据
|
|
|
- const timePoints = minuteData.map(item => item.time);
|
|
|
- const values = minuteData.map(item => item.value);
|
|
|
-
|
|
|
- const option = {
|
|
|
- title: {
|
|
|
- text: targetData.deviceName + ' ' + targetData.paraName,
|
|
|
- left: 'center'
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- formatter: function (params) {
|
|
|
- let result = params[0].axisValue + '分<br/>';
|
|
|
- params.forEach(param => {
|
|
|
- let valueText = '';
|
|
|
- valueText = param.value !== null ? param.value : '无数据';
|
|
|
- result += `<div style="display:flex;align-items:center;">
|
|
|
- <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${param.color};"></span>
|
|
|
- ${param.seriesName}: ${valueText}
|
|
|
- </div>`;
|
|
|
- });
|
|
|
- return result;
|
|
|
- }
|
|
|
- },
|
|
|
- legend:{
|
|
|
- top: 40 ,
|
|
|
- left: 'center',
|
|
|
- textStyle: {
|
|
|
- fontSize: 10
|
|
|
- },
|
|
|
- itemWidth: 10,
|
|
|
- itemHeight: 10
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '4%',
|
|
|
- top: '25%',
|
|
|
- bottom: 20,
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- boundaryGap: false,
|
|
|
- data: timePoints
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- type: 'value',
|
|
|
- name: targetData.paraName
|
|
|
- },
|
|
|
- series: [{
|
|
|
- name: targetData.deviceName + '-' + targetData.paraName,
|
|
|
- type: 'line',
|
|
|
- data: values,
|
|
|
- smooth: true,
|
|
|
- showSymbol: false
|
|
|
- }]
|
|
|
- };
|
|
|
-
|
|
|
- minuteChartInstance1.setOption(option);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 更新图表0
|
|
|
-function updateChart() {
|
|
|
- if (chartInstance0 && rzLineList.value.length > 0) {
|
|
|
- const hours = rzLineList.value.map(item => item.hour.toString().padStart(2, '0') + ':00');
|
|
|
- const values = rzLineList.value.map(item => item.paraValue);
|
|
|
-
|
|
|
- const option = {
|
|
|
- title: {
|
|
|
- text: rzLineList.value[0].deviceName + ' ' + rzLineList.value[0].paraName,
|
|
|
- left: 'center'
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- formatter: function (params) {
|
|
|
- let result = params[0].axisValue + '<br/>';
|
|
|
- params.forEach(param => {
|
|
|
- let valueText = '';
|
|
|
- valueText = param.value !== null ? param.value : '无数据';
|
|
|
- result += `<div style="display:flex;align-items:center;">
|
|
|
- <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${param.color};"></span>
|
|
|
- ${param.seriesName}: ${valueText}
|
|
|
- </div>`;
|
|
|
- });
|
|
|
- return result;
|
|
|
- }
|
|
|
- },
|
|
|
- legend:{
|
|
|
- top: 40 ,
|
|
|
- left: 'center',
|
|
|
- textStyle: {
|
|
|
- fontSize: 10
|
|
|
- },
|
|
|
- itemWidth: 10,
|
|
|
- itemHeight: 10
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '4%',
|
|
|
- top: '25%',
|
|
|
- bottom: 20,
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- boundaryGap: false,
|
|
|
- data: hours
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- type: 'value',
|
|
|
- name: rzLineList.value[0].paraName
|
|
|
- },
|
|
|
- series: [{
|
|
|
- name: rzLineList.value[0].deviceName,
|
|
|
- type: 'line',
|
|
|
- data: values,
|
|
|
- smooth: true,
|
|
|
- showSymbol: false
|
|
|
- }]
|
|
|
- };
|
|
|
-
|
|
|
- chartInstance0.setOption(option);
|
|
|
-
|
|
|
- // 先移除之前的点击事件监听,避免重复绑定
|
|
|
- chartInstance0.off('click');
|
|
|
- // 添加点击事件监听
|
|
|
- chartInstance0.on('click', (params) => {
|
|
|
- handleChartClick(params, 'chart0');
|
|
|
- });
|
|
|
- } else if (chartInstance0) {
|
|
|
- // 如果没有数据,清空图表
|
|
|
- chartInstance0.setOption({
|
|
|
- title: {
|
|
|
- text: '暂无数据',
|
|
|
- left: 'center',
|
|
|
- top: 'center'
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- data: []
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- type: 'value'
|
|
|
- },
|
|
|
- series: []
|
|
|
- });
|
|
|
-
|
|
|
- // 移除点击事件监听
|
|
|
- chartInstance0.off('click');
|
|
|
- }
|
|
|
-
|
|
|
- // 更新数据后重新初始化表格滚动同步
|
|
|
- nextTick(() * {
|
|
|
- initMainTableScrollSync();
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-// 更新图表1
|
|
|
-function updateChart1() {
|
|
|
- if (chartInstance1 && rzLineList1.value.length > 0) {
|
|
|
- const hours = rzLineList1.value.map(item => item.hour.toString().padStart(2, '0') + ':00');
|
|
|
- const values = rzLineList1.value.map(item => item.paraValue);
|
|
|
-
|
|
|
- const option = {
|
|
|
- title: {
|
|
|
- text: rzLineList1.value[0].deviceName + ' ' + rzLineList1.value[0].paraName,
|
|
|
- left: 'center'
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- formatter: function (params) {
|
|
|
- let result = params[0].axisValue + '<br/>';
|
|
|
- params.forEach(param => {
|
|
|
- let valueText = '';
|
|
|
- valueText = param.value !== null ? param.value : '无数据';
|
|
|
- result += `<div style="display:flex;align-items:center;">
|
|
|
- <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${param.color};"></span>
|
|
|
- ${param.seriesName}: ${valueText}
|
|
|
- </div>`;
|
|
|
- });
|
|
|
- return result;
|
|
|
- }
|
|
|
- },
|
|
|
- legend:{
|
|
|
- top: 40 ,
|
|
|
- left: 'center',
|
|
|
- textStyle: {
|
|
|
- fontSize: 10
|
|
|
- },
|
|
|
- itemWidth: 10,
|
|
|
- itemHeight: 10
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '4%',
|
|
|
- top: '25%',
|
|
|
- bottom: 20,
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- boundaryGap: false,
|
|
|
- data: hours
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- type: 'value',
|
|
|
- name: rzLineList1.value[0].paraName
|
|
|
- },
|
|
|
- series: [{
|
|
|
- name: rzLineList1.value[0].deviceName,
|
|
|
- type: 'line',
|
|
|
- data: values,
|
|
|
- smooth: true,
|
|
|
- showSymbol: false
|
|
|
- }]
|
|
|
- };
|
|
|
-
|
|
|
- chartInstance1.setOption(option);
|
|
|
-
|
|
|
- // 先移除之前的点击事件监听,避免重复绑定
|
|
|
- chartInstance1.off('click');
|
|
|
- // 添加点击事件监听
|
|
|
- chartInstance1.on('click', (params) => {
|
|
|
- handleChartClick(params, 'chart1');
|
|
|
- });
|
|
|
- } else if (chartInstance1) {
|
|
|
- // 如果没有数据,清空图表
|
|
|
- chartInstance1.setOption({
|
|
|
- title: {
|
|
|
- text: '暂无数据',
|
|
|
- left: 'center',
|
|
|
- top: 'center'
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- data: []
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- type: 'value'
|
|
|
- },
|
|
|
- series: []
|
|
|
- });
|
|
|
-
|
|
|
- // 移除点击事件监听
|
|
|
- chartInstance1.off('click');
|
|
|
- }
|
|
|
-
|
|
|
- // 更新数据后重新初始化表格滚动同步
|
|
|
- nextTick(() => {
|
|
|
- initMainTableScrollSync();
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-// 图表点击事件处理函数
|
|
|
-function handleChartClick(params, chartType) {
|
|
|
- // 获取点击的小时
|
|
|
- const hour = params.name;
|
|
|
-
|
|
|
- // 查找对应小时的数据(无论点击的是哪个图表,都要显示两个设备的数据)
|
|
|
- // 尝试多种匹配方式来查找数据
|
|
|
- let targetData0 = null;
|
|
|
- let targetData1 = null;
|
|
|
-
|
|
|
- // 对于第一个数据集
|
|
|
- for (let i = 0; i < rzLineList.value.length; i++) {
|
|
|
- const item = rzLineList.value[i];
|
|
|
- const itemHour = item.hour.toString().padStart(2, '0');
|
|
|
- const clickedHour = hour.replace(':00', ''); // 去掉可能的 ':00' 后缀
|
|
|
-
|
|
|
- if (itemHour === clickedHour) {
|
|
|
- targetData0 = item;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 对于第二个数据集
|
|
|
- for (let i = 0; i < rzLineList1.value.length; i++) {
|
|
|
- const item = rzLineList1.value[i];
|
|
|
- const itemHour = item.hour.toString().padStart(2, '0');
|
|
|
- const clickedHour = hour.replace(':00', ''); // 去掉可能的 ':00' 后缀
|
|
|
-
|
|
|
- if (itemHour === clickedHour) {
|
|
|
- targetData1 = item;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 检查两个设备是否都有对应小时的数据
|
|
|
- if ((targetData0 && targetData0.paraMValue) || (targetData1 && targetData1.paraMValue)) {
|
|
|
- try {
|
|
|
- // 设置对话框标题
|
|
|
- minuteDialogTitle.value = `小时 ${hour} 的分钟级数据对比`;
|
|
|
-
|
|
|
- // 处理左侧设备的分钟级数据
|
|
|
- if (targetData0 && targetData0.paraMValue) {
|
|
|
- let minuteData0;
|
|
|
- try {
|
|
|
- minuteData0 = typeof targetData0.paraMValue === 'string'
|
|
|
- ? JSON.parse(targetData0.paraMValue)
|
|
|
- : targetData0.paraMValue;
|
|
|
- } catch (e) {
|
|
|
- // 尝试其他格式
|
|
|
- if (Array.isArray(targetData0.paraMValue)) {
|
|
|
- minuteData0 = targetData0.paraMValue;
|
|
|
- } else {
|
|
|
- minuteData0 = [];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 设置左侧分钟级数据
|
|
|
- minuteTableData0.value = minuteData0.map(item => ({
|
|
|
- time: item.time,
|
|
|
- value: item.value
|
|
|
- }));
|
|
|
- minuteDataLabel0.value = targetData0.paraName;
|
|
|
-
|
|
|
- // 初始化左侧分钟级图表
|
|
|
- nextTick(() => {
|
|
|
- initMinuteChart0(minuteData0, targetData0);
|
|
|
- // 建立分钟级图表联动
|
|
|
- if (minuteChartInstance0 && minuteChartInstance1) {
|
|
|
- echarts.connect([minuteChartInstance0, minuteChartInstance1]);
|
|
|
- }
|
|
|
-
|
|
|
- // 初始化表格滚动同步
|
|
|
- initMainTableScrollSync();
|
|
|
- });
|
|
|
- } else {
|
|
|
- // 如果没有数据,清空左侧内容
|
|
|
- minuteTableData0.value = [];
|
|
|
- minuteDataLabel0.value = '';
|
|
|
- if (minuteChartInstance0) {
|
|
|
- minuteChartInstance0.dispose();
|
|
|
- minuteChartInstance0 = null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 处理右侧设备的分钟级数据
|
|
|
- if (targetData1 && targetData1.paraMValue) {
|
|
|
- let minuteData1;
|
|
|
- try {
|
|
|
- minuteData1 = typeof targetData1.paraMValue === 'string'
|
|
|
- ? JSON.parse(targetData1.paraMValue)
|
|
|
- : targetData1.paraMValue;
|
|
|
- } catch (e) {
|
|
|
- // 尝试其他格式
|
|
|
- if (Array.isArray(targetData1.paraMValue)) {
|
|
|
- minuteData1 = targetData1.paraMValue;
|
|
|
- } else {
|
|
|
- minuteData1 = [];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 设置右侧分钟级数据
|
|
|
- minuteTableData1.value = minuteData1.map(item => ({
|
|
|
- time: item.time,
|
|
|
- value: item.value
|
|
|
- }));
|
|
|
- minuteDataLabel1.value = targetData1.paraName;
|
|
|
-
|
|
|
- // 初始化右侧分钟级图表
|
|
|
- nextTick(() => {
|
|
|
- initMinuteChart1(minuteData1, targetData1);
|
|
|
- // 建立分钟级图表联动
|
|
|
- if (minuteChartInstance0 && minuteChartInstance1) {
|
|
|
- echarts.connect([minuteChartInstance0, minuteChartInstance1]);
|
|
|
- }
|
|
|
-
|
|
|
- // 初始化表格滚动同步
|
|
|
- initMainTableScrollSync();
|
|
|
- });
|
|
|
- } else {
|
|
|
- // 如果没有数据,清空右侧内容
|
|
|
- minuteTableData1.value = [];
|
|
|
- minuteDataLabel1.value = '';
|
|
|
- if (minuteChartInstance1) {
|
|
|
- minuteChartInstance1.dispose();
|
|
|
- minuteChartInstance1 = null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 显示对话框
|
|
|
- showMinuteDialog();
|
|
|
- } catch (error) {
|
|
|
- proxy.$modal.msgError("数据解析失败");
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 显示提示信息
|
|
|
- proxy.$modal.msgWarning("该小时没有分钟级数据");
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 窗口大小改变时重置图表大小
|
|
|
-function resizeChart() {
|
|
|
- if (chartInstance0) {
|
|
|
- chartInstance0.resize();
|
|
|
- }
|
|
|
- if (chartInstance1) {
|
|
|
- chartInstance1.resize();
|
|
|
- }
|
|
|
- if (minuteChartInstance0) {
|
|
|
- minuteChartInstance0.resize();
|
|
|
- }
|
|
|
- if (minuteChartInstance1) {
|
|
|
- minuteChartInstance1.resize();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 关闭分钟级数据弹窗
|
|
|
-function handleMinuteDialogClose() {
|
|
|
- minuteDialogVisible.value = false;
|
|
|
-}
|
|
|
-
|
|
|
-// 显示分钟级数据弹窗
|
|
|
-function showMinuteDialog() {
|
|
|
- minuteDialogVisible.value = true;
|
|
|
-}
|
|
|
-
|
|
|
-// 初始化主表表格滚动同步
|
|
|
-function initMainTableScrollSync() {
|
|
|
- // 清理之前的事件监听器
|
|
|
- cleanups.forEach(cleanup => cleanup());
|
|
|
- cleanups = [];
|
|
|
-
|
|
|
- // 初始化新的滚动同步
|
|
|
- const newCleanups = initTableScrollSync(tableRef0, tableRef1, isSyncing);
|
|
|
- cleanups = newCleanups;
|
|
|
-}
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- initChart();
|
|
|
- window.addEventListener('resize', resizeChart);
|
|
|
-
|
|
|
- // 默认选择所有产线
|
|
|
- //selectedLines.value = [...allLines.value];
|
|
|
-
|
|
|
- // 初始加载数据
|
|
|
- getList();
|
|
|
-
|
|
|
- // 添加一个微任务确保图表正确初始化
|
|
|
- nextTick(() => {
|
|
|
- if (!chartInstance0 && chartRef0.value) {
|
|
|
- chartInstance0 = echarts.init(chartRef0.value);
|
|
|
- }
|
|
|
- if (!chartInstance1 && chartRef1.value) {
|
|
|
- chartInstance1 = echarts.init(chartRef1.value);
|
|
|
- }
|
|
|
-
|
|
|
- // 初始化主表滚动同步
|
|
|
- initMainTableScrollSync();
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-onUnmounted(() => {
|
|
|
- window.removeEventListener('resize', resizeChart);
|
|
|
- if (chartInstance0) {
|
|
|
- chartInstance0.dispose();
|
|
|
- }
|
|
|
- if (chartInstance1) {
|
|
|
- chartInstance1.dispose();
|
|
|
- }
|
|
|
- if (minuteChartInstance0) {
|
|
|
- minuteChartInstance0.dispose();
|
|
|
- }
|
|
|
- if (minuteChartInstance1) {
|
|
|
- minuteChartInstance1.dispose();
|
|
|
- }
|
|
|
-
|
|
|
- // 清理表格滚动同步事件监听器
|
|
|
- cleanups.forEach(cleanup => cleanup());
|
|
|
-});
|
|
|
-
|
|
|
-onActivated(() => {
|
|
|
- resizeChart();
|
|
|
-});
|
|
|
-
|
|
|
-// 取消按钮
|
|
|
-function cancel() {
|
|
|
- open.value = false;
|
|
|
- reset();
|
|
|
-}
|
|
|
-
|
|
|
-// 表单重置
|
|
|
-function reset() {
|
|
|
- form.value = {
|
|
|
- id: null,
|
|
|
- dataDate: null,
|
|
|
- hour: null,
|
|
|
- line: null,
|
|
|
- openRate: null,
|
|
|
- length: null,
|
|
|
- tmp: null,
|
|
|
- speed: null,
|
|
|
- energy: null,
|
|
|
- amp: null,
|
|
|
- createdBy: null,
|
|
|
- createdTime: null,
|
|
|
- updatedBy: null,
|
|
|
- updatedTime: null,
|
|
|
- remark: null
|
|
|
- };
|
|
|
- proxy.resetForm("rzLineRef");
|
|
|
-}
|
|
|
-
|
|
|
-/** 搜索按钮操作 */
|
|
|
-function handleQuery() {
|
|
|
- queryParams.value.pageNum = 1;
|
|
|
- // 检查查询条件
|
|
|
- if (!queryParams.value.dataDate) {
|
|
|
- proxy.$modal.msgWarning("请选择日期");
|
|
|
- return;
|
|
|
- }
|
|
|
- // 不要重置已选择的产线和设备,仅更新数据
|
|
|
- updateQueryData();
|
|
|
-}
|
|
|
-
|
|
|
-/** 重置按钮操作 */
|
|
|
-function resetQuery() {
|
|
|
- proxy.resetForm("queryRef");
|
|
|
- // 设置默认日期为当前日期
|
|
|
- const now = new Date();
|
|
|
- const year = now.getFullYear();
|
|
|
- const month = (now.getMonth() + 1).toString().padStart(2, '0');
|
|
|
- const day = now.getDate().toString().padStart(2, '0');
|
|
|
- queryParams.value.dataDate = `${year}-${month}-${day}`;
|
|
|
-
|
|
|
- // 重置产线和设备选择
|
|
|
- selectedLines.value = [];
|
|
|
- selectedMetrics.value = {};
|
|
|
- equipmentList.value = {};
|
|
|
-
|
|
|
- handleQuery();
|
|
|
-}
|
|
|
-// 处理设备类型变化
|
|
|
-function handleEquipmentTypeChange(val) {
|
|
|
- // 清空已选的设备参数
|
|
|
- selectedEquipmentParam.value = '';
|
|
|
-
|
|
|
- // 如果有选择设备类型,则更新设备参数选项
|
|
|
- if (val) {
|
|
|
- // 在设备类型列表中找到当前选中的设备类型
|
|
|
- const selectedType = equipmentTypeList.value.find(item => item.typeId === val);
|
|
|
- if (selectedType && selectedType.dyeTypeParaList) {
|
|
|
- // 提取设备参数选项
|
|
|
- equipmentParamOptions.value = selectedType.dyeTypeParaList.map(item => {
|
|
|
- return {
|
|
|
- paraCode: item.paraCode,
|
|
|
- paraName: item.paraName
|
|
|
- };
|
|
|
- });
|
|
|
-
|
|
|
- // 默认选择第一条设备参数
|
|
|
- if (selectedType.dyeTypeParaList.length > 0 && !selectedEquipmentParam.value) {
|
|
|
- selectedEquipmentParam.value = selectedType.dyeTypeParaList[0].paraCode;
|
|
|
- // 触发设备参数变化事件
|
|
|
- handleEquipmentParamChange();
|
|
|
- }
|
|
|
- } else {
|
|
|
- equipmentParamOptions.value = [];
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 如果没有选择设备类型,清空设备参数选项
|
|
|
- equipmentParamOptions.value = [];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 处理设备参数变化
|
|
|
-function handleEquipmentParamChange() {
|
|
|
- // 清空设备列表和已选择的设备
|
|
|
- equipmentList.value = {};
|
|
|
- selectedMetrics.value = {};
|
|
|
-
|
|
|
- // 获取新设备列表
|
|
|
- getDeviceList();
|
|
|
-}
|
|
|
-
|
|
|
-// 处理产线选择变化
|
|
|
-function handleLineSelectionChange(val) {
|
|
|
- if (val.length > 2) {
|
|
|
- // 限制最多选择两条产线
|
|
|
- selectedLines.value = val.slice(0, 2);
|
|
|
- proxy.$modal.msgWarning("最多只能选择两条产线进行对比");
|
|
|
- }
|
|
|
- // 当取消选择所有产线时,清空相关设备选择
|
|
|
- if (val.length === 0) {
|
|
|
- selectedMetrics.value = {};
|
|
|
- }
|
|
|
- getDeviceList();
|
|
|
-}
|
|
|
-
|
|
|
-/** 新增按钮操作 */
|
|
|
-function handleAdd() {
|
|
|
- reset();
|
|
|
- open.value = true;
|
|
|
- title.value = "添加染整线产线小时统计数据";
|
|
|
-}
|
|
|
-
|
|
|
-/** 修改按钮操作 */
|
|
|
-function handleUpdate(row) {
|
|
|
- reset();
|
|
|
- const _id = row.id || ids.value
|
|
|
- getRzLine(_id).then(response => {
|
|
|
- form.value = response.data;
|
|
|
- open.value = true;
|
|
|
- title.value = "修改染整线产线小时统计数据";
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-/** 提交按钮 */
|
|
|
-function submitForm() {
|
|
|
- proxy.$refs["rzLineRef"].validate(valid => {
|
|
|
- if (valid) {
|
|
|
- if (form.value.id != null) {
|
|
|
- updateRzLine(form.value).then(response => {
|
|
|
- proxy.$modal.msgSuccess("修改成功");
|
|
|
- open.value = false;
|
|
|
- getList();
|
|
|
- });
|
|
|
- } else {
|
|
|
- addRzLine(form.value).then(response => {
|
|
|
- proxy.$modal.msgSuccess("新增成功");
|
|
|
- open.value = false;
|
|
|
- getList();
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-/** 删除按钮操作 */
|
|
|
-function handleDelete(row) {
|
|
|
- const _ids = row.id || ids.value;
|
|
|
- proxy.$modal.confirm('是否确认删除染整线产线小时统计数据编号为"' + _ids + '"的数据项?').then(function() {
|
|
|
- return delRzLine(_ids);
|
|
|
- }).then(() => {
|
|
|
- getList();
|
|
|
- proxy.$modal.msgSuccess("删除成功");
|
|
|
- }).catch(() => {});
|
|
|
-}
|
|
|
-
|
|
|
-/** 导出按钮操作 */
|
|
|
-function handleExport() {
|
|
|
- proxy.download('dyeing/rzLine/export', {
|
|
|
- ...queryParams.value
|
|
|
- }, `rzLine_${new Date().getTime()}.xlsx`)
|
|
|
-}
|
|
|
-
|
|
|
-getList();
|
|
|
-</script>
|