Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
350c9fb877 | ||
|
|
19ae81ae6e |
32
app.py
32
app.py
@@ -398,18 +398,46 @@ def api_calendar_sync():
|
|||||||
@app.route('/api/calendar-sync-all', methods=['GET'])
|
@app.route('/api/calendar-sync-all', methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
def api_calendar_sync_all():
|
def api_calendar_sync_all():
|
||||||
"""批量查询过去15天~未来15天的钉钉日程,按日期分组返回"""
|
"""批量查询过去15天~未来15天的钉钉日程,按日期分组返回,并自动填充到对应日期的 checkin"""
|
||||||
import json as _json
|
import json as _json
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
today = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
|
today = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
results = []
|
results = []
|
||||||
|
saved_days = 0
|
||||||
for delta in range(-15, 16):
|
for delta in range(-15, 16):
|
||||||
d = today + timedelta(days=delta)
|
d = today + timedelta(days=delta)
|
||||||
ds = d.strftime('%Y-%m-%d')
|
ds = d.strftime('%Y-%m-%d')
|
||||||
events = _fetch_dingtalk_events(ds)
|
events = _fetch_dingtalk_events(ds)
|
||||||
if events:
|
if events:
|
||||||
results.append({'date': ds, 'events': events})
|
results.append({'date': ds, 'events': events})
|
||||||
return jsonify({'ok': True, 'data': results})
|
# 自动去重填充到对应日期的 checkin
|
||||||
|
existing = get_checkin(ds)
|
||||||
|
data = existing['data'] if existing else {'morning': [], 'evening': [], 'study': []}
|
||||||
|
morning = data.get('morning', [])
|
||||||
|
existing_texts = set()
|
||||||
|
for mi in morning:
|
||||||
|
t = mi if isinstance(mi, str) else mi.get('text', '')
|
||||||
|
if t.strip():
|
||||||
|
existing_texts.add(t.strip())
|
||||||
|
added = False
|
||||||
|
for evt in events:
|
||||||
|
summary = (evt.get('summary') or '').strip()
|
||||||
|
if not summary:
|
||||||
|
continue
|
||||||
|
text = f"【{evt['time']}】{summary}" if evt.get('time') else summary
|
||||||
|
loc = evt.get('location', '')
|
||||||
|
if loc:
|
||||||
|
text += f" @{loc}"
|
||||||
|
text = text.strip()
|
||||||
|
if text not in existing_texts:
|
||||||
|
morning.append(text)
|
||||||
|
existing_texts.add(text)
|
||||||
|
added = True
|
||||||
|
if added:
|
||||||
|
data['morning'] = morning
|
||||||
|
save_checkin(ds, data)
|
||||||
|
saved_days += 1
|
||||||
|
return jsonify({'ok': True, 'data': results, 'saved_days': saved_days})
|
||||||
|
|
||||||
|
|
||||||
# ── 启动 ──────────────────────────────────────────────
|
# ── 启动 ──────────────────────────────────────────────
|
||||||
|
|||||||
@@ -410,7 +410,7 @@
|
|||||||
var totalDays = data.length;
|
var totalDays = data.length;
|
||||||
var totalEvents = 0;
|
var totalEvents = 0;
|
||||||
data.forEach(function(d){ totalEvents += d.events.length; });
|
data.forEach(function(d){ totalEvents += d.events.length; });
|
||||||
summary.innerHTML = '同步完成!共 <b>' + totalDays + '</b> 天有日程,合计 <b>' + totalEvents + '</b> 个会议';
|
summary.innerHTML = '同步完成!共 <b>' + totalDays + '</b> 天有日程,合计 <b>' + totalEvents + '</b> 个会议' + (res.saved_days ? ',已自动填充 <b>' + res.saved_days + '</b> 天' : '');
|
||||||
|
|
||||||
// 渲染结果列表
|
// 渲染结果列表
|
||||||
var html = '';
|
var html = '';
|
||||||
@@ -1044,7 +1044,7 @@
|
|||||||
(info.morning_items || []).forEach(function(mi){ items.push({pillar: p, text: mi.text, type: 'morning'}); });
|
(info.morning_items || []).forEach(function(mi){ items.push({pillar: p, text: mi.text, type: 'morning'}); });
|
||||||
}
|
}
|
||||||
if (blueprintFilter === 'all' || blueprintFilter === 'evening') {
|
if (blueprintFilter === 'all' || blueprintFilter === 'evening') {
|
||||||
(info.evening_items || []).forEach(function(ei){ items.push({pillar: p, text: ei.mistake || ei.improvement, type: 'evening'}); });
|
(info.evening_items || []).forEach(function(ei){ items.push({pillar: p, text: ei.mistake || ei.improvement, improvement: ei.improvement, type: 'evening'}); });
|
||||||
}
|
}
|
||||||
if (blueprintFilter === 'all' || blueprintFilter === 'study') {
|
if (blueprintFilter === 'all' || blueprintFilter === 'study') {
|
||||||
(info.study_items || []).forEach(function(si){ items.push({pillar: p, text: si.name, type: 'study', done: si.done, note: si.note}); });
|
(info.study_items || []).forEach(function(si){ items.push({pillar: p, text: si.name, type: 'study', done: si.done, note: si.note}); });
|
||||||
@@ -1064,13 +1064,15 @@
|
|||||||
var html = '';
|
var html = '';
|
||||||
items.forEach(function(item){
|
items.forEach(function(item){
|
||||||
var dot = '<span class="bp-pillar-dot" style="background:' + (pillarColors[item.pillar.name] || '#94A3B8') + '"></span>';
|
var dot = '<span class="bp-pillar-dot" style="background:' + (pillarColors[item.pillar.name] || '#94A3B8') + '"></span>';
|
||||||
var noteHtml = item.type === 'study' && item.note ? '<span class="bp-item-note">' + esc(item.note) + '</span>' : '';
|
var extra = '';
|
||||||
|
if (item.type === 'study' && item.note) extra = '<span class="bp-item-note">' + esc(item.note) + '</span>';
|
||||||
|
if (item.type === 'evening' && item.improvement) extra = '<span class="bp-item-note evening">→ ' + esc(item.improvement) + '</span>';
|
||||||
html += '<div class="bp-list-item">' +
|
html += '<div class="bp-list-item">' +
|
||||||
dot +
|
dot +
|
||||||
'<span class="bp-item-pillar">' + item.pillar.name + '</span>' +
|
'<span class="bp-item-pillar">' + item.pillar.name + '</span>' +
|
||||||
'<span class="bp-item-type ' + item.type + '">' + (typeLabels[item.type] || item.type) + '</span>' +
|
'<span class="bp-item-type ' + item.type + '">' + (typeLabels[item.type] || item.type) + '</span>' +
|
||||||
'<span class="bp-item-text">' + esc(item.text) + '</span>' +
|
'<span class="bp-item-text">' + esc(item.text) + '</span>' +
|
||||||
noteHtml +
|
extra +
|
||||||
'</div>';
|
'</div>';
|
||||||
});
|
});
|
||||||
list.innerHTML = html;
|
list.innerHTML = html;
|
||||||
|
|||||||
@@ -1507,6 +1507,7 @@ body {
|
|||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
.bp-item-note.evening { color: var(--danger); }
|
||||||
.bp-list-empty {
|
.bp-list-empty {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
|
|||||||
Reference in New Issue
Block a user