/* ziwei-power 前端逻辑 — 通过 API 与 Flask 后端交互 */ (function() { 'use strict'; /* ── Toast ──────────────────────────────── */ var toastTimer = null; function showToast(msg, type) { type = type || 'info'; var el = document.getElementById('toast'); el.textContent = msg; el.className = 'toast ' + type + ' show'; clearTimeout(toastTimer); toastTimer = setTimeout(function(){ el.classList.remove('show'); }, 2500); } /* ── API 封装 ───────────────────────────── */ function apiGetCheckin(date, cb) { fetch('/api/checkin?date=' + encodeURIComponent(date)) .then(function(r){ return r.json(); }) .then(function(res){ if (res.ok) cb(null, res.data); else cb(res.error); }) .catch(function(e){ cb(e.message); }); } function apiSaveCheckin(date, data, cb) { fetch('/api/checkin', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({date: date, data: data}) }) .then(function(r){ return r.json(); }) .then(function(res){ if (res.ok) cb(null); else cb(res.error); }) .catch(function(e){ cb(e.message); }); } function apiDeleteCheckin(date, cb) { fetch('/api/checkin/' + encodeURIComponent(date), {method: 'DELETE'}) .then(function(r){ return r.json(); }) .then(function(res){ if (res.ok) cb(null); else cb(res.error); }) .catch(function(e){ cb(e.message); }); } function apiGetHistory(cb) { fetch('/api/history') .then(function(r){ return r.json(); }) .then(function(res){ if (res.ok) cb(null, res.data); else cb(res.error); }) .catch(function(e){ cb(e.message); }); } /* ── Tab 切换 ───────────────────────────── */ window.switchTab = function(name, ev) { var tabs = document.querySelectorAll('.tab'); var contents = document.querySelectorAll('.tab-content'); for (var i=0; i' + '' + ''; container.appendChild(div); renumberMorning(); } function renumberMorning() { var rows = document.querySelectorAll('#morning-list .item-row'); for (var i=0; i' + '
' + '错误' + '' + '改进方案' + '' + '
' + ''; container.appendChild(div); renumberEvening(); } function renumberEvening() { var rows = document.querySelectorAll('#evening-list .item-row'); for (var i=0; i' + '' + ''; container.appendChild(div); } window.addMorning = function() { var count = document.querySelectorAll('#morning-list .item-row').length; if (count >= 3) { showToast('最多 3 条立志', 'error'); return; } addMorningRow(''); }; window.addEvening = function() { var count = document.querySelectorAll('#evening-list .item-row').length; if (count >= 5) { showToast('最多 5 条改过', 'error'); return; } addEveningRow('', ''); }; window.addStudy = function() { addStudyRow('', false); }; /* ── 加载 & 保存 ────────────────────────── */ window.loadCheckin = function() { var date = document.getElementById('check-date').value; if (!date) return; apiGetCheckin(date, function(err, row){ if (err) { fillForm(null); return; } fillForm(row ? row.data : null); }); }; window.saveCheckin = function() { var date = document.getElementById('check-date').value; if (!date) { showToast('请先选择日期!', 'error'); return; } var data = buildData(); apiSaveCheckin(date, data, function(err){ if (err) { showToast('保存失败: ' + err, 'error'); return; } showToast('✅ 打卡保存成功!', 'success'); }); }; /* ── 每周评分 ───────────────────────────── */ var weekOffset = 0; function getMonday(d) { var day = d.getDay(); var diff = d.getDate() - day + (day === 0 ? -6 : 1); var m = new Date(d); m.setDate(diff); return m; } function fmtDate(d) { var y = d.getFullYear(); var m = ('0'+(d.getMonth()+1)).slice(-2); var day = ('0'+d.getDate()).slice(-2); return y + '-' + m + '-' + day; } window.changeWeek = function(dir) { weekOffset += dir; loadWeekly(); }; function loadWeekly() { var today = new Date(); today.setDate(today.getDate() + weekOffset * 7); var monday = getMonday(today); var sunday = new Date(monday); sunday.setDate(monday.getDate() + 6); document.getElementById('week-label').textContent = fmtDate(monday) + ' ~ ' + fmtDate(sunday); apiGetHistory(function(err, rows){ if (err) { showToast('加载失败', 'error'); return; } var map = {}; for (var i=0; i= 2 ? '✅' : '⚠️'; var color = dayScore >= 2 ? '#10B981' : '#F59E0B'; details.push('
' + ds + ' — 得分:' + dayScore + '/3 ' + icon + '
'); } } var score = totalDays > 0 ? Math.round((totalScore / (totalDays * 3)) * 100) : 0; document.getElementById('weekly-score').textContent = score; var txt = ''; if (score >= 90) txt = '🌟 卓越!磁场非常强大'; else if (score >= 70) txt = '💪 良好,继续保持'; else if (score >= 50) txt = '⚠️ 一般,需要加强'; else txt = '❌ 较弱,急需调整'; document.getElementById('score-text').textContent = txt; document.getElementById('weekly-details').innerHTML = details.join(''); }); } /* ── 历史记录 ───────────────────────────── */ function loadHistory() { apiGetHistory(function(err, rows){ var el = document.getElementById('history-list'); if (err) { el.innerHTML = '

加载失败

'; return; } if (!rows || rows.length === 0) { el.innerHTML = '

暂无历史记录

'; return; } var html = ''; for (var i=0; i' + '
' + r.date + '
' + '
' + (preview.join(' · ') || '暂无内容') + '
' + '' + '' + ''; } el.innerHTML = html; }); } window.deleteHistory = function(date) { if (!confirm('确定删除 ' + date + ' 的打卡记录吗?此操作不可恢复!')) return; apiDeleteCheckin(date, function(err){ if (err) { showToast('删除失败: ' + err, 'error'); return; } showToast('已删除', 'info'); loadHistory(); }); }; /* ── HTML 转义 ──────────────────────────── */ function esc(s) { return String(s).replace(/&/g,'&').replace(/"/g,'"').replace(//g,'>'); } /* ── 初始化 ────────────────────────────── */ function init() { var today = new Date().toISOString().split('T')[0]; var cd = document.getElementById('check-date'); if (cd) { cd.value = today; } fillForm(null); loadCheckin(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();