修复图表时间轴不全与城市决策卡模型补齐卡顿

- 后端 Open-Meteo 请求加 past_days=1,小时数据从 00:00 开始
- 前端图表层填充完整 00:00-23:00 时间轴,缺失时段置空
- 城市深度分析门槛从 >1 降为 >=1,单模型城市不再被拦
- hydration 队列加最大重试 3 次,防止永久卡在等待模型补齐
- 移除右侧面板历史对账按钮
This commit is contained in:
2569718930@qq.com
2026-05-16 20:14:05 +08:00
parent b27bedbca3
commit 2e02133696
5 changed files with 37 additions and 38 deletions
@@ -47,8 +47,8 @@ export function isFullEnoughForDeepAnalysis(detail?: CityDetail | null) {
return false;
}
return (
countDetailModels(detail, detail.local_date) > 1 &&
countDetailForecastDays(detail) > 1
countDetailModels(detail, detail.local_date) >= 1 &&
countDetailForecastDays(detail) >= 1
);
}
@@ -30,6 +30,7 @@ export function useAiPinnedCityWorkspace({
const aiFullHydrationRef = useRef<Set<string>>(new Set());
const aiHydrationQueueRef = useRef<string[]>([]);
const aiHydrationRunningRef = useRef(false);
const aiHydrationRetriesRef = useRef<Map<string, number>>(new Map());
const runAiHydrationQueue = useCallback(async () => {
if (aiHydrationRunningRef.current) return;
@@ -47,10 +48,22 @@ export function useAiPinnedCityWorkspace({
"full",
);
if (!isFullEnoughForDeepAnalysis(detail)) {
aiFullHydrationRef.current.delete(key);
const retries = aiHydrationRetriesRef.current.get(key) || 0;
if (retries >= 3) {
aiFullHydrationRef.current.delete(key);
aiHydrationRetriesRef.current.delete(key);
} else {
aiHydrationRetriesRef.current.set(key, retries + 1);
}
}
} catch {
aiFullHydrationRef.current.delete(key);
const retries = aiHydrationRetriesRef.current.get(key) || 0;
if (retries >= 3) {
aiFullHydrationRef.current.delete(key);
aiHydrationRetriesRef.current.delete(key);
} else {
aiHydrationRetriesRef.current.set(key, retries + 1);
}
}
}
} finally {
@@ -132,6 +145,8 @@ export function useAiPinnedCityWorkspace({
aiPinnedCities.forEach((item) => {
const key = normalizeCityKey(item.cityName);
if (!key || aiFullHydrationRef.current.has(key)) return;
const retries = aiHydrationRetriesRef.current.get(key) || 0;
if (retries >= 3) return;
const detail = findDetailForCity(store.cityDetailsByName, item.cityName);
const needsFullHydration = !isFullEnoughForDeepAnalysis(detail);
if (!needsFullHydration) return;