日结与时点锚点系统 v1 — 需求卡
目的:把"时间一直在转"变成"我在错过什么"。 范围:4 个优先级 P0 → P3,串成一套从「看见后果」到「规划行为」的递进机制。 状态:草案,等 P1 拍板开工。 关联:
AGENTS.md§1 三层架构 ·src/utils/gameTime.ts·src/components/AppHeaderBar.tsx·docs/design/active/经济循环体系-v1.md
0. 背景与现状
当前时间系统
- 1 天 = 24 slot,1 slot = 6 秒真实时间 → 1 天约 2.5 分钟
- 分段:清晨(6-12) / 白天(12-18) / 傍晚(18-24) / 深夜(0-6)
- 业务阶段:
open(营业)/closing(打烊)/closed(关门) - 顶部
AppHeaderBar时辰区只渲染 3 个文字:gameTimeLabel/timeOfDayLabel/businessPhase,无进度、无锚点、无倒计时 getTimePhasePolicy只决定"哪些事能做",没有"做了奖励/不做惩罚"的反馈链
玩家痛点
- 时间在走 → 玩家只感受到"流水",感受不到"错失"
- 今日没做完的事 → 明日没有清晰的累计反馈
- 早做 / 晚做 → 玩家看不出差别
- 招人 / 备料 / 补货的"决策" → 没有"应到时间",没有"应到但没到"的负反馈
核心目标
让玩家在每天结束(深夜 0:00)时,看到一张"今天我亏了多少"的结算卡——这是"压迫感"转化为"决策动力"的支点。
1. 领域架构(按 AGENTS.md §1 三层分离)
新建领域 daily/,遵循项目「数据 / 逻辑 / UI」三分。
| 层 | 目录 | 内容 |
| :-: | :--- | :--- |
| 数据层 | src/data/daily/ | 类型 + 常量 + 静态配置(漏接定价、保护期天数、锚点定义、默认待办模板) |
| 逻辑层 | src/utils/daily/ | 纯函数(结算构建、锚点推算、待办评估、应到检查) |
| UI 层 | src/components/daily/ | 4 个组件(日结卡、时间条、待办面板、应到红点) |
import 方向(强制)
UI 层 ──> 逻辑层 ──> 数据层
↑ ↑
└───────────┘
(UI 也可直接读数据常量)
禁止:
- ❌ 数据层 import utils/ 或 components/
- ❌ 逻辑层 import components/
- ❌ 跨领域 import(
daily/内部不直接读auction/的内部数据,经 utils 走)
共享类型
DailySettlement/TimeAnchor/DailyChecklistItem/AnchorReadiness全部定义在src/data/daily/types.ts- 命名约定沿用 AGENTS.md §4:PascalCase 类型、UPPER_SNAKE_CASE 常量、camelCase 函数、
Logic后缀
2. P0 · 日结日报卡(最关键,零风险)
用户故事
作为掌柜,每天深夜 0:00 我想看到一张结算卡,知道「今天接待了多少 / 漏接了多少 / 亏了多少」,并对比昨日。
触发
- 每进入
slot === 0(即新一天 0:00)时自动触发一次 - 一次弹窗只能被关闭,不重复触发
- 历史日结存档到
dailyHistory: DailySettlement[],供主厅"日结回顾"面板查询
数据流
触发 → collectDayMetrics(state) → buildDailySettlement(metrics, prevDay)
→ render <DailySettlementCard settlement={...} onClose={...} />
→ onClose: push to dailyHistory, 标记已读
字段定义(src/data/daily/types.ts)
export interface DailySettlement {
day: number; // 第几天
dateLabel: string; // '第 3 日 · 七月初九'
businessDate: BusinessDate; // 复用现有 BusinessDate 类型
// —— 基础数据 ——
servedGuests: number; // 接待人数
servedGuestsDelta: number; // 对比昨日 (+/-)
income: number; // 营业收入
incomeDelta: number; // 对比昨日
// —— 漏接(关键)——
missedGuests: number; // 漏接人数
missedLoss: number; // 漏接潜在损失(按客单价估算)
missedReasonTags: string[]; // 漏接原因 ['座位满', '厨房爆', '无人接待']
// —— 资源警示 ——
inventoryAlerts: InventoryAlert[]; // 库存告急清单
staffFatigue: { name: string; delta: number }[]; // 员工疲劳累积
// —— 明日预告 ——
tomorrowPreview: { customerMult: number; weatherLabel: string };
// —— 对比基准 ——
comparedTo: 'prevDay' | 'weekAgo'; // 固定为 prevDay
// —— 元数据 ——
isProtectedDay: boolean; // 是否在保护期内(前 3 天)
createdAt: number; // 时间戳
}
export interface InventoryAlert {
itemName: string;
remaining: number;
daysUntilEmpty: number; // 按今日消耗速率估算
severity: 'warn' | 'danger';
}
关键规则
| 规则 | 说明 |
| :- | :- |
| 「漏接」定义 | 客流高峰(12:00-18:00)时段,因 座位满 / 厨房爆 / 无人接待 而未能入座的客人总数。需要客流系统已经能输出"应到 vs 实际",开工前请先确认此数据源;如无则用「实际入座 < 应到」的差值 |
| 「漏接损失」定价 | = 漏接人数 × 该时段的平均客单价。客单价取当日「已接待客人平均消费」× 0.85(折扣因子,模拟"本可赚到但没赚到") |
| 保护期 | 前 3 天(day 1-3)isProtectedDay = true,漏接损失显示但不入账。从 day 4 开始正式扣银(但仍仅展示,不直接扣到 coins,只做软提醒) |
| 库存告警 | 当日 24:00 库存 ≤ 2 天消耗量 → 告警;≤ 0.5 天 → 红色危险 |
| 员工疲劳 | 当日总疲劳累加 +N%,若 > 80% 提示"明日产能 -X%" |
| 明日预告 | 复用现有 TodayCalendarSnapshot(节气/天气/客流倍率) |
三层落点
| 层 | 文件 | 内容 |
| :-: | :--- | :--- |
| 数据 | src/data/daily/settlement.ts | DailySettlement / InventoryAlert 类型 + MISSED_LOSS_DISCOUNT_FACTOR / PROTECTION_DAYS 常量 |
| 数据 | src/data/daily/missedReasons.ts | MISSED_REASON_LABELS 映射(座位满/厨房爆/无人接待/打烊中/天气) |
| 逻辑 | src/utils/daily/settlementLogic.ts | buildDailySettlement(state, prevDay): DailySettlement 纯函数 |
| 逻辑 | src/utils/daily/missedGuestsLogic.ts | aggregateMissedGuests(customerFlowLog): { count, loss, reasons } |
| UI | src/components/daily/DailySettlementCard.tsx | 模态弹窗组件 |
| UI | src/components/daily/MissedLossLine.tsx | 漏接行(带 ⚠ 警示)独立组件便于复用 |
UI 草图
┌──────────────── 第 3 日 · 日结 ────────────────┐
│ 掌柜,今天辛苦了,请过目。 │
│ │
│ 📈 接待客人 28 位 ↑ 5 │
│ 💰 营业收入 1,240 银 ↑ 180 │
│ │
│ ⚠ 漏接 7 位 → 损失 约 105 银 │ ← 关键
│ 原因:座位满 4 · 厨房爆 2 · 无人接待 1 │
│ │
│ 📦 库存告急 │
│ · 米 剩 3 桶(约 1.5 天用完)🔴 │
│ · 油 剩 5 壶(约 2 天用完)🟡 │
│ │
│ 😓 员工疲劳 │
│ · 大嘴 +18(明日产能 -8%) │
│ │
│ 🌤 明日预告 │
│ 客流 +20% · 多云转晴 │
│ │
│ [ 收下,继续经营 ] │
└────────────────────────────────────────────────┘
验收清单
- [ ] 每天 0:00 slot 自动触发日结弹窗
- [ ] 弹窗显示 7 个字段组(接待/营收/漏接/库存/疲劳/预告/对比)
- [ ] "漏接"字段必显示「X 位 · 损失 Y 银」+ 原因 tag
- [ ] 对比昨日用 ↑/↓ 标记,持平用 —
- [ ] 关闭后写入
dailyHistory,不重复触发 - [ ] day 1-3 保护期:
isProtectedDay = true,漏接损失灰色"演示中" - [ ] day 4+:漏接损失正常显示(软提醒,不实际扣银)
- [ ] 现有 66 个 tsc 错误不新增
- [ ]
npm run lint通过 - [ ]
npm run build通过
估时
半天(半天数据/逻辑 + 半天 UI 组件 + 半天联调)。等数据源(客流日志)确认后开始。
依赖
- 🔴 开工前必须确认:客流系统是否能输出"应到 vs 实际入座"的对比数据?如无,P0 需要降级为"只显示接待数 + 营收"两个字段,"漏接"延后到 P1 + P3 一起做
- 🟡 现有
TodayCalendarSnapshot复用即可,无需新增
3. P1 · 顶部时间条改造(进度条 + 锚点 + 倒计时)
用户故事
作为掌柜,顶部时间条不再是冷冰冰的文字,而是一根"我正走在一根有刻度的尺子上"的进度条,让我随时知道「下一件该发生的事还有多久」。
触发
- 持续渲染(不是事件),基于
gameTime.slot实时计算
数据流
AppHeaderBar 渲染 → 内部嵌入 <TimeProgressBar gameTime={gameTime} />
→ getNextAnchor(slot) / getTimeToNextAnchor(slot)
→ 渲染进度条 + 4 个锚点 + 倒计时
字段定义
// src/data/daily/timeAnchors.ts
export type AnchorId = 'dawn-prep' | 'noon-peak' | 'dusk-closing' | 'night-settle';
export interface TimeAnchor {
id: AnchorId;
slot: number; // 锚点 slot(6 / 12 / 18 / 0)
label: string; // '厨子备料' / '客流高峰' / '打烊收尾' / '深夜结算'
iconKey: string; // 复用 TONGFU_ICON_ASSETS key
toneClass: string; // Tailwind class
hint: string; // 锚点说明 '客人最多的时候'
}
export const TIME_ANCHORS: TimeAnchor[] = [
{ id: 'dawn-prep', slot: 6, label: '厨子备料', iconKey: 'kitchenPot', toneClass: '...', hint: '厨房开始一天的工作' },
{ id: 'noon-peak', slot: 12, label: '客流高峰', iconKey: 'guestGroup', toneClass: '...', hint: '客人最多的时候' },
{ id: 'dusk-closing', slot: 18, label: '打烊收尾', iconKey: 'broom', toneClass: '...', hint: '厨房清理,盘点' },
{ id: 'night-settle', slot: 0, label: '深夜结算', iconKey: 'abacus', toneClass: '...', hint: '日结日报' },
];
关键规则
| 规则 | 说明 |
| :- | :- |
| 当前锚点 | currentAnchor = TIME_ANCHORS.find(a => a.slot === currentTimeSlot);或「两个锚点之间」取上一个 |
| 下一锚点倒计时 | getTimeToNextAnchor(slot) = (next.slot - slot + 24) % 24 |
| 跨越 0 点 | slot 22 时,下一锚点是 24+0=0,逻辑用 (next.slot - slot + 24) % 24 自然处理 |
| 已完成锚点 | 当前 slot > 锚点 slot(且未跨日)→ 显示 ✓ 状态 |
| 下一锚点 | 高亮 + 倒计时数字 |
三层落点
| 层 | 文件 | 内容 |
| :-: | :--- | :--- |
| 数据 | src/data/daily/timeAnchors.ts | TimeAnchor 类型 + TIME_ANCHORS 常量数组 |
| 逻辑 | src/utils/daily/timeAnchorLogic.ts | getCurrentAnchor(slot) / getNextAnchor(slot) / getTimeToNextAnchor(slot) / getAnchorsStatus(slot) |
| UI | src/components/daily/TimeProgressBar.tsx | 进度条 + 锚点 + 倒计时 复合组件 |
| UI | 修改 src/components/AppHeaderBar.tsx | 把 gameTimeLabel 段(line 92-108)替换为 <TimeProgressBar gameTime={gameTime} /> |
UI 草图
时辰 第 3 日 · 白天 12:00 [营业中]
┌──────────────────────────────────────────┐
│ ●6:00 ◆12:00 ✦18:00 ◯0:00 │
│ ✓已过 ◀当前 ↘ 还有 6 时段 ↘ 还有 12 │
│ [▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░] │
└──────────────────────────────────────────┘
验收清单
- [ ] 顶部时间条可见 4 个锚点
- [ ] 当前时点对应锚点高亮(蓝色脉冲)
- [ ] 已过锚点显示 ✓ 灰色
- [ ] 未到锚点显示剩余时段数
- [ ] 每过一个 slot 倒计时 -1
- [ ] 通过 06:00 / 12:00 / 18:00 / 00:00 时点时锚点状态切换
- [ ] 跨日(slot 0)自动重置
- [ ] 移动端宽度 < 640 时锚点标签自动隐藏(只显图标)
估时
1 天。纯函数 + 1 个新组件 + 1 个文件小改。
依赖
- 🟢 无。可独立施工。
4. P2 · 今日待办清单(玩家每日规划)
用户故事
作为掌柜,我每天可以为今天 4 个锚点各安排"该完成什么",完成后自动 ✓,没完成进入日结的"未完成"列。
触发
- 每天清晨 06:00(dawn-prep 锚点)自动生成今日默认待办
- 玩家可手动增删/勾选
- 跨日 24:00 自动归档未完成项到日结
字段定义
// src/data/daily/checklist.ts
export type ChecklistCategory = 'staff' | 'inventory' | 'kitchen' | 'reputation' | 'finance';
export interface DailyChecklistItem {
id: string; // uuid
day: number; // 所属日期
anchorId: AnchorId; // 关联到哪个时点
category: ChecklistCategory;
title: string; // '派大嘴值早班'
description?: string; // '前厅 +1 接待力'
autoCompleteCondition?: string; // 自动化检查 key,如 'staff.dazui.shift.morning'
isCompleted: boolean; // 玩家手动勾 / 自动化 ✓
completedAt?: number; // 时间戳
carriedOver: boolean; // 是否为昨日逾期带入
}
export const DEFAULT_DAILY_CHECKLIST_TEMPLATE: Omit<DailyChecklistItem, 'id' | 'day' | 'isCompleted' | 'completedAt' | 'carriedOver'>[] = [
{ anchorId: 'dawn-prep', category: 'kitchen', title: '厨房备料', description: '米/油/盐库存 ≥ 5' },
{ anchorId: 'dawn-prep', category: 'staff', title: '早班派班', description: '前厅 +1 厨子 +1' },
{ anchorId: 'noon-peak', category: 'inventory', title: '高峰备货', description: '招牌菜食材足量' },
{ anchorId: 'dusk-closing', category: 'kitchen', title: '打烊清洁', description: '厨子收尾' },
{ anchorId: 'night-settle', category: 'finance', title: '盘点铜钱', description: '查看日结' },
];
关键规则
| 规则 | 说明 |
| :- | :- |
| 生成时机 | 每天 slot 6(dawn-prep)时从 DEFAULT_DAILY_CHECKLIST_TEMPLATE 复制生成今日 checklist |
| 逾期带入 | 昨日未完成项 carriedOver = true,移入今日最高优先级位置(不强制仍要在昨日锚点) |
| 自动完成 | 若 autoCompleteCondition 命中(如 staff.dazui.shift.morning = true),自动 isCompleted = true |
| 手动完成 | 玩家在面板上点 ✓ |
| 未完成后果 | 跨日 24:00 时未完成项进入日结卡的"未完成 N 项"字段(不直接扣银) |
| 逾期上限 | 同一 item carriedOver 最多 2 天,第 3 天强制归档到日结历史不显示在面板 |
三层落点
| 层 | 文件 | 内容 |
| :-: | :--- | :--- |
| 数据 | src/data/daily/checklist.ts | DailyChecklistItem 类型 + DEFAULT_DAILY_CHECKLIST_TEMPLATE 常量 |
| 逻辑 | src/utils/daily/checklistLogic.ts | generateDailyChecklist(day, carriedOver) / evaluateChecklist(items, state) / archiveOverdue(items, day) |
| 逻辑 | src/utils/daily/checklistAutoComplete.ts | tryAutoComplete(item, state): boolean 检查各项 autoCompleteCondition |
| UI | src/components/daily/DailyChecklistPanel.tsx | 抽屉式面板,按 4 个锚点分组 |
| UI | src/components/daily/ChecklistItem.tsx | 单个待办行(含自动完成态/手动勾选/逾期 badge) |
UI 草图
今日待办(第 3 日) [ + 新增 ]
┌─ 🌅 厨子备料 06:00 ─────────────────── 2/3 已完成
│ ✓ 厨房备料 自动完成
│ ✓ 早班派班 自动完成
│ ☐ 检查油壶是否够用 [手动]
│
├─ ☀ 客流高峰 12:00 ─────────────────── 0/1 已完成
│ ☐ 高峰备货 [手动]
│
├─ 🌆 打烊收尾 18:00 ─────────────────── 0/1 已完成
│ ☐ 打烊清洁 [自动]
│
└─ 🌙 深夜结算 0:00 ─────────────────── 0/1 已完成
☐ 盘点铜钱 [手动]
验收清单
- [ ] 每天 slot 6 自动从模板生成今日待办
- [ ] 玩家可手动勾选 / 取消
- [ ] 自动化条件命中时自动 ✓ 并显示「自动完成」badge
- [ ] 昨日未完成项带「⚠ 逾期」badge 带入今日
- [ ] 同 item 逾期 ≥ 3 天强制归档
- [ ] 跨日 24:00 未完成项进入日结卡"未完成 N 项"
- [ ] 玩家可手动新增自定义待办
- [ ] 面板支持按锚点折叠/展开
估时
1.5 天(半天数据/逻辑 + 1 天 UI + 半天自动化接入)。
依赖
- 🟢 内部依赖 P1(P1 提供锚点定义),但 P2 内部也可独立 mock 锚点常量
- 🟡 「自动完成条件」需要和现有员工 / 库存 / 厨房系统对接,对接工作量单独估算
5. P3 · 时点驱动的「应到 vs 实际」后果链(最重,后置)
用户故事
作为掌柜,每天到锚点时,客栈会自动检查「该到位的资源」是否到位。不到位时实际产出降级(出菜慢 / 拒客 / 关门),并把降级结果累计到日结"漏接"列。
触发
- 每个锚点 slot(6/12/18/0)触发
checkAnchorReadiness(anchor, state) - 输出
AnchorReadiness报告,降级结果回写到当日 metrics
字段定义
// src/data/daily/anchorRequirements.ts
export interface AnchorRequirement {
anchorId: AnchorId;
requirements: RequirementCheck[];
}
export type RequirementCheck =
| { kind: 'staff-min'; role: 'front' | 'kitchen'; min: number; }
| { kind: 'inventory-min'; itemId: string; min: number; }
| { kind: 'kitchen-recipe'; recipeId: string; }
| { kind: 'coin-min'; min: number; };
export interface AnchorReadiness {
anchorId: AnchorId;
isReady: boolean;
gaps: RequirementGap[]; // 未达标的项
downgrades: DowngradeEffect[]; // 实际触发的降级
}
export interface DowngradeEffect {
kind: 'slow-service' | 'reject-customers' | 'auto-close' | 'reputation-loss';
severity: number; // 1-3
description: string;
}
关键规则
| 规则 | 说明 |
| :- | :- |
| 客流高峰 12:00 检查 | 座位 ≥ 阈值 / 厨子 ≥ 1 / 库存 ≥ 高峰消耗量 |
| 厨子不足 | slow-service:出菜速度 -30%,顾客差评率 +15% |
| 座位满 | reject-customers:漏接人数 +N |
| 库存 < 0.5 天 | auto-close:该时点强制进入 closing |
| 降级量化 | 每个 downgrade 转成「漏接 N 位 / 损失 M 银」累加到日结 |
| 保护期 | day 1-3 所有 downgrade 降级 50% |
| 可被 P2 待办缓解 | 玩家在 P2 待办里"完成"对应项,可减少 gap 数量 |
三层落点
| 层 | 文件 | 内容 |
| :-: | :--- | :--- |
| 数据 | src/data/daily/anchorRequirements.ts | AnchorRequirement / RequirementCheck / DowngradeEffect 类型 + 默认配置 |
| 逻辑 | src/utils/daily/anchorCheckLogic.ts | checkAnchorReadiness(anchor, state): AnchorReadiness |
| 逻辑 | src/utils/daily/downgradeLogic.ts | applyDowngrade(state, downgrade): NewState |
| UI | 复用 P0 日结卡「漏接」列 + P2 待办面板红点 | 不用新增组件 |
| UI | src/components/daily/AnchorGapChip.tsx | 在 P1 时间条锚点旁显示「⚠2」红 badge |
UI 草图(P1 时间条上的红 badge)
●6:00 ◆12:00 ⚠2 ✦18:00 ◯0:00
↑ 当前高峰有 2 项资源缺口
验收清单
- [ ] 4 个锚点 slot 自动检查资源
- [ ] 不达标时弹出 toast「客流高峰:厨房人手不足」
- [ ] 时间条对应锚点显示红 badge
- [ ] 降级效果实际影响出菜/接待/关门
- [ ] 降级结果进入日结"漏接"列
- [ ] day 1-3 保护期降级 50%
- [ ] P2 待办完成可缓解对应 gap(具体对接哪些待办项在 P2 落地时定)
估时
3-4 天(1 天配置 + 1 天逻辑 + 1 天 UI 接入 + 0.5-1 天联调 + 0.5 天 P0+P1+P2 兼容)
依赖
- 🔴 必须在 P0 + P1 + P2 上线后跑 1-2 个版本,根据玩家反馈决定是否上 P3
- 🔴 必须和员工 / 库存 / 厨房三个系统约定好"资源接口"
6. 节奏与平衡
1 天 2.5 分钟是否要调?
| 节奏 | 适合度 | 建议 | | :- | :- | :- | | 1 天 2.5 分钟(现状) | 加了 P0+P1 后会显得太快——日结卡读完时间已经过了 1/3 | 🟡 上 P0 后看玩家反馈再定 | | 1 天 4 分钟 | 4 个锚点各 1 分钟,玩家有"做事窗口" | ✅ 建议作为 P3 上线时的配套调整 | | 1 天 5 分钟 | 偏慢,挂机感下降 | ❌ 不建议 |
建议:P0 上线时先不动节奏,P1 上线后看玩家是否反映"日结还没看完就过了一天",如反映再调到 4 分钟。
「漏接损失」定价
- 客单价 = 当日「已接待客人平均消费」
- 漏接损失 = 漏接人数 × 客单价 × 0.85(折扣因子,模拟"本可赚到但没赚到")
- 软提醒,不直接扣银——这是关键,让玩家先学会看
保护期
- day 1-3 全机制保护:日结卡
isProtectedDay = true,漏接损失灰色"演示中" - day 4+:正常显示,仅展示不扣银
- 真实扣银(如果要做)放到 P3 联调稳定后再开
7. 风险与依赖
风险
| 风险 | 等级 | 缓解 |
| :- | :-: | :- |
| 「漏接」数据源不存在 | 🔴 高 | 开工前先 grep 客流系统;若没有,降级方案:P0 只显示接待/营收两个字段,漏接延后 |
| P0 + P1 同时上线,玩家没有「适应期」 | 🟡 中 | 隔版本上线,P0 先跑 1 版再上 P1 |
| 自动化条件对接 P2 工作量低估 | 🟡 中 | 落地前先和员工/库存系统 owner 拉清单 |
| 保护期结束玩家突然被罚 | 🟡 中 | day 4 弹一次性说明 toast「保护期结束,掌柜的判断将真实影响日结」 |
| 顶部时间条宽度不够 | 🟢 低 | 移动端 < 640px 自动隐藏文字只显图标 |
| 3 层架构破坏 | 🟢 低 | 每个文件落到对应层;提交前按 AGENTS.md §1 自检 |
全局依赖
- 🟡
TodayCalendarSnapshot复用,无新增 - 🟡
BusinessDate/Calendar类型复用 - 🔴 客流系统**输出"应到 vs 实际"**的能力——P0 开工前必确认
- 🟢 现有
coins/reputation/ 库存接口稳定,无破坏性改动
8. 落地路线
| 阶段 | 内容 | 估时 | 准入条件 | | :- | :- | :- | :- | | P0 | 日结日报卡(漏接 + 营收 + 库存 + 疲劳 + 预告) | 0.5 天 | 客流日志源确认 | | P1 | 顶部时间条改造(进度条 + 锚点 + 倒计时) | 1 天 | 无 | | 观察期 | 跑 1-2 个版本(每版本 3-5 天) | — | 收集玩家反馈 | | P2 | 今日待办清单(手动 + 自动完成 + 逾期) | 1.5 天 | P1 已上线 | | 观察期 2 | 跑 1-2 个版本 | — | 收集玩家反馈 | | P3 | 时点后果链(应到 vs 实际 + 降级) | 3-4 天 | P0+P1+P2 稳定 + 资源接口定 | | 节奏调整 | 1 天从 2.5 分钟调到 4 分钟(如果需要) | 0.5 天 | P1 反馈确认需要 |
提交规范
每个阶段完工时:
- [ ]
npm run lint通过 - [ ]
npm run build通过 - [ ] 现有 66 个 tsc 错误不新增
- [ ] 三层架构自检(按 AGENTS.md §1)
- [ ] 至少 1 个新测试(
*.regression.ts或现有测试文件) - [ ] 更新
docs/design/active/产品需求总览-v1.md加一行"日结/锚点系统 · P0 ✅"
9. 验收总览
P0 验收(半日交付)
- ✅ 每天 0:00 弹日结卡,7 个字段组齐全
- ✅ 漏接数 + 损失银 + 原因 tag 必显示
- ✅ 保护期正确标记
- ✅ 历史日结可查
P1 验收(1 日交付)
- ✅ 4 锚点进度条 + 倒计时实时刷新
- ✅ 当前锚点高亮
- ✅ 移动端降级(隐藏文字)
P2 验收(1.5 日交付)
- ✅ 每日 slot 6 自动生成 checklist
- ✅ 自动 + 手动完成双通道
- ✅ 跨日逾期处理
P3 验收(3-4 日交付,需 P0+P1+P2 稳定)
- ✅ 4 锚点资源检查触发降级
- ✅ 降级量化进入日结
- ✅ 时间条红 badge
- ✅ 保护期降级 50%
10. 待拍板事项
开工前请 P1 拍板以下 5 项:
- P0 「漏接」数据源——客流系统是否已有"应到 vs 实际"?如无,是否同意降级方案(P0 只显示接待/营收,漏接延后)?
- 节奏是否调整——P0 上线时维持 2.5 分钟/天,还是直接调到 4 分钟/天?
- 保护期天数——3 天够吗?是否要 5 天?
- 漏接损失是否真扣银——P3 之前都做软提醒,P3 联调后再开真扣?还是有别的时间点?
- P2 自动化条件对接范围——是只做员工早班,还是全量(员工/库存/厨房/财务)?
文档版本:v1 · 2026-07-31 · 草案
作者:Mavis(产品向)
关联:AGENTS.md §1 三层架构 · docs/design/active/经济循环体系-v1.md · docs/design/active/产品需求总览-v1.md