wukai vor 2 Wochen
Ursprung
Commit
af1a24fa9d
2 geänderte Dateien mit 263 neuen und 5 gelöschten Zeilen
  1. 8 0
      src/api/calc/calcSpec.js
  2. 255 5
      src/views/calc/calcSpec/index.vue

+ 8 - 0
src/api/calc/calcSpec.js

@@ -9,6 +9,14 @@ export function listCalcSpec(query) {
     })
 }
 
+export function trend(query){
+    return request({
+        url: '/calc/calcSpec/trend',
+        method: 'get',
+        params: query
+    })
+}
+
 // 查询按配方1小时统计数据详细
 export function getCalcSpec(id) {
     return request({

+ 255 - 5
src/views/calc/calcSpec/index.vue

@@ -36,12 +36,21 @@
         </el-select>
       </el-form-item>
 
-<!--      <el-form-item>-->
-<!--        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>-->
-<!--        <el-button icon="Refresh" @click="resetQuery">重置</el-button>-->
-<!--      </el-form-item>-->
+      <el-form-item>
+        <el-button type="success" @click="viewTrend">查看近5日织造米数</el-button>
+      </el-form-item>
     </el-form>
 
+    <!-- 图表弹窗 -->
+    <el-dialog title="近5日织造米数趋势图" v-model="chartDialogVisible" width="800px" append-to-body>
+      <div ref="chartRef" style="width: 100%; height: 400px;"></div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeChartDialog">关闭</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
     <el-table v-loading="loading" :data="calcSpecList" show-summary :summary-method="getSummaries"
               @selection-change="handleSelectionChange">
       <el-table-column label="日期" align="center" prop="dataDate" width="180">
@@ -107,8 +116,10 @@
 </template>
 
 <script setup name="CalcSpec">
-import {addCalcSpec, delCalcSpec, getCalcSpec, listCalcSpec, updateCalcSpec} from "@/api/calc/calcSpec";
+import {addCalcSpec, delCalcSpec, getCalcSpec, listCalcSpec, updateCalcSpec,trend} from "@/api/calc/calcSpec";
 import {listDevice} from "@/api/biz/device"
+import * as echarts from 'echarts';
+import { nextTick } from 'vue';
 
 const {proxy} = getCurrentInstance();
 const {in_out_time} = proxy.useDict('in_out_time');
@@ -122,6 +133,10 @@ const multiple = ref(true);
 const total = ref(0);
 const title = ref("");
 const deviceOptions = ref([]);
+const chartRef = ref(null);
+let chartInstance = null;
+const chartDialogVisible = ref(false);
+const trendData = ref({});
 
 const data = reactive({
   form: {},
@@ -202,6 +217,241 @@ function getList() {
   });
 }
 
+/**查询趋势*/
+function viewTrend(){
+  trend(queryParams.value).then(response => {
+    // 保存数据并显示图表弹窗
+    trendData.value = response;
+    chartDialogVisible.value = true;
+    // 等待DOM更新后初始化图表
+    nextTick(() => {
+      initChart(response);
+    });
+  });
+}
+
+// 关闭图表弹窗
+function closeChartDialog() {
+  chartDialogVisible.value = false;
+  // 销毁图表实例
+  if (chartInstance) {
+    chartInstance.dispose();
+    chartInstance = null;
+  }
+}
+
+// 初始化图表
+function initChart(data) {
+  // 销毁之前的图表实例
+  if (chartInstance) {
+    chartInstance.dispose();
+  }
+
+  // 初始化新的图表实例
+  chartInstance = echarts.init(chartRef.value);
+
+  console.log('传入initChart的数据:', data); // 调试信息
+
+  // 处理数据 - 修正数据访问路径
+  let responseData = data.data.data;
+
+  const timestamps = responseData.timestamps || [];
+  const values = responseData.values || [];
+
+  console.log('提取的原始数据:', { timestamps, values }); // 调试信息
+
+  // 将时间戳转换为日期字符串 (mm-dd hh:mm格式)
+  const dates = timestamps.map(timestamp => {
+    const date = new Date(timestamp);
+    const month = (date.getMonth() + 1).toString().padStart(2, '0');
+    const day = date.getDate().toString().padStart(2, '0');
+    const hours = date.getHours().toString().padStart(2, '0');
+    const minutes = date.getMinutes().toString().padStart(2, '0');
+    return `${month}-${day} ${hours}:${minutes}`;
+  });
+
+  // 提取数值(处理嵌套数组)
+  const chartValues = [];
+  const validDates = [];
+
+  values.forEach((item, index) => {
+    // 检查是否有足够的数据点
+    if (Array.isArray(item) && item.length > 0) {
+      // 获取第一个元素并尝试转为数字
+      const rawValue = item[0];
+      const numericValue = parseFloat(rawValue);
+
+      // 检查转换后的值是否有效
+      if (!isNaN(numericValue)) {
+        chartValues.push(numericValue);
+        validDates.push(dates[index]);
+      } else if (typeof rawValue === 'number' && !isNaN(rawValue)) {
+        // 如果本身就是数字
+        chartValues.push(rawValue);
+        validDates.push(dates[index]);
+      }
+    }
+  });
+
+  console.log('处理后的图表数据:', { validDates, chartValues }); // 调试信息
+
+  // 如果没有有效数据,显示提示
+  if (validDates.length === 0 && chartValues.length === 0) {
+    chartInstance.setOption({
+      title: {
+        text: '暂无有效数据',
+        left: 'center',
+        top: 'center'
+      }
+    });
+    return;
+  }
+
+  // 计算默认显示的时间范围(根据选择的日期和时段)
+  let startIndex = 0;
+  let endIndex = validDates.length - 1;
+
+  if (queryParams.value.dataDate && queryParams.value.remark) {
+    // 解析时段,例如 "7-19" 或 "23-7"
+    const timeRange = queryParams.value.remark.split('-');
+    if (timeRange.length === 2) {
+      const startTime = parseInt(timeRange[0]);
+      const endTime = parseInt(timeRange[1]);
+
+      // 构造选择的日期
+      const selectedDate = new Date(queryParams.value.dataDate);
+      const month = (selectedDate.getMonth() + 1).toString().padStart(2, '0');
+      const day = selectedDate.getDate().toString().padStart(2, '0');
+
+      // 判断是否是跨天时段(如23-7)
+      if (startTime > endTime) {
+        // 跨天时段处理,例如 23-7 表示当天23点到次日7点
+        // 查找当天23点开始的数据
+        const startDateTime = `${month}-${day} ${startTime.toString().padStart(2, '0')}:00`;
+        const startTimeIndex = validDates.findIndex(date => date.startsWith(startDateTime));
+        if (startTimeIndex !== -1) {
+          startIndex = startTimeIndex;
+        }
+
+        // 查找次日7点的数据
+        const nextDay = new Date(selectedDate);
+        nextDay.setDate(nextDay.getDate() + 1);
+        const nextMonth = (nextDay.getMonth() + 1).toString().padStart(2, '0');
+        const nextDayStr = nextDay.getDate().toString().padStart(2, '0');
+        const endDateTime = `${nextMonth}-${nextDayStr} ${endTime.toString().padStart(2, '0')}:00`;
+        const endTimeIndex = validDates.findIndex(date => date.startsWith(endDateTime));
+        if (endTimeIndex !== -1) {
+          endIndex = endTimeIndex;
+        }
+      } else {
+        // 正常时段处理,例如 7-19 表示当天7点到19点
+        // 查找开始时间索引
+        const startDateTime = `${month}-${day} ${startTime.toString().padStart(2, '0')}:00`;
+        const startTimeIndex = validDates.findIndex(date => date.startsWith(startDateTime));
+        if (startTimeIndex !== -1) {
+          startIndex = startTimeIndex;
+        }
+
+        // 查找结束时间索引
+        const endDateTime = `${month}-${day} ${endTime.toString().padStart(2, '0')}:00`;
+        const endTimeIndex = validDates.findIndex(date => date.startsWith(endDateTime));
+        if (endTimeIndex !== -1) {
+          endIndex = endTimeIndex;
+        } else {
+          // 如果找不到确切的结束时间,尝试查找最接近的时间点
+          for (let i = validDates.length - 1; i >= 0; i--) {
+            if (validDates[i].startsWith(`${month}-${day}`)) {
+              endIndex = i;
+              break;
+            }
+          }
+        }
+      }
+
+      // 确保索引范围合理
+      if (startIndex >= endIndex) {
+        endIndex = Math.min(startIndex + 10, validDates.length - 1); // 默认显示10个点
+      }
+    }
+  }
+
+  // 配置图表选项 - 遵循项目规范
+  const option = {
+    title: {
+      text: '近5日织造米数趋势图',
+      left: 'center'
+    },
+    tooltip: {
+      trigger: 'axis',
+      formatter: function (params) {
+        const date = params[0].axisValue;
+        const value = params[0].data;
+        return `${date}<br/>织造米数: ${value}`;
+      }
+    },
+    dataZoom: [
+      {
+        type: 'inside',
+        startValue: startIndex,
+        endValue: endIndex
+      },
+      {
+        type: 'slider',
+        startValue: startIndex,
+        endValue: endIndex,
+        bottom: 10
+      }
+    ],
+    xAxis: {
+      type: 'category',
+      data: validDates.length > 0 ? validDates : dates, // 如果有有效日期则使用,否则使用全部日期
+      name: '时间',
+      axisLabel: {
+        formatter: '{value}',
+        rotate: 45 // 旋转标签以避免重叠
+      },
+      splitLine: {
+        show: false  // 遵循规范:不显示网格线
+      }
+    },
+    yAxis: {
+      type: 'value',
+      name: '织造米数',
+      splitLine: {
+        show: false  // 遵循规范:不显示网格线
+      }
+    },
+    series: [{
+      data: chartValues.length > 0 ? chartValues : values, // 如果有处理后的数据则使用,否则使用原始数据
+      type: 'line',
+      smooth: true,
+      showSymbol: false,  // 遵循规范:不显示数据点小圆圈
+      itemStyle: {
+        color: '#409EFF'
+      },
+      markPoint: {
+        data: [
+          {type: 'max', name: '最大值', itemStyle: {color: '#F56C6C'}},
+          {type: 'min', name: '最小值', itemStyle: {color: '#67C23A'}}
+        ]
+      },
+      markLine: {
+        data: [
+          {type: 'average', name: '平均值'}
+        ]
+      }
+    }]
+  };
+
+  // 设置图表配置
+  chartInstance.setOption(option);
+
+  // 监听窗口大小变化,自适应图表
+  window.addEventListener('resize', () => {
+    chartInstance.resize();
+  });
+}
+
 //自定义方法
 function getSummaries(param) {
   const {columns, data} = param;