fix: 主页预嵌入统计数据,日历首次加载即可显示状态圆点
This commit is contained in:
101
app.py
101
app.py
@@ -68,11 +68,58 @@ def logout():
|
||||
|
||||
# ── 主页 ──────────────────────────────────────────────
|
||||
|
||||
def compute_stats():
|
||||
"""计算统计数据,供 API 和模板共用"""
|
||||
rows = get_all_checkins()
|
||||
total_days = len(rows)
|
||||
total_morning = 0
|
||||
total_evening = 0
|
||||
total_study = 0
|
||||
calendar = {}
|
||||
|
||||
for row in rows:
|
||||
d = row['date']
|
||||
data = row['data']
|
||||
morning = data.get('morning', [])
|
||||
evening = data.get('evening', [])
|
||||
study = data.get('study', [])
|
||||
|
||||
total_morning += sum(1 for x in morning if isinstance(x, str) and x.strip())
|
||||
total_evening += sum(1 for x in evening if (
|
||||
isinstance(x, str) and x.strip() or
|
||||
isinstance(x, dict) and (x.get('mistake', '') or '').strip()
|
||||
))
|
||||
total_study += sum(1 for x in study if x.get('done'))
|
||||
|
||||
day_score = 0
|
||||
has_morning = any(isinstance(x, str) and x.strip() for x in morning)
|
||||
has_evening = any(
|
||||
(isinstance(x, str) and x.strip()) or
|
||||
(isinstance(x, dict) and (x.get('mistake', '') or '').strip())
|
||||
for x in evening
|
||||
)
|
||||
has_study = any(x.get('done') for x in study)
|
||||
if has_morning: day_score += 1
|
||||
if has_evening: day_score += 1
|
||||
if has_study: day_score += 1
|
||||
|
||||
calendar[d] = 'pass' if day_score >= 2 else 'fail'
|
||||
|
||||
return dict(
|
||||
total_days=total_days, total_morning=total_morning,
|
||||
total_evening=total_evening, total_study=total_study,
|
||||
calendar=calendar
|
||||
)
|
||||
|
||||
|
||||
@app.route('/')
|
||||
@login_required
|
||||
def index():
|
||||
import json
|
||||
stats = compute_stats()
|
||||
return render_template('index.html',
|
||||
username=session.get('display_name', session.get('username', '')))
|
||||
username=session.get('display_name', session.get('username', '')),
|
||||
initial_stats=json.dumps(stats, ensure_ascii=False))
|
||||
|
||||
|
||||
# ── API ──────────────────────────────────────────────
|
||||
@@ -116,56 +163,8 @@ def api_history():
|
||||
@app.route('/api/stats', methods=['GET'])
|
||||
@login_required
|
||||
def api_stats():
|
||||
"""返回统计数据和日历状态映射"""
|
||||
rows = get_all_checkins()
|
||||
|
||||
total_days = len(rows)
|
||||
total_morning = 0
|
||||
total_evening = 0
|
||||
total_study = 0
|
||||
calendar = {}
|
||||
|
||||
for row in rows:
|
||||
d = row['date']
|
||||
data = row['data']
|
||||
morning = data.get('morning', [])
|
||||
evening = data.get('evening', [])
|
||||
study = data.get('study', [])
|
||||
|
||||
# 统计条目
|
||||
total_morning += sum(1 for x in morning if isinstance(x, str) and x.strip())
|
||||
total_evening += sum(1 for x in evening if (
|
||||
isinstance(x, str) and x.strip() or
|
||||
isinstance(x, dict) and (x.get('mistake', '') or '').strip()
|
||||
))
|
||||
total_study += sum(1 for x in study if x.get('done'))
|
||||
|
||||
# 评分
|
||||
day_score = 0
|
||||
has_morning = any(isinstance(x, str) and x.strip() for x in morning)
|
||||
has_evening = any(
|
||||
(isinstance(x, str) and x.strip()) or
|
||||
(isinstance(x, dict) and (x.get('mistake', '') or '').strip())
|
||||
for x in evening
|
||||
)
|
||||
has_study = any(x.get('done') for x in study)
|
||||
if has_morning:
|
||||
day_score += 1
|
||||
if has_evening:
|
||||
day_score += 1
|
||||
if has_study:
|
||||
day_score += 1
|
||||
|
||||
calendar[d] = 'pass' if day_score >= 2 else 'fail'
|
||||
|
||||
return jsonify({
|
||||
'ok': True,
|
||||
'total_days': total_days,
|
||||
'total_morning': total_morning,
|
||||
'total_evening': total_evening,
|
||||
'total_study': total_study,
|
||||
'calendar': calendar
|
||||
})
|
||||
stats = compute_stats()
|
||||
return jsonify({'ok': True, **stats})
|
||||
|
||||
|
||||
@app.route('/api/user', methods=['GET'])
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
document.getElementById('stat-study').textContent = data.total_study;
|
||||
calendarStatus = data.calendar || {};
|
||||
}
|
||||
renderCalendar(); // 无论成败都重新渲染
|
||||
renderCalendar();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -649,9 +649,19 @@
|
||||
initStudyPresets();
|
||||
bindAutoSave();
|
||||
lastSavedDate = todayStr;
|
||||
|
||||
// 从页面嵌入数据获取初始统计(0 延迟)
|
||||
if (window.__INITIAL_STATS__) {
|
||||
var s = window.__INITIAL_STATS__;
|
||||
document.getElementById('stat-days').textContent = s.total_days;
|
||||
document.getElementById('stat-morning').textContent = s.total_morning;
|
||||
document.getElementById('stat-study').textContent = s.total_study;
|
||||
calendarStatus = s.calendar || {};
|
||||
}
|
||||
|
||||
loadCheckin();
|
||||
loadStats();
|
||||
renderCalendar(); // 立即渲染日历,不等异步统计
|
||||
loadStats(); // 异步刷新最新数据
|
||||
renderCalendar(); // 同步渲染 — calendarStatus 已有值
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>紫微 · 磁场管理</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<script>window.__INITIAL_STATS__ = {{ initial_stats | safe }};</script>
|
||||
</head>
|
||||
<body>
|
||||
{% include "icons.html" %}
|
||||
|
||||
Reference in New Issue
Block a user