# 「随心」主题(Suixin Theme)任务清单(tasks) > 说明: > > - 本清单基于 `spec_kit/SuixinTheme/plan.md` 拆分为可执行任务。 > - 执行过程中:完成一项就在对应条目打勾(`[x]`),并补充必要的实现备注/PR 链接(如有)。 > - **当本 tasks 全部完成后**,需要回到 `spec_kit/overview.md` 在 `SuixinTheme` 条目下标记“已完成编码(阶段性/全部)”。 ## 0. 准备与基线确认 - [x] **T0.1 确认现有主题切换链路位置与文件** - **涉及文件**:`client/components/home/ThemeModal.tsx`、`client/app/(app)/home.tsx`、`client/src/storage/appStorage.ts` - **验收**:确认 `ThemeMode` 当前仅 `scenery/color`,并确认 `Home` 背景分支逻辑位置(方便插入 `suixin` 分支) - [x] **T0.2 确认用户画像可在 Home 获取** - **涉及文件**:`client/src/storage/appStorage.ts`、`client/src/features/userProfileScoring/*` - **验收**:`getUserProfileScoring()` 在 Home 已可读到 `stage/need/emotion_score/profile_confidence/profile_answered` ## 1. 数据与存储层改造(ThemeMode + suixin state) - [x] **T1.1 扩展 `ThemeMode` 枚举支持 `suixin`** - **涉及文件**:`client/src/storage/appStorage.ts`(类型 + `getThemeMode/setThemeMode` 兼容) - **要点**: - 新类型:`'scenery' | 'color' | 'suixin'` - `getThemeMode()` 读取到未知值时回退 `scenery`(保持兼容) - **验收**:TypeScript 编译无类型报错;旧存储值仍可正常读取 - [x] **T1.2 新增本地存储:`ui.theme.suixin.state`** - **涉及文件**:`client/src/storage/appStorage.ts` - **新增内容**: - `type SuixinThemeStateV1` - `getSuixinThemeState()` / `setSuixinThemeState()`(建议) - **验收**:能读写该 key;结构包含 `base_theme_id/seed/step_index/last_color` ## 2. 「随心」颜色算法模块(纯函数 + 可测试) - [x] **T2.1 新增 `suixinTheme` 模块目录与色盘常量** - **建议路径**:`client/src/features/suixinTheme/` - **新增文件建议**: - `palette.ts`:Base Theme(5)+ Neutral(1)常量 - `types.ts`:`BaseThemeId`、`SuixinThemeStateV1`(若不放在 storage) - **验收**:色值与 `设计说明文档/个性化背景颜色推荐算法.md` 完全一致 - [x] **T2.2 实现 Base Theme 选择(Theme Picking)** - **建议文件**:`client/src/features/suixinTheme/pickTheme.ts` - **规则**(必须对齐文档 Hard Rules): - `stage.unknown === 1` → `neutral` - `need` 为空 `{}` → `neutral` - 否则取 `Object.keys(need)[0]`,未知 key → `neutral` - **验收**:不同画像输入下输出主题 id 符合预期 - [x] **T2.3 实现线性 `lerp`(仅线性,禁止 easing)** - **建议文件**:`client/src/features/suixinTheme/colorMath.ts` - **要求**: - `hex ↔ rgb` 转换 - `lerpRgb(a,b,t)`:\(t\in[0,1]\) clamp - 输出标准 `#RRGGBB` - **验收**:插值边界 t=0/1 输出正确;中间值可复现、无跳段 - [x] **T2.4 实现 \(t\) 生成(切文案步进 + 往返波形)** - **建议文件**:`client/src/features/suixinTheme/progress.ts` - **要求**: - `N=12` 可配置常量 - 采用往返波形,避免回卷突跳 - **验收**:连续 step_index 下 \(t\) 始终在 \([0,1]\),且相邻变化幅度稳定 - [x] **T2.5(可选增强)按 emotion/confidence 控制“动态增强开关”** - **说明**:一期允许先不做亮度微扰,只实现“禁动态开关” - **对齐点**: - 文档:`emotion_score ≤ 0.2` 禁止任何扰动 - `emotion_score=null` 视为不确定,同样禁止扰动 - **验收**:低情绪/不确定时不触发增强分支(一期未实现亮度微扰,默认不启用任何扰动) ## 3. UI:ThemeModal 增加「随心」入口 - [x] **T3.1 ThemeModal 新增第三个主题卡片** - **涉及文件**:`client/components/home/ThemeModal.tsx` - **要点**: - `ThemeMode` 类型同步为包含 `suixin` - 新增 `ThemeCard`:`onPress={() => onSelect('suixin')}` - 布局改为 3 卡可展示(`flexWrap`/调整 gap/尺寸),避免小屏溢出 - 预览图占位(可先复用 `theme_color.png` 或新增 `theme_suixin.png`) - **验收**:弹窗可见第三项;选中态边框正确;无布局溢出 ## 4. i18n:新增主题文案(TC/EN) - [x] **T4.1 增加 `theme.suixin` 翻译键** - **涉及文件**:`client/src/i18n/locales/all.json` - **文案建议**: - `zh-TW`: `隨心` - `en`: `Ease`(语义化命名;如需改音译,后续可替换) - **验收**:切换语言后 ThemeModal 的第三项标题正确显示,不出现缺失 key ## 5. Home:随心主题渲染 + 冷启动/切文案计算 - [x] **T5.1 Home 增加 `suixin` 分支并使用 `backgroundColor`** - **涉及文件**:`client/app/(app)/home.tsx` - **要点**: - `themeMode === 'suixin'` 时,不渲染风景图 - 背景色来自 suixin 状态(`last_color`)或初始化计算结果 - **验收**:选择随心主题后背景变为算法输出色;切回风景/纯色逻辑不受影响 - [x] **T5.2 冷启动(进程级)计算并锁定 Base Theme** - **涉及文件**:`client/app/_layout.tsx`(或新增全局单例模块)、`client/app/(app)/home.tsx` - **要点**: - 生成一次 `boot_id`(仅内存)用于判断“本次进程首次进入 Home” - 首次进入 Home 且 theme=suixin:根据画像选 `base_theme_id` 并初始化 `seed/step_index/last_color` - 写入 `ui.theme.suixin.state` 持久化 - **验收**:同一次运行内多次进入 Home 不重复“冷启动重算”;重启 App 后会重算一次 - [x] **T5.3 切换文案时更新 suixin 颜色(不跨主题)** - **涉及文件**:`client/app/(app)/home.tsx` - **要点**: - 在 `triggerNextContent` 切换 index 后:若 theme=suixin,`step_index += 1` → 计算 \(t\) → `lerp` 得到新 `last_color` - 持久化更新 state - **验收**:上滑切下一条文案时背景色小幅变化;Base Theme 不变(同一色系内变化) ## 6. 收藏背景记录兼容 - [x] **T6.1 收藏逻辑兼容 suixin** - **涉及文件**:`client/app/(app)/home.tsx`(`favItem.background` 写入) - **规则**: - `suixin` 与 `color` 一致:保存 `hex` 到 `background` - **验收**:收藏后在 Favorites 列表缩略卡片可正确显示背景色 ## 7. 测试与回归 - [x] **T7.1(推荐)为 suixin 模块补单测** - **建议路径**:`client/src/features/suixinTheme/__tests__/` - **覆盖点**: - `stage.unknown=1` → neutral - `need={}` → neutral - `need={rest_balance:1}` → rest_balance - 往返波形 \(t\) 的边界与范围 - `lerp` 边界与格式 - **验收**:测试通过,避免回归 - [x] **T7.2 手动验收(按 spec)** - **验收清单**: - ThemeModal:三主题可切换,选中态正确 - 随心:冷启动首次进入 Home 生效;切文案时同主题内变色 - Hard Rules:unknown / need 跳过 → Neutral - 多语言:TC/EN 标题正确 - **备注**:已完成自动化回归(`vitest` + `tsc`);如需视觉确认可在模拟器/真机打开 ThemeModal 与 Home 做肉眼验收 ## 8. 收尾:overview.md 标记 - [x] **T8.1 tasks 全部完成后更新 `spec_kit/overview.md`** - **位置**:`## SuixinTheme` 条目 - **内容**:补充“已完成编码(全部)”与关键变更文件清单(可选) - **验收**:overview 总览可读、可追踪