This commit is contained in:
HuangHai
2026-01-19 13:56:47 +08:00
parent 219cd5c220
commit b20b778f5d
10 changed files with 242 additions and 132 deletions

View File

@@ -4,11 +4,15 @@ import json
from typing import List, Optional, Dict, Any
from fastapi import APIRouter, HTTPException
from fastapi.responses import StreamingResponse
from fastapi.responses import StreamingResponse, FileResponse, JSONResponse
from DbKit.Db import Db
from Config.Config import DB_URL
from Util.LlmUtil import get_llm_response
from Tools.T6_Export import export_excel, DorisExcelExporter, extract_hourly_prices_from_schedule
import tempfile
import os
import zipfile
from Model.YltAnalyticsModel import (
StationBase,
CompetitorStation,
@@ -33,6 +37,89 @@ async def close_db():
await db.close()
@router.get("/api/operators/hourly-prices")
async def get_operators_hourly_prices():
operators = ["新电途", "特来电", "驿来特", "艾特吉易充"]
exporter = DorisExcelExporter(db_url=DB_URL)
await exporter.init()
try:
result = []
for op in operators:
rows = await exporter.fetch_current_station_rows(op)
if not rows:
result.append({"operator": op, "series": [None] * 24})
continue
sums = [0.0] * 24
counts = [0] * 24
for row in rows:
schedule_json = row.get("schedule_json")
series = extract_hourly_prices_from_schedule(schedule_json)
for i in range(24):
v = series[i]
if v is None:
continue
sums[i] += float(v)
counts[i] += 1
avg_series = []
for i in range(24):
c = counts[i]
if c > 0:
avg_series.append(sums[i] / c)
else:
avg_series.append(None)
result.append({"operator": op, "series": avg_series})
finally:
await exporter.close()
return {"operators": result}
@router.get("/api/export/prices-zip")
async def export_prices_zip():
operators = ["新电途", "特来电", "驿来特", "艾特吉易充"]
tmp_dir = tempfile.mkdtemp(prefix="price_export_")
excel_paths = []
for op in operators:
filename = f"{op}_{asyncio.get_event_loop().time():.0f}.xlsx"
output_path = os.path.join(tmp_dir, filename)
await export_excel(op, output_path)
excel_paths.append(output_path)
zip_path = os.path.join(tmp_dir, "prices_export.zip")
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf:
for p in excel_paths:
arcname = os.path.basename(p)
zf.write(p, arcname=arcname)
return FileResponse(
zip_path,
media_type="application/zip",
filename="多供应商电价导出.zip",
)
@router.get("/api/ai/pricing/strategy-summary")
async def ai_pricing_strategy_summary():
resp = await get_operators_hourly_prices()
data = resp.get("operators", [])
text_data = []
for item in data:
text_data.append({"operator": item.get("operator"), "series": item.get("series")})
text = (
"下面是四家供应商新电途、特来电、驿来特、艾特吉易充基于最新爬取数据计算出的平均24小时分时电价\n"
f"{text_data}\n"
"请根据这些数据,综合分析各司的定价策略差异,重点对比我司(驿来特)与其他供应商的分时电价水平,"
"指出我司在不同时段可能存在的潜在问题和风险例如明显偏贵、价格结构不合理等并给出2-3条可执行的优化建议。"
"回答控制在600字以内。"
)
chunks: List[str] = []
async for chunk in get_llm_response(
text,
stream=False,
system_prompt="你是熟悉中国充电桩行业的电价策略分析顾问。",
):
chunks.append(chunk)
summary_text = "".join(chunks)
return JSONResponse({"summary": summary_text})
@router.get("/api/ylt/stations", response_model=List[StationBase])
async def list_ylt_stations(q: Optional[str] = None):
base_sql = """