From 2a69f1a4365fb7daa8d00c07ac859a0d45780eb7 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 09 九月 2026 17:31:10 +0800
Subject: [PATCH] docs(mes): 添加设备数采API调试文档

---
 yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiDecisionKpiServiceImpl.java |  107 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 107 insertions(+), 0 deletions(-)

diff --git a/yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiDecisionKpiServiceImpl.java b/yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiDecisionKpiServiceImpl.java
index 5eea031..6e115e4 100644
--- a/yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiDecisionKpiServiceImpl.java
+++ b/yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiDecisionKpiServiceImpl.java
@@ -1,13 +1,18 @@
 package cn.iocoder.yudao.module.bi.service.decision;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.module.bi.dal.dataobject.decision.BiKpiValueHistoryDO;
 import cn.iocoder.yudao.module.bi.dal.mysql.decision.BiKpiDefinitionMapper;
 import cn.iocoder.yudao.module.bi.dal.dataobject.decision.BiKpiDefinitionDO;
+import cn.iocoder.yudao.module.bi.dal.mysql.decision.BiKpiValueHistoryMapper;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
 import java.util.*;
 
 /**
@@ -23,6 +28,9 @@
 
     @Resource
     private BiKpiDefinitionMapper kpiMapper;
+
+    @Resource
+    private BiKpiValueHistoryMapper kpiValueHistoryMapper;
 
     @Resource
     private JdbcTemplate jdbcTemplate;
@@ -105,6 +113,105 @@
         return executeKpiSql(kpi.getQuerySql());
     }
 
+    @Override
+    public Map<String, Object> getKpiTrend(String kpiCode, LocalDateTime beginTime,
+                                           LocalDateTime endTime, String periodType) {
+        BiKpiDefinitionDO kpi = kpiMapper.selectOne(BiKpiDefinitionDO::getCode, kpiCode);
+        Map<String, Object> result = new LinkedHashMap<>();
+        result.put("kpiCode", kpiCode);
+        result.put("kpiName", kpi != null ? kpi.getName() : kpiCode);
+        result.put("category", kpi != null ? kpi.getCategory() : null);
+        result.put("unit", kpi != null ? kpi.getUnit() : null);
+        result.put("periodType", periodType != null ? periodType : "hour");
+
+        if (kpi == null) {
+            result.put("points", Collections.emptyList());
+            return result;
+        }
+
+        LocalDateTime begin = beginTime != null ? beginTime :
+                LocalDateTime.now().minusDays(30);
+        LocalDateTime end = endTime != null ? endTime : LocalDateTime.now();
+        List<BiKpiValueHistoryDO> history = kpiValueHistoryMapper
+                .selectByKpiCodeAndTimeRange(kpiCode, begin, end);
+
+        List<Map<String, Object>> points = new ArrayList<>();
+        for (BiKpiValueHistoryDO h : history) {
+            Map<String, Object> p = new LinkedHashMap<>();
+            p.put("time", h.getSnapshotTime());
+            p.put("value", h.getKpiValue());
+            points.add(p);
+        }
+        result.put("points", points);
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getKpiCompare(String kpiCode) {
+        BiKpiDefinitionDO kpi = kpiMapper.selectOne(BiKpiDefinitionDO::getCode, kpiCode);
+        Map<String, Object> result = new LinkedHashMap<>();
+        result.put("kpiCode", kpiCode);
+        result.put("kpiName", kpi != null ? kpi.getName() : kpiCode);
+        result.put("unit", kpi != null ? kpi.getUnit() : null);
+
+        // 鍙栨渶杩� 24 鏉″揩鐓э紙鎸夋椂闂村�掑簭锛夛紝鏈�杩戜竴鏉′负褰撳墠鍊�
+        List<BiKpiValueHistoryDO> recent = kpiValueHistoryMapper.selectRecentByKpiCode(kpiCode, 24);
+        if (CollUtil.isEmpty(recent)) {
+            result.put("currentValue", null);
+            result.put("previousValue", null);
+            result.put("changeRate", null);
+            result.put("avgValue", null);
+            result.put("maxValue", null);
+            result.put("minValue", null);
+            return result;
+        }
+
+        // recent 涓哄�掑簭锛岀 0 鏉℃渶鏂�
+        BiKpiValueHistoryDO current = recent.get(0);
+        result.put("currentTime", current.getSnapshotTime());
+        result.put("currentValue", current.getKpiValue());
+
+        if (recent.size() > 1) {
+            BiKpiValueHistoryDO previous = recent.get(1);
+            result.put("previousTime", previous.getSnapshotTime());
+            result.put("previousValue", previous.getKpiValue());
+            result.put("changeRate", calcChangeRate(previous.getKpiValue(), current.getKpiValue()));
+        } else {
+            result.put("previousValue", null);
+            result.put("changeRate", null);
+        }
+
+        // 杩� 24 鏈熺粺璁℃眹鎬�
+        BigDecimal sum = BigDecimal.ZERO;
+        BigDecimal max = null;
+        BigDecimal min = null;
+        for (BiKpiValueHistoryDO h : recent) {
+            if (h.getKpiValue() == null) {
+                continue;
+            }
+            sum = sum.add(h.getKpiValue());
+            max = max == null ? h.getKpiValue() : h.getKpiValue().max(max);
+            min = min == null ? h.getKpiValue() : h.getKpiValue().min(min);
+        }
+        result.put("periodCount", recent.size());
+        if (recent.size() > 0) {
+            result.put("avgValue", sum.divide(BigDecimal.valueOf(recent.size()), 4, RoundingMode.HALF_UP));
+        } else {
+            result.put("avgValue", BigDecimal.ZERO);
+        }
+        result.put("maxValue", max);
+        result.put("minValue", min);
+        return result;
+    }
+
+    private BigDecimal calcChangeRate(BigDecimal previous, BigDecimal current) {
+        if (previous == null || current == null || previous.compareTo(BigDecimal.ZERO) == 0) {
+            return null;
+        }
+        return current.subtract(previous).divide(previous, 4, RoundingMode.HALF_UP)
+                .multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
+    }
+
     /**
      * 鎵ц KPI 鏌ヨ SQL
      */

--
Gitblit v1.9.3