Compare commits
No commits in common. "master" and "dev-nzy" have entirely different histories.
@ -1,34 +1,10 @@
|
|||||||
package com.accounting.config;
|
package com.accounting.config;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.lang.NonNull;
|
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
import org.springframework.scheduling.annotation.SchedulingConfigurer;
|
|
||||||
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
public class SchedulerConfig implements SchedulingConfigurer {
|
public class SchedulerConfig {
|
||||||
|
|
||||||
/**
|
|
||||||
* 配置定时任务为单线程执行,避免并发问题
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void configureTasks(@NonNull ScheduledTaskRegistrar taskRegistrar) {
|
|
||||||
taskRegistrar.setScheduler(taskExecutor());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean(destroyMethod = "shutdown")
|
|
||||||
public Executor taskExecutor() {
|
|
||||||
return Executors.newSingleThreadScheduledExecutor(r -> {
|
|
||||||
Thread thread = new Thread(r, "gold-price-scheduler");
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,13 +20,4 @@ public interface GoldPriceMapper extends BaseMapper<GoldPrice> {
|
|||||||
|
|
||||||
@Select("SELECT MAX(price_date) FROM gold_price WHERE gold_id = #{goldId}")
|
@Select("SELECT MAX(price_date) FROM gold_price WHERE gold_id = #{goldId}")
|
||||||
LocalDate selectLatestDate(@Param("goldId") String goldId);
|
LocalDate selectLatestDate(@Param("goldId") String goldId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查指定时间点是否已存在数据(用于防重复插入)
|
|
||||||
* @param goldId 黄金品种ID
|
|
||||||
* @param updateTime 更新时间
|
|
||||||
* @return 存在的记录数
|
|
||||||
*/
|
|
||||||
@Select("SELECT COUNT(*) FROM gold_price WHERE gold_id = #{goldId} AND update_time = #{updateTime}")
|
|
||||||
int countByGoldIdAndUpdateTime(@Param("goldId") String goldId, @Param("updateTime") java.time.LocalDateTime updateTime);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import java.time.LocalDate;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -50,8 +51,6 @@ public class GoldPriceServiceImpl implements GoldPriceService {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void refreshCurrentPrice(String goldId) {
|
public void refreshCurrentPrice(String goldId) {
|
||||||
log.info("Starting refreshCurrentPrice for goldId={}", goldId);
|
|
||||||
|
|
||||||
K780Response response = k780ApiClient.fetchGoldPrice(goldId);
|
K780Response response = k780ApiClient.fetchGoldPrice(goldId);
|
||||||
|
|
||||||
if (!"1".equals(response.getSuccess()) || response.getResult() == null) {
|
if (!"1".equals(response.getSuccess()) || response.getResult() == null) {
|
||||||
@ -59,39 +58,14 @@ public class GoldPriceServiceImpl implements GoldPriceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
K780Result result = response.getResult();
|
K780Result result = response.getResult();
|
||||||
|
|
||||||
// 记录API返回的所有数据,用于调试
|
|
||||||
if (result.getDtList() != null) {
|
|
||||||
log.info("API returned {} gold price records", result.getDtList().size());
|
|
||||||
result.getDtList().forEach((id, data) -> {
|
|
||||||
log.info("Gold price data - goldId: {}, uptime: {}, lastPrice: {}",
|
|
||||||
id, data.getUptime(), data.getLastPrice());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
K780Result.GoldPriceData goldPriceData = extractGoldPriceData(result, goldId);
|
K780Result.GoldPriceData goldPriceData = extractGoldPriceData(result, goldId);
|
||||||
log.info("Extracted gold price data - goldId: {}, uptime: {}, lastPrice: {}",
|
|
||||||
goldPriceData.getGoldId(), goldPriceData.getUptime(), goldPriceData.getLastPrice());
|
|
||||||
|
|
||||||
GoldPrice goldPrice = convertToEntity(goldPriceData);
|
GoldPrice goldPrice = convertToEntity(goldPriceData);
|
||||||
log.info("Converted to entity - goldId: {}, updateTime: {}, priceDate: {}",
|
|
||||||
goldPrice.getGoldId(), goldPrice.getUpdateTime(), goldPrice.getPriceDate());
|
|
||||||
|
|
||||||
// 防重复插入:检查是否已存在相同时间点的数据
|
|
||||||
int existingCount = goldPriceMapper.countByGoldIdAndUpdateTime(goldId, goldPrice.getUpdateTime());
|
|
||||||
if (existingCount > 0) {
|
|
||||||
log.warn("Gold price data already exists for goldId={}, updateTime={}, skipping insert",
|
|
||||||
goldId, goldPrice.getUpdateTime());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 插入新记录 每15分钟查询一次结果并存储
|
// 插入新记录 每15分钟查询一次结果并存储
|
||||||
goldPrice.setCreateTime(LocalDateTime.now());
|
goldPrice.setCreateTime(LocalDateTime.now());
|
||||||
goldPriceMapper.insert(goldPrice);
|
goldPriceMapper.insert(goldPrice);
|
||||||
|
|
||||||
log.info("Successfully inserted gold price - id: {}, goldId: {}, priceDate: {}, updateTime: {}, createTime: {}",
|
log.info("Refreshed gold price for goldId={}, priceDate={}", goldPrice.getGoldId(), goldPrice.getPriceDate());
|
||||||
goldPrice.getId(), goldPrice.getGoldId(), goldPrice.getPriceDate(),
|
|
||||||
goldPrice.getUpdateTime(), goldPrice.getCreateTime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -163,22 +137,16 @@ public class GoldPriceServiceImpl implements GoldPriceService {
|
|||||||
// 解析更新时间
|
// 解析更新时间
|
||||||
if (data.getUptime() != null && !data.getUptime().isEmpty()) {
|
if (data.getUptime() != null && !data.getUptime().isEmpty()) {
|
||||||
try {
|
try {
|
||||||
LocalDateTime parsedTime = LocalDateTime.parse(data.getUptime(), DATE_TIME_FORMATTER);
|
entity.setUpdateTime(LocalDateTime.parse(data.getUptime(), DATE_TIME_FORMATTER));
|
||||||
entity.setUpdateTime(parsedTime);
|
entity.setPriceDate(entity.getUpdateTime().toLocalDate());
|
||||||
entity.setPriceDate(parsedTime.toLocalDate());
|
|
||||||
log.debug("Successfully parsed update time: {} -> {}", data.getUptime(), parsedTime);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Failed to parse update time: {}, error: {}, using current time instead",
|
log.warn("Failed to parse update time: {}", data.getUptime());
|
||||||
data.getUptime(), e.getMessage());
|
entity.setUpdateTime(LocalDateTime.now());
|
||||||
LocalDateTime now = LocalDateTime.now();
|
entity.setPriceDate(LocalDate.now());
|
||||||
entity.setUpdateTime(now);
|
|
||||||
entity.setPriceDate(now.toLocalDate());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("Uptime is null or empty, using current time");
|
entity.setUpdateTime(LocalDateTime.now());
|
||||||
LocalDateTime now = LocalDateTime.now();
|
entity.setPriceDate(LocalDate.now());
|
||||||
entity.setUpdateTime(now);
|
|
||||||
entity.setPriceDate(now.toLocalDate());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user