|
|
@@ -231,6 +231,27 @@ public class StockPoolHistoryServiceImpl implements IStockPoolHistoryService {
|
|
|
StringBuilder successMsg = new StringBuilder();
|
|
|
StringBuilder failureMsg = new StringBuilder();
|
|
|
|
|
|
+ // 批量查询已存在的记录
|
|
|
+ List<String> stockCodes = dataList.stream()
|
|
|
+ .map(StockPoolHistoryVo::getStockCode)
|
|
|
+ .filter(StringUtils::isNotBlank)
|
|
|
+ .distinct()
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
+
|
|
|
+ Map<String, StockPoolHistory> existingMap = new java.util.HashMap<>();
|
|
|
+ if (!stockCodes.isEmpty()) {
|
|
|
+ LambdaQueryWrapper<StockPoolHistory> lqw = Wrappers.lambdaQuery();
|
|
|
+ lqw.in(StockPoolHistory::getStockCode, stockCodes)
|
|
|
+ .eq(StockPoolHistory::getRecordDate, parsedRecordDate);
|
|
|
+ List<StockPoolHistory> existingList = baseMapper.selectList(lqw);
|
|
|
+ existingMap = existingList.stream()
|
|
|
+ .collect(java.util.stream.Collectors.toMap(StockPoolHistory::getStockCode, e -> e));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 准备批量插入和更新的列表
|
|
|
+ List<StockPoolHistory> toInsertList = new ArrayList<>();
|
|
|
+ List<StockPoolHistory> toUpdateList = new ArrayList<>();
|
|
|
+
|
|
|
for (int i = 0; i < dataList.size(); i++) {
|
|
|
StockPoolHistoryVo vo = dataList.get(i);
|
|
|
try {
|
|
|
@@ -342,11 +363,8 @@ public class StockPoolHistoryServiceImpl implements IStockPoolHistoryService {
|
|
|
// 使用管理员指定的记录日期,而不是Excel中的日期
|
|
|
vo.setRecordDate(parsedRecordDate);
|
|
|
|
|
|
- // 检查是否已存在(根据股票代码和记录日期)
|
|
|
- LambdaQueryWrapper<StockPoolHistory> lqw = Wrappers.lambdaQuery();
|
|
|
- lqw.eq(StockPoolHistory::getStockCode, vo.getStockCode())
|
|
|
- .eq(StockPoolHistory::getRecordDate, parsedRecordDate);
|
|
|
- StockPoolHistory existing = baseMapper.selectOne(lqw);
|
|
|
+ // 检查是否已存在
|
|
|
+ StockPoolHistory existing = existingMap.get(vo.getStockCode());
|
|
|
|
|
|
if (existing != null) {
|
|
|
if (updateSupport) {
|
|
|
@@ -364,9 +382,7 @@ public class StockPoolHistoryServiceImpl implements IStockPoolHistoryService {
|
|
|
existing.setDayLowestPrice(vo.getDayLowestPrice());
|
|
|
existing.setDayAvgPrice(vo.getDayAvgPrice());
|
|
|
existing.setDayClosePrice(vo.getDayClosePrice());
|
|
|
- // 计算行情涨跌(最高涨幅)
|
|
|
- existing.setHighTrend(calculateHighTrend(vo.getStockCode(), parsedRecordDate, vo.getDayHighestPrice()));
|
|
|
- baseMapper.updateById(existing);
|
|
|
+ toUpdateList.add(existing);
|
|
|
updateNum++;
|
|
|
successNum++;
|
|
|
} else {
|
|
|
@@ -380,9 +396,7 @@ public class StockPoolHistoryServiceImpl implements IStockPoolHistoryService {
|
|
|
StockPoolHistory entity = BeanUtil.toBean(vo, StockPoolHistory.class);
|
|
|
entity.setRecordDate(parsedRecordDate);
|
|
|
entity.setAdminId(LoginHelper.getUserId());
|
|
|
- // 计算行情涨跌(最高涨幅)
|
|
|
- entity.setHighTrend(calculateHighTrend(vo.getStockCode(), parsedRecordDate, vo.getDayHighestPrice()));
|
|
|
- baseMapper.insert(entity);
|
|
|
+ toInsertList.add(entity);
|
|
|
successNum++;
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
@@ -394,6 +408,27 @@ public class StockPoolHistoryServiceImpl implements IStockPoolHistoryService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 批量计算最高涨幅
|
|
|
+ log.info("开始批量计算最高涨幅,待插入: {} 条,待更新: {} 条", toInsertList.size(), toUpdateList.size());
|
|
|
+ for (StockPoolHistory entity : toInsertList) {
|
|
|
+ entity.setHighTrend(calculateHighTrend(entity.getStockCode(), parsedRecordDate, entity.getDayClosePrice()));
|
|
|
+ }
|
|
|
+ for (StockPoolHistory entity : toUpdateList) {
|
|
|
+ entity.setHighTrend(calculateHighTrend(entity.getStockCode(), parsedRecordDate, entity.getDayClosePrice()));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量插入
|
|
|
+ if (!toInsertList.isEmpty()) {
|
|
|
+ baseMapper.insertBatch(toInsertList);
|
|
|
+ log.info("批量插入完成: {} 条", toInsertList.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量更新
|
|
|
+ if (!toUpdateList.isEmpty()) {
|
|
|
+ baseMapper.updateBatchById(toUpdateList);
|
|
|
+ log.info("批量更新完成: {} 条", toUpdateList.size());
|
|
|
+ }
|
|
|
+
|
|
|
if (failureNum > 0) {
|
|
|
String message = String.format("导入完成!成功 %d 条(其中更新 %d 条),失败 %d 条。详细错误信息请查看服务器日志。",
|
|
|
successNum, updateNum, failureNum);
|
|
|
@@ -500,30 +535,30 @@ public class StockPoolHistoryServiceImpl implements IStockPoolHistoryService {
|
|
|
|
|
|
/**
|
|
|
* 计算行情涨跌(最高涨幅)
|
|
|
- * 公式:(当日最高价 - 昨日收盘价) / 昨日收盘价 * 100
|
|
|
- * 如果找不到昨日数据则返回0
|
|
|
- *
|
|
|
+ * 公式:(十日之内最高价 - 当天收盘价) / 当天收盘价 * 100
|
|
|
+ * 如果找不到数据则返回0
|
|
|
+ *
|
|
|
* @param stockCode 股票代码
|
|
|
* @param recordDate 当前记录日期
|
|
|
- * @param dayHighestPrice 当日最高价
|
|
|
+ * @param dayClosePrice 当天收盘价
|
|
|
* @return 最高涨幅百分比,保留2位小数
|
|
|
*/
|
|
|
- private BigDecimal calculateHighTrend(String stockCode, LocalDate recordDate, BigDecimal dayHighestPrice) {
|
|
|
- if (dayHighestPrice == null) {
|
|
|
+ private BigDecimal calculateHighTrend(String stockCode, LocalDate recordDate, BigDecimal dayClosePrice) {
|
|
|
+ if (dayClosePrice == null || dayClosePrice.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
- // 查询昨日收盘价
|
|
|
- BigDecimal previousClosePrice = baseMapper.selectPreviousClosePrice(stockCode, recordDate);
|
|
|
-
|
|
|
- if (previousClosePrice == null || previousClosePrice.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
- // 找不到昨日数据或昨日收盘价为0,返回0
|
|
|
+
|
|
|
+ // 查询十日内最高价
|
|
|
+ BigDecimal tenDaysHighestPrice = baseMapper.selectTenDaysHighestPrice(stockCode, recordDate);
|
|
|
+
|
|
|
+ if (tenDaysHighestPrice == null) {
|
|
|
+ // 找不到十日内数据,返回0
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
-
|
|
|
- // 计算最高涨幅:(当日最高价 - 昨日收盘价) / 昨日收盘价 * 100
|
|
|
- return dayHighestPrice.subtract(previousClosePrice)
|
|
|
- .divide(previousClosePrice, 4, RoundingMode.HALF_UP)
|
|
|
+
|
|
|
+ // 计算最高涨幅:(十日之内最高价 - 当天收盘价) / 当天收盘价 * 100
|
|
|
+ return tenDaysHighestPrice.subtract(dayClosePrice)
|
|
|
+ .divide(dayClosePrice, 4, RoundingMode.HALF_UP)
|
|
|
.multiply(new BigDecimal("100"))
|
|
|
.setScale(2, RoundingMode.HALF_UP);
|
|
|
}
|