From 1dfdc3b0611211feba0570ec6d8cfad078c37135 Mon Sep 17 00:00:00 2001
From: xiaoyi <908147524@qq.com>
Date: 星期三, 26 八月 2026 15:13:28 +0800
Subject: [PATCH] feat 功能修正
---
yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiForecastServiceImpl.java | 50 ++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiForecastServiceImpl.java b/yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiForecastServiceImpl.java
index 6f183d3..478da23 100644
--- a/yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiForecastServiceImpl.java
+++ b/yudao-module-bi/src/main/java/cn/iocoder/yudao/module/bi/service/decision/BiForecastServiceImpl.java
@@ -1,6 +1,8 @@
package cn.iocoder.yudao.module.bi.service.decision;
+import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
+import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastHistorySaveReqVO;
import cn.iocoder.yudao.module.bi.controller.admin.decision.vo.DecisionForecastWorkOrderCreateReqVO;
import cn.iocoder.yudao.module.bi.dal.dataobject.decision.BiForecastDataDO;
import cn.iocoder.yudao.module.bi.dal.mysql.decision.BiForecastDataMapper;
@@ -12,10 +14,12 @@
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.bi.enums.ErrorCodeConstants.BI_FORECAST_NO_HISTORY;
import static cn.iocoder.yudao.module.bi.enums.ErrorCodeConstants.BI_FORECAST_NOT_EXISTS;
/**
@@ -44,21 +48,51 @@
return forecastDataMapper.selectListByCodeAndTimeRange(forecastCode, beginTime, endTime);
}
+ /**
+ * 绉诲姩骞冲潎绐楀彛澶у皬
+ */
+ private static final int SMA_WINDOW = 12;
+
+ @Override
+ public Long createForecastHistory(DecisionForecastHistorySaveReqVO reqVO) {
+ BiForecastDataDO data = BiForecastDataDO.builder()
+ .forecastCode(reqVO.getForecastCode())
+ .forecastName(reqVO.getForecastName())
+ .pointTime(reqVO.getPointTime())
+ .forecastValue(reqVO.getForecastValue())
+ .actualValue(reqVO.getActualValue())
+ .dimension(reqVO.getDimension())
+ .dimensionValue(reqVO.getDimensionValue())
+ .remark(reqVO.getRemark())
+ .modelVersion("manual-history")
+ .build();
+ forecastDataMapper.insert(data);
+ return data.getId();
+ }
+
@Override
public void generateForecast(String forecastCode, LocalDateTime pointTime) {
- // 鏈湡鍗犱綅锛氱畝鍗曠Щ鍔ㄥ钩鍧囬娴�
- // 瀹為檯椤圭洰搴旈泦鎴� ML 妯″瀷锛圓RIMA/Prophet/LSTM锛�
- log.info("[generateForecast][鐢熸垚棰勬祴] forecastCode={}, pointTime={}, 褰撳墠涓哄崰浣嶅疄鐜�", forecastCode, pointTime);
+ // 鍩轰簬鍚岄娴嬬紪鐮佺殑鍘嗗彶棰勬祴鏁版嵁鍋氱畝鍗曠Щ鍔ㄥ钩鍧囷紱鏃犲巻鍙叉暟鎹椂涓嶄吉閫犻浂鍊�
+ List<BiForecastDataDO> history = forecastDataMapper.selectRecentByCode(forecastCode, SMA_WINDOW);
+ if (CollUtil.isEmpty(history)) {
+ throw exception(BI_FORECAST_NO_HISTORY);
+ }
+ BigDecimal sum = history.stream()
+ .map(BiForecastDataDO::getForecastValue)
+ .filter(value -> value != null)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ BigDecimal avg = sum.divide(BigDecimal.valueOf(history.size()), 4, RoundingMode.HALF_UP);
+ BigDecimal bound = avg.multiply(new BigDecimal("0.10"));
BiForecastDataDO forecast = BiForecastDataDO.builder()
.forecastCode(forecastCode)
- .forecastName("璐熻嵎棰勬祴(鍗犱綅)")
+ .forecastName(history.get(0).getForecastName())
.pointTime(pointTime)
- .forecastValue(BigDecimal.ZERO)
- .lowerBound(BigDecimal.ZERO)
- .upperBound(BigDecimal.ZERO)
+ .forecastValue(avg)
+ .lowerBound(avg.subtract(bound))
+ .upperBound(avg.add(bound))
.confidenceLevel(new BigDecimal("95.00"))
- .modelVersion("v1.0-placeholder")
+ .modelVersion("v1.0-sma")
.build();
forecastDataMapper.insert(forecast);
}
--
Gitblit v1.9.3