diff --git a/app.py b/app.py index 98d6769..f54b1dc 100644 --- a/app.py +++ b/app.py @@ -225,6 +225,27 @@ def api_reorder_wishes(): return jsonify({'ok': True}) +# ── 日历同步 API ──────────────────────────── + +CALENDAR_CACHE = os.path.join(os.path.expanduser('~'), '.workbuddy', 'data', 'ziwei-power', 'calendar_cache.json') + +@app.route('/api/calendar-sync', methods=['GET']) +@login_required +def api_calendar_sync(): + """获取指定日期的钉钉日历会议""" + import json as _json + date = request.args.get('date', '') + if not date: + return jsonify({'ok': False, 'error': '缺少 date 参数'}), 400 + try: + with open(CALENDAR_CACHE, 'r') as f: + events = _json.load(f) + except (FileNotFoundError, _json.JSONDecodeError): + return jsonify({'ok': True, 'data': []}) + today_events = [e for e in events if e.get('date') == date] + return jsonify({'ok': True, 'data': today_events}) + + # ── 启动 ────────────────────────────────────────────── if __name__ == '__main__': diff --git a/static/app.js b/static/app.js index b5f2cbc..1d953a1 100644 --- a/static/app.js +++ b/static/app.js @@ -362,6 +362,45 @@ } } + /* ── 日历同步 ── */ + + window.syncCalendar = function() { + var date = document.getElementById('check-date').value; + var btn = document.querySelector('.btn-cal-sync'); + if (btn) { btn.style.opacity = '0.5'; btn.disabled = true; } + fetch('/api/calendar-sync?date=' + encodeURIComponent(date)) + .then(function(r){ return r.json(); }) + .then(function(res){ + if (btn) { btn.style.opacity = '1'; btn.disabled = false; } + if (!res.ok) { showToast(res.error || '同步失败', 'error'); return; } + var events = res.data || []; + if (events.length === 0) { showToast('今日无日程', 'info'); return; } + var added = 0; + events.forEach(function(e) { + var text = '【' + e.time + '】' + e.summary; + if (e.location) text += ' @' + e.location; + var existing = document.querySelectorAll('#morning-list input[type="text"]'); + var already = false; + existing.forEach(function(inp){ if (inp.value.indexOf(e.summary) >= 0) already = true; }); + if (already) return; + var count = document.querySelectorAll('#morning-list .item-row').length; + if (count >= 3) return; + addMorningRow(text); + added++; + }); + if (added > 0) { + showToast('已同步 ' + added + ' 条日程', 'info'); + triggerAutoSave(); + } else { + showToast('日程已存在或已满', 'info'); + } + }) + .catch(function(){ + if (btn) { btn.style.opacity = '1'; btn.disabled = false; } + showToast('同步失败', 'error'); + }); + }; + window.addMorning = function() { var count = document.querySelectorAll('#morning-list .item-row').length; if (count >= 3) { showToast('最多 3 条立志', 'error'); return; } diff --git a/static/style.css b/static/style.css index 9553c05..d6a4849 100644 --- a/static/style.css +++ b/static/style.css @@ -535,6 +535,26 @@ body { color: var(--primary); } +/* 日历同步按钮 */ +.btn-cal-sync { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border: none; + background: transparent; + color: var(--text-muted); + border-radius: 6px; + cursor: pointer; + transition: all 0.2s; + flex-shrink: 0; +} +.btn-cal-sync:hover { + background: var(--success-light); + color: var(--success); +} + /* 编辑模式下才显示的元素 */ .edit-only { display: none; } .card.editing .edit-only { display: flex; } diff --git a/templates/index.html b/templates/index.html index e8864e3..900ca4c 100644 --- a/templates/index.html +++ b/templates/index.html @@ -113,6 +113,9 @@