From a0a0c3a839a43c1d2632b125fbf9b6c87c6f11cc Mon Sep 17 00:00:00 2001 From: Lxy Date: Sat, 31 Jan 2026 12:03:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=89=B9=E9=87=8F=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E3=80=81=E6=89=B9=E9=87=8F=E5=88=86=E6=9E=90=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/StockDataController.java | 10 ++ .../newstocksystem/mapper/TTrendsMapper.java | 7 + .../service/IStockDailyTradeService.java | 7 + .../impl/StockDailyTradeServiceImpl.java | 62 ++++++++ .../mapper/newstocksystem/TTrendsMapper.xml | 6 + ruoyi-ui/src/api/newstocksystem/stockdata.js | 8 ++ .../src/views/newstocksystem/stockdata.vue | 134 ++++++++++++++++++ 7 files changed, 234 insertions(+) diff --git a/newstock-system/src/main/java/com/ruoyi/newstocksystem/controller/StockDataController.java b/newstock-system/src/main/java/com/ruoyi/newstocksystem/controller/StockDataController.java index db152dd..4264004 100644 --- a/newstock-system/src/main/java/com/ruoyi/newstocksystem/controller/StockDataController.java +++ b/newstock-system/src/main/java/com/ruoyi/newstocksystem/controller/StockDataController.java @@ -349,6 +349,16 @@ public class StockDataController extends BaseController String result = stockDailyTradeService.analysisStockData(stockDailyTrade); return AjaxResult.success(result); } + + /** + * 获取所有未分析的交易日期 + */ + @GetMapping("/unanalyzedDates") + public AjaxResult getUnanalyzedDates() + { + List unanalyzedDates = stockDailyTradeService.selectUnanalyzedDates(); + return AjaxResult.success(unanalyzedDates); + } // ========================= 个股新高新低状态相关接口 ========================= diff --git a/newstock-system/src/main/java/com/ruoyi/newstocksystem/mapper/TTrendsMapper.java b/newstock-system/src/main/java/com/ruoyi/newstocksystem/mapper/TTrendsMapper.java index c28f6aa..4b14fb9 100644 --- a/newstock-system/src/main/java/com/ruoyi/newstocksystem/mapper/TTrendsMapper.java +++ b/newstock-system/src/main/java/com/ruoyi/newstocksystem/mapper/TTrendsMapper.java @@ -135,4 +135,11 @@ public interface TTrendsMapper * @return 趋势数据列表 */ public List getTrendsByDateAndType(TTrends tTrends); + + /** + * 获取最后一个已分析的交易日 + * + * @return 最后一个已分析的交易日(格式:yyyy-MM-dd) + */ + public String selectLastAnalyzedDate(); } \ No newline at end of file diff --git a/newstock-system/src/main/java/com/ruoyi/newstocksystem/service/IStockDailyTradeService.java b/newstock-system/src/main/java/com/ruoyi/newstocksystem/service/IStockDailyTradeService.java index bb6df84..568cdc1 100644 --- a/newstock-system/src/main/java/com/ruoyi/newstocksystem/service/IStockDailyTradeService.java +++ b/newstock-system/src/main/java/com/ruoyi/newstocksystem/service/IStockDailyTradeService.java @@ -117,4 +117,11 @@ public interface IStockDailyTradeService * @return 是否已存在分析数据 */ public boolean checkTrendsExists(Date tradeDate); + + /** + * 获取所有未分析的交易日期 + * + * @return 未分析的交易日期列表(格式:yyyy-MM-dd) + */ + public List selectUnanalyzedDates(); } diff --git a/newstock-system/src/main/java/com/ruoyi/newstocksystem/service/impl/StockDailyTradeServiceImpl.java b/newstock-system/src/main/java/com/ruoyi/newstocksystem/service/impl/StockDailyTradeServiceImpl.java index 18b4c60..04030bc 100644 --- a/newstock-system/src/main/java/com/ruoyi/newstocksystem/service/impl/StockDailyTradeServiceImpl.java +++ b/newstock-system/src/main/java/com/ruoyi/newstocksystem/service/impl/StockDailyTradeServiceImpl.java @@ -11,6 +11,8 @@ import java.util.Map; import java.util.Arrays; import java.util.Calendar; import java.util.stream.Collectors; +import java.text.ParseException; +import java.text.SimpleDateFormat; import com.ruoyi.newstocksystem.domain.*; import com.ruoyi.newstocksystem.mapper.TStocksInTrendMapper; @@ -409,6 +411,66 @@ public class StockDailyTradeServiceImpl implements IStockDailyTradeService } } + @Override + public List selectUnanalyzedDates() + { + logger.info("开始获取未分析的交易日期"); + try { + // 1. 从t_trends获取最后一个交易日(已分析的最后日期) + String lastAnalyzedDateStr = trendsMapper.selectLastAnalyzedDate(); + Date lastAnalyzedDate = null; + if (lastAnalyzedDateStr != null) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + lastAnalyzedDate = sdf.parse(lastAnalyzedDateStr); + logger.info("最后一个已分析的交易日: {}", lastAnalyzedDateStr); + } else { + logger.info("没有已分析的交易日,将获取所有交易日期"); + } + + // 2. 在t_stock_daily_trade中获取该日之后所有有数据的交易日 + List allTradeDates = stockDailyTradeMapper.selectTradeDates(); + logger.info("所有交易日期数量: {}", allTradeDates.size()); + + // 3. 过滤掉已经分析过的日期,返回未分析的日期列表 + List unanalyzedDates = new ArrayList<>(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + + for (String dateStr : allTradeDates) { + Date tradeDate = sdf.parse(dateStr); + + // 如果没有已分析的日期,或者当前日期在最后分析日期之后 + if (lastAnalyzedDate == null || tradeDate.after(lastAnalyzedDate)) { + // 检查该日期是否已分析 + if (!checkTrendsExists(tradeDate)) { + unanalyzedDates.add(dateStr); + } + } + } + + // 4. 对未分析日期列表按照日期升序排列(时间更早的在前面) + unanalyzedDates.sort((date1, date2) -> { + try { + Date d1 = sdf.parse(date1); + Date d2 = sdf.parse(date2); + return d1.compareTo(d2); + } catch (ParseException e) { + logger.error("日期排序失败", e); + throw new RuntimeException("日期排序失败: " + e.getMessage()); + } + }); + + logger.info("未分析的交易日期数量: {}", unanalyzedDates.size()); + if (!unanalyzedDates.isEmpty()) { + logger.info("最早的未分析交易日: {}", unanalyzedDates.get(0)); + logger.info("最晚的未分析交易日: {}", unanalyzedDates.get(unanalyzedDates.size() - 1)); + } + return unanalyzedDates; + } catch (Exception e) { + logger.error("获取未分析的交易日期失败", e); + throw new RuntimeException("获取未分析的交易日期失败: " + e.getMessage()); + } + } + /** * 检查指定日期是否存在交易数据 * diff --git a/newstock-system/src/main/resources/mapper/newstocksystem/TTrendsMapper.xml b/newstock-system/src/main/resources/mapper/newstocksystem/TTrendsMapper.xml index f9c829d..f1b907f 100644 --- a/newstock-system/src/main/resources/mapper/newstocksystem/TTrendsMapper.xml +++ b/newstock-system/src/main/resources/mapper/newstocksystem/TTrendsMapper.xml @@ -189,4 +189,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND momentum_type = #{momentumType} ORDER BY `rank` + + + \ No newline at end of file diff --git a/ruoyi-ui/src/api/newstocksystem/stockdata.js b/ruoyi-ui/src/api/newstocksystem/stockdata.js index cdf5063..b79cf59 100644 --- a/ruoyi-ui/src/api/newstocksystem/stockdata.js +++ b/ruoyi-ui/src/api/newstocksystem/stockdata.js @@ -176,6 +176,14 @@ export default { }) }, + // 获取所有未分析的交易日期 + getUnanalyzedDates() { + return request({ + url: '/newstocksystem/stockdata/unanalyzedDates', + method: 'get' + }) + }, + // ========================= 个股新高新低状态相关 ========================= // 查询个股新高新低状态列表 diff --git a/ruoyi-ui/src/views/newstocksystem/stockdata.vue b/ruoyi-ui/src/views/newstocksystem/stockdata.vue index eb026a7..ba58b3a 100644 --- a/ruoyi-ui/src/views/newstocksystem/stockdata.vue +++ b/ruoyi-ui/src/views/newstocksystem/stockdata.vue @@ -28,6 +28,11 @@ 导入新高新低数据 + + + 批量分析数据 + + @@ -390,6 +395,48 @@ 取 消 + + + +
+ + 正在获取未分析的交易日期... +
+
+ + 所有交易日期都已分析 +
+
+ 未分析的交易日期 + + + + + + + +
+ +
@@ -489,6 +536,14 @@ export default { }, batchFileList: [], + // ========================= 批量分析相关 ========================= + batchAnalysis: { + open: false, + loading: false, + analyzing: false, + unanalyzedDates: [] + }, + // ========================= 分析状态相关 ========================= analysisStatus: { isAnalyzed: false, // 当前选择日期是否已分析 @@ -1008,6 +1063,85 @@ export default { resolve() // 继续处理下一个文件,即使当前文件失败 }) }) + }, + + // ========================= 批量分析方法 ========================= + + /** 打开批量分析对话框 */ + handleBatchAnalysis() { + this.batchAnalysis.open = true + this.batchAnalysis.loading = true + this.batchAnalysis.unanalyzedDates = [] + // 获取未分析的交易日期 + this.getUnanalyzedDates() + }, + + /** 获取未分析的交易日期 */ + getUnanalyzedDates() { + stockdataApi.getUnanalyzedDates().then(response => { + this.batchAnalysis.loading = false + if (response.data && Array.isArray(response.data)) { + // 格式化未分析日期列表,添加状态 + this.batchAnalysis.unanalyzedDates = response.data.map(date => ({ + tradeDate: date, + status: 'pending' + })) + } + }).catch(error => { + this.batchAnalysis.loading = false + this.$message.error('获取未分析的交易日期失败:' + (error.msg || error.message || '未知错误')) + }) + }, + + /** 提交批量分析 */ + submitBatchAnalysis() { + if (this.batchAnalysis.unanalyzedDates.length === 0) { + this.$message.warning('没有未分析的交易日期') + return + } + + this.batchAnalysis.analyzing = true + + // 按顺序处理每个未分析的日期 + const processAnalysis = async (index) => { + if (index >= this.batchAnalysis.unanalyzedDates.length) { + // 所有日期分析完成 + this.batchAnalysis.analyzing = false + this.batchAnalysis.open = false + this.$message.success('批量分析完成') + // 刷新数据列表 + this.getDailyTradeList() + return + } + + const dateItem = this.batchAnalysis.unanalyzedDates[index] + try { + await this.processBatchAnalysis(dateItem) + // 处理下一个日期 + processAnalysis(index + 1) + } catch (error) { + this.batchAnalysis.analyzing = false + this.$message.error('批量分析过程中发生错误:' + (error.message || '未知错误')) + } + } + + // 开始处理第一个日期 + processAnalysis(0) + }, + + /** 处理单个日期的分析 */ + processBatchAnalysis(dateItem) { + return new Promise((resolve, reject) => { + stockdataApi.analysis({ tradeDate: dateItem.tradeDate }).then(response => { + // 更新日期状态为成功 + dateItem.status = 'success' + resolve() + }).catch(error => { + // 更新日期状态为失败 + dateItem.status = 'error' + resolve() // 继续处理下一个日期,即使当前日期分析失败 + }) + }) } } }