v1.0.0 — 评分规则大改 & UI优化

- 责善改过:纵向排列、输入框样式对齐立志、扁平化去内层卡片嵌套
- 自动保存:blur 触发替代 input 防抖,静默保存
- 日评分:3项全有 → 60分 + 多出条数×5;缺失 → 条数×5
- 周评分:日峰值累加制,取消百分比上限
- 修复 preset-note 溢出、清理冗余代码
This commit is contained in:
mac
2026-06-02 23:31:46 +08:00
parent 2545f39af9
commit 2d6eb4dc35
3 changed files with 77 additions and 75 deletions

View File

@@ -9,7 +9,6 @@
var calYear, calMonth; // 日历显示的月份
var activePanel = 'daily'; // 当前面板
var weekOffset = 0; // 每周评分偏移
var autoSaveTimer = null; // 自动保存防抖
var lastSavedData = null; // 上次保存快照
var lastSavedDate = null; // 上次保存日期
var selectedDate = null; // 日历中选中日期
@@ -399,7 +398,6 @@
/* ================================================================
Load & Auto Save Checkin
================================================================ */
var lastSavedData = null; // 上次保存的数据快照,避免重复保存
window.loadCheckin = function() {
var date = document.getElementById('check-date').value;
@@ -426,22 +424,18 @@
});
};
/** 自动保存(带防抖) */
/** 自动保存 — 失去焦点/勾选/删除时触发 */
function triggerAutoSave() {
clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(function() {
var date = document.getElementById('check-date').value;
if (!date) return;
var data = buildData();
var dataStr = JSON.stringify(data);
if (dataStr === lastSavedData) return; // 无变化,跳过
apiSaveCheckin(date, data, function(err){
if (err) { showToast('自动保存失败', 'error'); return; }
lastSavedData = dataStr;
showToast('已自动保存', 'info');
loadStats();
});
}, 1500);
var date = document.getElementById('check-date').value;
if (!date) return;
var data = buildData();
var dataStr = JSON.stringify(data);
if (dataStr === lastSavedData) return;
apiSaveCheckin(date, data, function(err){
if (err) { showToast('保存失败', 'error'); return; }
lastSavedData = dataStr;
loadStats();
});
}
/** 为每日打卡面板绑定自动保存事件 */
@@ -449,12 +443,12 @@
var panel = document.getElementById('panel-daily');
if (!panel) return;
// 输入框 & 文本域:input 事件
panel.addEventListener('input', function(e) {
// 输入框 & 文本域:失去焦点时保存
panel.addEventListener('blur', function(e) {
if (e.target.matches('input[type="text"], textarea, input[type="date"]')) {
triggerAutoSave();
}
});
}, true);
// 复选框change 事件
panel.addEventListener('change', function(e) {
@@ -470,13 +464,6 @@
setTimeout(triggerAutoSave, 100); // 等 DOM 更新后
}
});
// 预设项目勾选切换
panel.addEventListener('change', function(e) {
if (e.target.matches('.preset-check input[type="checkbox"]')) {
triggerAutoSave();
}
});
}
/* ================================================================
@@ -522,21 +509,27 @@
if (dd) {
totalDays++;
var dayScore = 0;
var morning = dd.morning || [];
var hasMorning = morning.some(function(x){ return x && typeof x === 'string' && x.trim(); });
var evening = dd.evening || [];
var hasEvening = evening.some(function(x){
var study = dd.study || [];
var morningCount = morning.filter(function(x){ return x && typeof x === 'string' && x.trim(); }).length;
var eveningCount = evening.filter(function(x){
var mst = typeof x === 'string' ? x : (x.mistake || '');
return mst && typeof mst === 'string' && mst.trim();
});
var study = dd.study || [];
var hasStudy = study.some(function(x){ return x.done; });
if (hasMorning) dayScore++;
if (hasEvening) dayScore++;
if (hasStudy) dayScore++;
}).length;
var studyCount = study.filter(function(x){ return x.done; }).length;
var allThree = morningCount > 0 && eveningCount > 0 && studyCount > 0;
var dayScore, status;
if (allThree) {
dayScore = 60 + (morningCount - 1 + eveningCount - 1 + studyCount - 1) * 5;
status = 'pass';
} else {
dayScore = (morningCount + eveningCount + studyCount) * 5;
status = 'fail';
}
totalScore += dayScore;
var status = dayScore >= 2 ? 'pass' : 'fail';
dayCells.push({
ds: ds, dayScore: dayScore, status: status,
@@ -550,21 +543,21 @@
}
}
var score = totalDays > 0 ? Math.round((totalScore / (totalDays * 3)) * 100) : 0;
var score = totalScore;
document.getElementById('weekly-score').textContent = score;
var ring = document.querySelector('.score-ring');
if (ring) {
var R = 50, C = 2 * Math.PI * R;
ring.setAttribute('stroke-dasharray', C);
ring.setAttribute('stroke-dashoffset', C - (C * score / 100));
ring.setAttribute('stroke-dashoffset', C - (C * totalDays / 7));
}
var txt = '';
if (score >= 90) txt = '卓越!磁场非常强大';
else if (score >= 70) txt = '良好,继续保持';
else if (score >= 50) txt = '一般,需要加强';
else txt = '较弱,急需调整';
if (totalDays >= 7) txt = '全勤!本周每天都有记录';
else if (totalDays >= 5) txt = '良好,保持了大部分记录';
else if (totalDays >= 3) txt = '一般,需要更规律打卡';
else txt = '本周记录偏少,加油!';
document.getElementById('score-text').textContent = txt;
var completedDays = dayCells.filter(function(c){ return c.status === 'pass'; }).length;
@@ -577,11 +570,11 @@
var cell = dayCells[g];
var dateParts = cell.ds.split('-');
var shortDate = dateParts[1] + '/' + dateParts[2];
var badgeText = cell.status === 'pass' ? '完成' : (cell.status === 'fail' ? '未达标' : '未打卡');
var badgeText = cell.status === 'pass' ? '达标' : (cell.status === 'fail' ? '未达标' : '未打卡');
gridHtml += '<div class="day-cell ' + cell.status + '">' +
'<div class="day-label">' + cell.weekday + '</div>' +
'<div class="day-date">' + shortDate + '</div>' +
'<div class="day-score">' + cell.dayScore + '<span style="font-size:11px;font-weight:400">/3</span></div>' +
'<div class="day-score">' + cell.dayScore + '<span style="font-size:11px;font-weight:400"></span></div>' +
'<div class="day-badge">' + badgeText + '</div>' +
'</div>';
}