diff --git a/Controller/YltAnalyticsController.py b/Controller/YltAnalyticsController.py index 7b4c1f2..ab4e150 100644 --- a/Controller/YltAnalyticsController.py +++ b/Controller/YltAnalyticsController.py @@ -86,7 +86,7 @@ async def get_operators_price_trends(days: int = 7): model = YltAnalyticsModel() rows = await model.get_operators_price_trends(days) - # 数据结构: { operator: { date_str: [sums_of_24h, counts_of_24h] } } + # 数据结构: { operator: { datetime_str: [sums_of_price, counts_of_station] } } trend_data = {} for op in operators: trend_data[op] = {} @@ -95,47 +95,65 @@ async def get_operators_price_trends(days: int = 7): op = row.get("operator") if op not in trend_data: continue - d_str = str(row.get("date_str")) - schedule_json = row.get("schedule_json") - if d_str not in trend_data[op]: - trend_data[op][d_str] = {"sums": [0.0] * 24, "counts": [0] * 24} + # 将日期和 schedule_json 展开为 24 小时的数据点 + d_str = str(row.get("date_str")) + # 将 2026-01-21 转换为 01/21 + try: + date_parts = d_str.split('-') + display_date = date_parts[1] + '/' + date_parts[2] + except: + display_date = d_str + schedule_json = row.get("schedule_json") series = extract_hourly_prices_from_schedule(schedule_json) - for i in range(24): - v = series[i] + + for hour in range(24): + v = series[hour] if v is not None: - trend_data[op][d_str]["sums"][i] += float(v) - trend_data[op][d_str]["counts"][i] += 1 + # 使用原始日期 YYYY-MM-DD 用于排序,显示时由前端或后端格式化 + # 这里我们构造一个带补全的时间字符串,方便自然排序 + dt_key = f"{d_str} {hour:02d}:00" + if dt_key not in trend_data[op]: + trend_data[op][dt_key] = {"sum": 0.0, "count": 0, "display": f"{display_date} {hour:02d}:00"} + trend_data[op][dt_key]["sum"] += float(v) + trend_data[op][dt_key]["count"] += 1 # 转换为 ECharts 友好格式 - # 1. 获取所有日期并排序 - all_dates = sorted(list(set(str(row.get("date_str")) for row in rows))) + # 1. 获取所有时间点并排序 + all_time_keys = set() + for op in operators: + all_time_keys.update(trend_data[op].keys()) + sorted_keys = sorted(list(all_time_keys)) - # 2. 为每个运营商计算每天的平均价格(24小时的平均值) + # 2. 提取显示用的标签 + display_dates = [] + if sorted_keys: + # 从任意一个存在的运营商数据中获取 display 标签 + first_op = operators[0] + for key in sorted_keys: + # 找到包含该 key 的 display 标签 + label = key # fallback + for op in operators: + if key in trend_data[op]: + label = trend_data[op][key]["display"] + break + display_dates.append(label) + + # 3. 为每个运营商构建完整的时间序列数据 series_result = [] for op in operators: - op_trend = [] - for d in all_dates: - if d in trend_data[op]: - day_stats = trend_data[op][d] - day_avg_sum = 0.0 - day_hour_count = 0 - for i in range(24): - if day_stats["counts"][i] > 0: - day_avg_sum += (day_stats["sums"][i] / day_stats["counts"][i]) - day_hour_count += 1 - - if day_hour_count > 0: - op_trend.append(round(day_avg_sum / day_hour_count, 4)) - else: - op_trend.append(None) + op_data = [] + for key in sorted_keys: + if key in trend_data[op]: + stats = trend_data[op][key] + op_data.append(round(stats["sum"] / stats["count"], 4)) else: - op_trend.append(None) - series_result.append({"name": op, "data": op_trend}) + op_data.append(None) + series_result.append({"name": op, "data": op_data}) return { - "dates": all_dates, + "dates": display_dates, "series": series_result } diff --git a/Controller/__pycache__/YltAnalyticsController.cpython-310.pyc b/Controller/__pycache__/YltAnalyticsController.cpython-310.pyc index e94bf76..8d47fd4 100644 Binary files a/Controller/__pycache__/YltAnalyticsController.cpython-310.pyc and b/Controller/__pycache__/YltAnalyticsController.cpython-310.pyc differ diff --git a/Util/LlmUtil.py b/Util/LlmUtil.py index 46bbf8a..8ade26a 100644 --- a/Util/LlmUtil.py +++ b/Util/LlmUtil.py @@ -1,4 +1,5 @@ import sys +import asyncio from openai import AsyncOpenAI diff --git a/Util/__pycache__/LlmUtil.cpython-310.pyc b/Util/__pycache__/LlmUtil.cpython-310.pyc index 36a4f51..1405682 100644 Binary files a/Util/__pycache__/LlmUtil.cpython-310.pyc and b/Util/__pycache__/LlmUtil.cpython-310.pyc differ diff --git a/static/css/dashboard.css b/static/css/dashboard.css index 304addb..d34460d 100644 --- a/static/css/dashboard.css +++ b/static/css/dashboard.css @@ -10,7 +10,7 @@ --success-color: #10b981; --table-header-bg: #0f172a; --table-row-hover: #334155; - --scrollbar-thumb: #475569; + --scrollbar-thumb: #334155; --scrollbar-track: #0f172a; } @@ -230,7 +230,7 @@ body { .ai-box { flex: 1; - background-color: rgba(15, 23, 42, 0.3); + background-color: #243347; border-radius: 8px; border: 1px solid var(--card-border); padding: 16px; @@ -240,6 +240,7 @@ body { color: #cbd5e1; scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent; + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2); } /* Markdown & LaTeX Rendering */ @@ -249,6 +250,7 @@ body { line-height: 1.8; word-wrap: break-word; color: #cbd5e1; + background-color: transparent !important; } .markdown-body h1, .markdown-body h2, .markdown-body h3, @@ -257,37 +259,40 @@ body { margin-bottom: 16px; font-weight: 600; line-height: 1.25; - color: var(--text-primary); + color: var(--text-primary) !important; + background-color: transparent !important; } .markdown-body h1 { font-size: 1.8em; border-bottom: 1px solid var(--card-border); padding-bottom: 0.3em; } .markdown-body h2 { font-size: 1.4em; border-bottom: 1px solid var(--card-border); padding-bottom: 0.3em; } .markdown-body h3 { font-size: 1.2em; } -.markdown-body p { margin-top: 0; margin-bottom: 16px; } +.markdown-body p { margin-top: 0; margin-bottom: 16px; background-color: transparent !important; } .markdown-body ul, .markdown-body ol { padding-left: 2em; margin-top: 0; margin-bottom: 16px; + background-color: transparent !important; } -.markdown-body li { margin: 0.25em 0; } +.markdown-body li { margin: 0.25em 0; background-color: transparent !important; } -.markdown-body strong { font-weight: 600; color: #fff; } +.markdown-body strong { font-weight: 600; color: #fff !important; background-color: transparent !important; } .markdown-body blockquote { padding: 0 1em; color: #94a3b8; border-left: 0.25em solid #3b82f6; margin: 0 0 16px 0; + background-color: transparent !important; } .markdown-body code { padding: 0.2em 0.4em; margin: 0; font-size: 85%; - background-color: rgba(148, 163, 184, 0.1); + background-color: rgba(59, 130, 246, 0.1) !important; border-radius: 6px; font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; } @@ -303,11 +308,7 @@ body { border-collapse: collapse; margin-top: 0; margin-bottom: 16px; -} - -.markdown-body table th { - font-weight: 600; - background-color: rgba(15, 23, 42, 0.8); + background-color: transparent !important; } .markdown-body table th, @@ -316,13 +317,18 @@ body { border: 1px solid var(--card-border); } +.markdown-body table th { + font-weight: 600; + background-color: #334155 !important; +} + .markdown-body table tr { - background-color: transparent; + background-color: transparent !important; border-top: 1px solid var(--card-border); } .markdown-body table tr:nth-child(2n) { - background-color: rgba(30, 41, 59, 0.3); + background-color: rgba(51, 65, 85, 0.3) !important; } /* LaTeX Styles */ diff --git a/static/dashboard.html b/static/dashboard.html index 1d118fa..aec05a7 100644 --- a/static/dashboard.html +++ b/static/dashboard.html @@ -5,7 +5,6 @@ 分时电价分析 - 驿来特AI智能大脑 -
diff --git a/static/douyin.html b/static/douyin.html index 22c7833..f57b4f7 100644 --- a/static/douyin.html +++ b/static/douyin.html @@ -45,7 +45,7 @@

⚡ AI正在阅读您的知识库并提炼精华,请稍候...

-
+
|