fix: analysis 500s, caching, alert page perf
P0: Fix KeyError in 3 analysis endpoints. geojson.py stores 1d risk as "risk_value" but analysis.py accessed "risk_1d" — always crashed. Backend: Add lru_cache to GeoJSON/CSV/Parquet loaders, date helpers, and district loader. Add try/except and FileNotFoundError guards. Frontend: Debounce riskRange, merge counts into useMemo, stabilize handleGridClick with ref, memoize nearest-grid scan, wrap AlertMap in React.memo, switch useLodGrid from fetch to cachedGet.
This commit is contained in:
@@ -83,7 +83,7 @@ async def get_trend(days: int = Query(default=7, ge=1, le=30)):
|
||||
if filepath.exists():
|
||||
grids = parse_geojson_file(filepath)
|
||||
if grids:
|
||||
avg_risk = sum(g["risk_1d"] for g in grids) / len(grids)
|
||||
avg_risk = sum(g["risk_value"] for g in grids) / len(grids)
|
||||
values.append(round(avg_risk, 4))
|
||||
else:
|
||||
values.append(0)
|
||||
@@ -125,8 +125,8 @@ async def get_districts():
|
||||
|
||||
if not districts:
|
||||
# Fallback: return city-wide aggregation
|
||||
avg_risk = sum(g["risk_1d"] for g in grids) / len(grids) if grids else 0
|
||||
high_risk_count = sum(1 for g in grids if g["risk_1d"] >= RISK_HIGH)
|
||||
avg_risk = sum(g["risk_value"] for g in grids) / len(grids) if grids else 0
|
||||
high_risk_count = sum(1 for g in grids if g["risk_value"] >= RISK_HIGH)
|
||||
|
||||
return DistrictsResponse(
|
||||
districts=[
|
||||
@@ -150,14 +150,14 @@ async def get_districts():
|
||||
for district in districts:
|
||||
if point_in_polygon(grid["latitude"], grid["longitude"], district["coordinates"]):
|
||||
district_data[district["name"]]["grids"].append(grid)
|
||||
if grid["risk_1d"] >= RISK_HIGH:
|
||||
if grid["risk_value"] >= RISK_HIGH:
|
||||
district_data[district["name"]]["high_risk"] += 1
|
||||
assigned = True
|
||||
break
|
||||
|
||||
if not assigned:
|
||||
unassigned["grids"].append(grid)
|
||||
if grid["risk_1d"] >= RISK_HIGH:
|
||||
if grid["risk_value"] >= RISK_HIGH:
|
||||
unassigned["high_risk"] += 1
|
||||
|
||||
# Build response
|
||||
@@ -169,7 +169,7 @@ async def get_districts():
|
||||
if not grids_in_district:
|
||||
continue
|
||||
|
||||
avg_risk = sum(g["risk_1d"] for g in grids_in_district) / len(grids_in_district)
|
||||
avg_risk = sum(g["risk_value"] for g in grids_in_district) / len(grids_in_district)
|
||||
high_risk_count = district_data[name]["high_risk"]
|
||||
|
||||
# Mock total cases based on risk and grid count
|
||||
@@ -187,7 +187,7 @@ async def get_districts():
|
||||
|
||||
# Add unassigned as "其他" if significant
|
||||
if unassigned["grids"]:
|
||||
avg_risk = sum(g["risk_1d"] for g in unassigned["grids"]) / len(unassigned["grids"])
|
||||
avg_risk = sum(g["risk_value"] for g in unassigned["grids"]) / len(unassigned["grids"])
|
||||
result.append(
|
||||
DistrictRisk(
|
||||
name="其他",
|
||||
@@ -224,8 +224,8 @@ async def get_correlations():
|
||||
|
||||
# Calculate mock correlations based on risk patterns
|
||||
# In production, this would use actual weather and health data
|
||||
avg_risk = sum(g["risk_1d"] for g in grids) / len(grids)
|
||||
risk_variance = sum((g["risk_1d"] - avg_risk) ** 2 for g in grids) / len(grids)
|
||||
avg_risk = sum(g["risk_value"] for g in grids) / len(grids)
|
||||
risk_variance = sum((g["risk_value"] - avg_risk) ** 2 for g in grids) / len(grids)
|
||||
|
||||
# Generate realistic correlation coefficients
|
||||
correlations = [
|
||||
|
||||
Reference in New Issue
Block a user