wukai vor 1 Monat
Ursprung
Commit
a27ebb8152
1 geänderte Dateien mit 315 neuen und 135 gelöschten Zeilen
  1. 315 135
      src/views/dyeing/gyfx/index.vue

+ 315 - 135
src/views/dyeing/gyfx/index.vue

@@ -1,30 +1,30 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px" style="text-align: center;">
-      <el-form-item style="width: 208px; display: inline-block;">
-        <div style="display: flex; align-items: center; justify-content: center;">
-          <el-button icon="ArrowLeft" @click="navigateDay(-1)" size="small" style="margin-right: 15px;"></el-button>
-          <el-date-picker clearable
-                          v-model="queryParams.dataDate"
-                          type="date"
-                          value-format="YYYY-MM-DD"
-                          placeholder="请选择日期"
-                          style="width: 130px"
-                          @change="handleQuery">
-          </el-date-picker>
-          <el-button icon="ArrowRight" @click="navigateDay(1)" size="small" style="margin-left: 15px;"></el-button>
-        </div>
-      </el-form-item>
-    </el-form>
-
-    <!-- 产线选择 -->
-    <el-row :gutter="20" style="margin-bottom: 20px;">
-      <el-col :span="24">
-        <el-card>
-          <!-- Added equipment type and parameter selectors on the same line -->
-          <div style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 10px;">
-            <span>设备类型:</span>
-            <el-select v-model="selectedEquipmentType" placeholder="请选择设备类型" size="small" @change="handleEquipmentTypeChange" clearable style="width: 150px;">
+    <!-- 头部操作区域 -->
+    <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"
@@ -33,8 +33,8 @@
               </el-option>
             </el-select>
             
-            <span style="margin-left: 30px;">设备参数:</span>
-            <el-select v-model="selectedEquipmentParam" placeholder="请选择设备参数" size="small" @change="handleEquipmentParamChange(v)" clearable style="width: 150px;">
+            <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"
@@ -43,39 +43,103 @@
               </el-option>
             </el-select>
           </div>
-          
-          <div style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 10px;">
-            <span>选择产线进行对比:</span>
-            <el-checkbox-group v-model="selectedLines" @change="getDeviceList(v)" style="padding-left: 10px;">
-              <el-checkbox v-for="line in allLines" :key="line" :value="line" :label="`${line}#`">
-                <div v-if="selectedLines.includes(line)" style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 0px;">
-                  <span>{{line}}# 设备:</span>
-                  <el-select v-model="selectedMetrics[line]" placeholder="请选择设备" size="small" @change="updateQueryData" style="width: 150px;">
-                    <el-option
-                      v-for="item in equipmentList[line]"
-                      :key="item.id"
-                      :label="item.name"
-                      :value="item.id">
-                    </el-option>
-                  </el-select>
-                </div>
-                <div v-else>{{ line }}#</div>
-              </el-checkbox>
-            </el-checkbox-group>
+        </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-card>
-      </el-col>
-    </el-row>
+        </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="20">
+    <el-row :gutter="15">
       <!-- 左侧折线图 -->
       <el-col :span="12">
-        <el-card style="margin-bottom: 20px;">
-          <div ref="chartRef0" style="width: 100%; height: 320px;"></div>
+        <el-card style="margin-bottom: 15px;">
+          <div ref="chartRef0" style="width: 100%; height: 400px;"></div>
         </el-card>
-         <el-card style="margin-bottom: 20px;">
-          <el-table :data="rzLineList" height="320" :span-method="spanMethod">
+         <el-card style="margin-bottom: 15px;">
+          <el-table :data="rzLineList" height="400" :span-method="spanMethod">
             <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" >
@@ -89,11 +153,11 @@
 
       <!-- 右侧表格 -->
       <el-col :span="12">
-        <el-card style="margin-bottom: 20px;">
-          <div ref="chartRef1" style="width: 100%; height: 320px;"></div>
+        <el-card style="margin-bottom: 15px;">
+          <div ref="chartRef1" style="width: 100%; height: 400px;"></div>
         </el-card>
-         <el-card style="margin-bottom: 20px;">
-          <el-table :data="rzLineList1" height="320" :span-method="spanMethod">
+         <el-card style="margin-bottom: 15px;">
+          <el-table :data="rzLineList1" height="400" :span-method="spanMethod">
             <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" >
@@ -159,7 +223,7 @@ const data = reactive({
 const selectedEquipmentType = ref('');
 const selectedEquipmentParam = ref('');
 const selectedMetrics = ref({});
-const selectedLines = ref([]);
+const selectedLines = ref([]);  // 多条产线选择
 const equipmentList = ref({});
 const equipmentTypeList = ref([]);
 const equipmentParamOptions = ref([]);
@@ -228,7 +292,6 @@ function navigateDay(offset) {
 }
 /** 查询染整线产线小时统计数据列表 */
 function getList() {
-  selectedLines.value = [];
   // 先获取设备类型列表
   listDeviceTypes({pageSize: 10000}).then(response => {
     equipmentTypeList.value = response.rows;
@@ -239,6 +302,13 @@ function getList() {
         typeName: item.typeName
       };
     });
+    
+    // 默认选择第一条设备类型
+    if (response.rows.length > 0 && !selectedEquipmentType.value) {
+      selectedEquipmentType.value = response.rows[0].typeId;
+      // 触发设备类型变化事件,加载对应的参数
+      handleEquipmentTypeChange(selectedEquipmentType.value);
+    }
   });
 }
 
@@ -251,92 +321,126 @@ function difference(arr1, arr2) {
  * 获取设备列表
  * @returns {void}
  */
-function getDeviceList(v){
-      // 检查是否选择了产线
-    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);
-      console.log("取消了产线:",tmp[0])
-      selectedMetrics.value[tmp[0]] = '';
-      updateQueryData();
-    }
- 
-  let currentLine = 0;
-  if (selectedLines.value.length == 1) {
-    currentLine = selectedLines.value[0];
-  }else{
-    let tmp = difference(selectedLines.value,oldSelectLines.value);
-    if (tmp.length == 1){
-      currentLine = tmp[0];
-    }
+function getDeviceList(){
+  // 检查是否选择了产线
+  if (selectedLines.value.length === 0) {
+    proxy.$modal.msgWarning("请至少选择一条产线进行对比");
+    return;
   }
-  if(currentLine == 0){    
+  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(selectedEquipmentType.value.length == 0){
+  
+  // 处理取消选择产线的情况
+  if (selectedLines.value.length < oldSelectLines.value.length) {
+    // 取消了一条产线
+    let tmp = difference(oldSelectLines.value, selectedLines.value);
+    console.log("取消了产线:", tmp[0]);
+    // 清除取消产线的相关设备选择
+    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
+    return;
   }
-  if(selectedEquipmentParam.value.length == 0){
+  if (!selectedEquipmentParam.value) {
     proxy.$modal.msgError("请先选择设备参数");
-    return
+    return;
   }
 
-  oldSelectLines.value =  JSON.parse(JSON.stringify(selectedLines.value));
-  listDevice({pageSize: 10000,pageNum:1,paraCode:selectedEquipmentParam.value,typeId:selectedEquipmentType.value,line:currentLine}).then(response => {
-    // 提取设备参数选项
-    equipmentList.value[currentLine] = response.rows.map(item => {
-      return {
-        id: item.deviceId,
-        name: item.deviceName
-      };
+  // 为所有选中的产线获取设备列表
+  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
+        };
+      });
     });
   });
+
+  oldSelectLines.value = JSON.parse(JSON.stringify(selectedLines.value));
+  // 如果选择了产线,更新图表
+  if (selectedLines.value.length >= 1) {
+    updateQueryData();
+  }
 }
 
 function updateQueryData() { 
   initChart();
-  rzLineList.value=[];
-  rzLineList1.value=[];
+  rzLineList.value = [];
+  rzLineList1.value = [];
+  
   let queryPara = {
     paraCode: selectedEquipmentParam.value,
     typeId: selectedEquipmentType.value,
     dataDate: queryParams.value.dataDate,
-    pageSize:10000,
-    pageNum:1,
+    pageSize: 10000,
+    pageNum: 1,
   };
-  if(selectedLines.value.length==1){
-    queryPara['line'] = selectedLines.value[0];
-    queryPara['deviceId'] = selectedMetrics.value[selectedLines.value[0]];
-    listHour(queryPara).then(res=>{
-      rzLineList.value = res.rows;
-      updateChart();
-    })
-  }
-  if(selectedLines.value.length==2){
-    queryPara['line'] = selectedLines.value[0];
-    queryPara['deviceId'] = selectedMetrics.value[selectedLines.value[0]];
-    listHour(queryPara).then(res=>{
-      rzLineList.value = res.rows;
-      updateChart();
-    })
-    queryPara['line'] = selectedLines.value[1];
-    queryPara['deviceId'] = selectedMetrics.value[selectedLines.value[1]];
-    listHour(queryPara).then(res=>{
-      rzLineList1.value = res.rows;
-      updateChart1();
-    })
+  
+  // 情况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;
+        updateChart();
+      });
+      
+      // 查询第二个设备的数据
+      queryPara['deviceId'] = selectedMetrics.value[line + '_1'];
+      listHour(queryPara).then(res => {
+        rzLineList1.value = res.rows;
+        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;
+        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;
+        updateChart1();
+      });
+    }
   }
 }
 
@@ -459,6 +563,11 @@ function updateChart() {
   };
 
   chartInstance0.setOption(option, true);
+  
+  // 添加图表点击事件监听
+  chartInstance0.on('click', (params) => {
+    handleChartClick(params, 0);
+  });
 }
 
 
@@ -560,8 +669,61 @@ function updateChart1() {
   };
 
   chartInstance1.setOption(option, true);
+  
+  // 添加图表点击事件监听
+  chartInstance1.on('click', (params) => {
+    handleChartClick(params, 1);
+  });
 }
 
+// 图表点击事件处理函数
+function handleChartClick(params, chartType) {
+  const hour = params.name; // 获取点击的小时
+  let dataList = [];
+  
+  if (chartType === 0) {
+    // 左侧图表
+    dataList = rzLineList.value;
+  } else {
+    // 右侧图表
+    dataList = rzLineList1.value;
+  }
+  
+  // 查找对应小时的数据
+  const targetData = dataList.find(item => 
+    item.hour.toString().padStart(2, '0') === hour
+  );
+  
+  if (targetData && targetData.paraMValue) {
+    try {
+      // 解析分钟级数据
+      const minuteData = typeof targetData.paraMValue === 'string' 
+        ? JSON.parse(targetData.paraMValue) 
+        : targetData.paraMValue;
+      
+      // 设置表格数据
+      minuteTableData.value = minuteData.map(item => ({
+        time: item.time,
+        value: item.value
+      }));
+      
+      // 设置对话框标题和标签
+      minuteDialogTitle.value = `${targetData.deviceName} - ${targetData.paraName} (小时: ${targetData.hour})`;
+      minuteDataLabel.value = targetData.paraName;
+      
+      // 显示对话框
+      minuteDialogVisible.value = true;
+      
+      // 使用 nextTick 确保 DOM 更新后再初始化图表
+      nextTick(() => {
+        initMinuteChart(minuteData, targetData);
+      });
+    } catch (error) {
+      console.error('解析分钟数据失败:', error);
+      proxy.$modal.msgError("数据解析失败");
+    }
+  }
+}
 
 // 窗口大小改变时重置图表大小
 function resizeChart() {
@@ -634,7 +796,8 @@ function handleQuery() {
     proxy.$modal.msgWarning("请选择日期");
     return;
   }
-  getList();
+  // 不要重置已选择的产线和设备,仅更新数据
+  updateQueryData();
 }
 
 /** 重置按钮操作 */
@@ -647,8 +810,10 @@ function resetQuery() {
   const day = now.getDate().toString().padStart(2, '0');
   queryParams.value.dataDate = `${year}-${month}-${day}`;
 
-  // 默认选择所有产线
-  selectedLines.value = [...allLines.value];
+  // 重置产线和设备选择
+  selectedLines.value = [];
+  selectedMetrics.value = {};
+  equipmentList.value = {};
 
   handleQuery();
 }
@@ -708,6 +873,13 @@ function handleEquipmentTypeChange(val) {
           paraName: item.paraName
         };
       });
+      
+      // 默认选择第一条设备参数
+      if (selectedType.dyeTypeParaList.length > 0 && !selectedEquipmentParam.value) {
+        selectedEquipmentParam.value = selectedType.dyeTypeParaList[0].paraCode;
+        // 触发设备参数变化事件
+        handleEquipmentParamChange();
+      }
     } else {
       equipmentParamOptions.value = [];
     }
@@ -726,11 +898,19 @@ function handleEquipmentParamChange() {
   updateQueryData();
 }
 
-// 多选框选中数据
-function handleSelectionChange(selection) {
-  ids.value = selection.map(item => item.id);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
+// 处理产线选择变化
+function handleLineSelectionChange(val) {
+  console.log('产线选择变化:', val);
+  if (val.length > 2) {
+    // 限制最多选择两条产线
+    selectedLines.value = val.slice(0, 2);
+    proxy.$modal.msgWarning("最多只能选择两条产线进行对比");
+  }
+  // 当取消选择所有产线时,清空相关设备选择
+  if (val.length === 0) {
+    selectedMetrics.value = {};
+  }
+  getDeviceList();
 }
 
 /** 新增按钮操作 */