新增积分系统:打卡/测试达标赚积分,纯累计可配置
- point_rule 规则表 + point_log 流水表(0008 迁移),唯一键防刷:同一事件首次达标才发放,重复静默返回 0 - 打卡分值随任务设置(模板/实例 points 字段,默认 10);测试类 6 种事件按规则表取值,各有默认分(单词 20/数学课 15/语法点 15/周测 50×2/考试通过 100) - 发放埋点 6 处:打卡、单词检测、数学课、语法知识点、英语/数学周测、考试通过;周测达标联动打卡实例不重复计分 - 孩子端:/kid 总积分徽章,新增 /points 积分页(总积分+流水),测验结果页即时显示「+N 积分」,周测结果页刷新后从流水取回已发积分 - 家长端:功能管理新增「积分管理」Section(规则分值配置+每孩子总积分/最近流水);任务管理内联编辑任务分值 - 修复:drizzle 将 mysql2 重复键错误包进 cause,沿错误链识别 ER_DUP_ENTRY Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
841f937b8e
commit
7a11a89031
@@ -17,11 +17,18 @@ import {
|
||||
import { SESSION_COOKIE, getSessionUser } from "@/lib/auth";
|
||||
import { addDays, dowOf, todayStr } from "@/lib/dates";
|
||||
import { passedCount, totalPoints } from "@/lib/grammar";
|
||||
import {
|
||||
POINT_EVENT_LABELS,
|
||||
listPointRules,
|
||||
pointHistory,
|
||||
totalPoints as childPointsTotal,
|
||||
} from "@/lib/points";
|
||||
import { viewUrl } from "@/lib/oss";
|
||||
import {
|
||||
ParentDashboard,
|
||||
type DevicesData,
|
||||
type OverviewData,
|
||||
type PointsData,
|
||||
type TemplatesData,
|
||||
type WeeklyRow,
|
||||
} from "./dashboard";
|
||||
@@ -136,6 +143,7 @@ export default async function ParentPage() {
|
||||
title: t.title,
|
||||
subject: t.subject,
|
||||
requiresPhoto: t.requiresPhoto,
|
||||
points: t.points,
|
||||
mode: t.mode,
|
||||
dateStart: t.dateStart,
|
||||
dateEnd: t.dateEnd,
|
||||
@@ -191,12 +199,33 @@ export default async function ParentPage() {
|
||||
passed: w.passed,
|
||||
}));
|
||||
|
||||
// ===== 积分管理(规则 + 每孩子总积分/最近流水) =====
|
||||
const rules = await listPointRules();
|
||||
const pointsData: PointsData = { rules, kids: [] };
|
||||
const eventLabel = (t: string) => (t === "checkin" ? "打卡" : POINT_EVENT_LABELS[t] ?? t);
|
||||
for (const kid of kids) {
|
||||
const [total, recent] = await Promise.all([childPointsTotal(kid.id), pointHistory(kid.id, 5)]);
|
||||
pointsData.kids.push({
|
||||
id: kid.id,
|
||||
name: kid.name,
|
||||
total,
|
||||
recent: recent.map((r) => ({
|
||||
id: r.id,
|
||||
label: eventLabel(r.eventType),
|
||||
remark: r.remark,
|
||||
points: r.points,
|
||||
date: r.createdAt.toLocaleDateString("zh-CN", SH),
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<ParentDashboard
|
||||
overview={overview}
|
||||
templates={templates}
|
||||
devices={devices}
|
||||
weekly={weekly}
|
||||
points={pointsData}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user