Site Tools


Hotfix release available: 2026-07-14c "Mort". upgrade now! [57.3] (what's this?)
家庭管理系统h5:冷启动文件

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
家庭管理系统h5:冷启动文件 [2026/09/28 11:01] – 生日模块权限修复 172.17.0.1家庭管理系统h5:冷启动文件 [2026/10/18 01:18] (current) – 4.58 新增成长记录模块 172.17.0.1
Line 226: Line 226:
 - 杨创伟(堂弟)→ 农历**八月十八** ✅ - 杨创伟(堂弟)→ 农历**八月十八** ✅
 - 果果(家庭老师)→ 生日仍缺 ❌(待用户提供) - 果果(家庭老师)→ 生日仍缺 ❌(待用户提供)
 +
 +====== 4.51 家务定期任务:启用/禁用开关(2026-10-10) ======
 +
 +**需求**:家务模块的**定期任务**增加开关按钮 ——
 +- **启用**:该任务按设置的定期时间**自动列入未完成家务**
 +- **禁用**:**不**按定期时间自动列入
 +- 按钮点一次切换一次(启用 → 显示「禁用」;禁用 → 显示「启用」)
 +
 +===== 后端(`family_api.py` + `family.db`) =====
 +| 位置 | 改动 |
 +|---|---|
 +| `tasks` 表 | 新增字段 **`enabled INTEGER DEFAULT 1`**(1=启用 / 0=禁用)|
 +| `/api/family/tasks/refresh` 定期**重启**查询 | 加 `AND COALESCE(enabled,1)=1` |
 +| `/api/family/tasks/refresh` **自动生成**查询 | 加 `AND COALESCE(enabled,1)=1` |
 +| 重复生成**查重**查询 | 加 `AND COALESCE(enabled,1)=1` |
 +| `PATCH /api/family/tasks/<id>` 白名单 | 加 `"enabled"`(★普通用户也可切换,`allow_keys` 非管理员分支放行 `enabled`)|
 +
 +===== 前端(`family.html`) =====
 +- **状态标记**:定期任务的标题行显示 `▶ 启用中`(绿底)或 `⏸ 已禁用`(灰底)
 +- **切换按钮**:定期任务的按钮行新增 `⏸ 禁用` / `▶ 启用`(**临时任务不显示**)
 +- 新增 `toggleTaskEnabled(id, to)`:PATCH 提交 `enabled`,成功后 toast 提示并 `renderPage()`
 +
 +===== 验证 =====
 +| 项 | 结果 |
 +|---|---|
 +| SQL 逻辑 | 定期重启查询 & 自动生成查询:**启用入选 / 禁用排除** ✅;对照旧查询(无条件)两者都命中,证明过滤生效 ✅ |
 +| 前端渲染 | 34 个任务(定期 16 / 临时 18);**16 个定期任务全部有按钮与标记** ✅;**临时任务 0 个误加** ✅ |
 +| 页面截图 | 定期任务显示「定期 · 每1天 · ▶ 启用中」+「⏸ 禁用」按钮;临时任务无该按钮 ✅ |
 +| 数据 | 现有 16 个定期任务默认全部 `enabled=1`(启用中);测试任务已清理 ✅ |
 +| 回归 | 其他模块未受影响 ✅;无 JS 错误 ✅ |
 +
 +> 说明:禁用仅停止**自动列入/重启**,**已存在**的任务实例不受影响(可手动完成或删除)。
 +
 +====== 4.52 家务启用/禁用功能仅管理员可见(2026-10-10) ======
 +
 +**需求**:家务的启用/禁用功能,**普通用户不可见**。
 +
 +**前端(`family.html`)**
 +- 管理员判定改为**运行时函数**(原用加载时常量 → USER 是异步设置,导致管理员也判为 false 的坑):
 +<code>
 +  function isAdminNow(){ try{ return !!(USER && USER.role==='admin'); }catch(e){ return false; } }
 +</code>
 +- 定期任务的 **`⏸ 禁用` / `▶ 启用` 按钮** 与 **`▶ 启用中 / ⏸ 已禁用` 状态标记** 均加 `&& isAdminNow()` 条件 → 普通用户完全看不到
 +
 +**后端(`family_api.py`)**
 +- `PATCH /api/family/tasks/<id>` 的 `allow_keys` 非管理员分支恢复为 `("status",)` → 收回普通用户的 `enabled` 修改权限(防绕过前端)
 +
 +**验证**(★关键:管理员与普通用户分别实测)
 +| 身份 | 结果 |
 +|---|---|
 +| **管理员 武燕青**(role=admin)| 页面出现「⏸ 禁用」按钮 + 「▶ 启用中」标记 ✅(定期任务有,临时任务没有)|
 +| **普通用户 果果**(role=user)| 「⏸ 禁用」按钮 **0 个**、启用/禁用标记 **0 个**、`toggleTaskEnabled` **0 处** ✅;家务功能正常(34 张卡片、定期标签、状态按钮都在)✅ |
 +
 +> ★ 踩坑记录:管理员判定**不能**用页面加载时常量。`USER` 由异步请求设置,加载瞬间为空 → `IS_ADMIN` 恒为 false → 管理员也看不到按钮。改为每次渲染时调用 `isAdminNow()` 后正常。
 +
 +====== 4.53 家务:操作已完成任务后不自动折叠(2026-10-10) ======
 +
 +**需求**:在操作/修改**已完成**任务时,操作完成后**不要自动折叠**(否则刚改的任务立刻被收进折叠区,看不到)。
 +
 +**实现**(`family.html`)
 +- 新增全局标志 `window.__keepOpen`
 +- **置位点(4 个操作入口)**:
 +  | 函数 | 场景 |
 +  |---|---|
 +  | `setTask(id,st)` | 点「未开始/进行中/已完成」状态按钮 |
 +  | `saveTaskEdit(id)` | 编辑并保存任务 |
 +  | `saveTask()` | 新增/保存任务 |
 +  | `toggleTaskEnabled(id,to)` | 定期任务启用/禁用 |
 +- **消费点**:`renderHouse()` 渲染「📦 已完成」区时
 +<code>
 +  var _doneDisp=(window.__keepOpen?'':'none'); window.__keepOpen=false;
 +  h+='… <div style="display:'+_doneDisp+'">';
 +</code>
 +  → 刚操作过则**展开**,随后立即重置标志(下次进入恢复默认折叠)
 +
 +**验证**
 +| 场景 | 结果 |
 +|---|---|
 +| 进入页面(未操作)| 已完成区 `display:none` → **默认折叠** ✅(原行为不变)|
 +| 置位后触发渲染 | 已完成区 `display:""` → **保持展开** ✅ |
 +| 渲染后 | `__keepOpen` 自动重置为 false ✅ |
 +
 +====== 4.54 家务:棕色按钮「启用」文案改为「安排」(2026-10-10) ======
 +
 +**需求**:家务中把**棕色的启用按钮**的"启用"改成"**安排**"。
 +
 +**定位**:`family.html` 任务卡片按钮行中,已完成任务显示的那个棕色按钮(`background:#6d4c41`):
 +<code>
 +<button class="btn sm" style="background:#6d4c41" onclick="setTask(id,'未开始')">🔄 安排</button>
 +</code>
 +(原为 `🔄 启用` —— 点它把已完成任务重新排回「未开始」)
 +
 +**改动**
 +| 位置 | 改动 |
 +|---|---|
 +| 棕色按钮文案 | `🔄 启用` → **`🔄 安排`** |
 +| 灰色切换按钮(定期任务启用/禁用)| 保持 `▶ 启用` / `⏸ 禁用`(★此前误改,已回退)|
 +
 +> ⚠️ **踩坑**:改代码时把 `// 注释` 写在了**拼接表达式的续行 `+` 之前**,导致续行加号被注释掉 → 表达式断裂 → **页面卡在「加载中…」**(接口全 200 但渲染中断)。
 +> ★ 教训:JS 字符串拼接中的行尾注释**必须写在 `+` 之后**(或直接不加注释)。
 +
 +**验证**
 +| 项 | 结果 |
 +|---|---|
 +| 「🔄 安排」按钮 | **29 个**(= 已完成任务数)✅ |
 +| 「🔄 启用」残留 | **0 个** ✅ |
 +| 灰色切换按钮 | `▶ 启用` 3 个 / `⏸ 禁用` 14 个(不受影响)✅ |
 +| 页面加载 | ✅ 正常(不再卡「加载中」)|
 +
 +====== 4.55 家庭管理:登录态永久保持(localStorage + cookie 双写)(2026-10-10) ======
 +
 +**需求**:家庭管理 18932573927 的**登录状态永久保持**(不用反复登录)。
 +
 +**背景**:原登录态只存 `localStorage.family_user`(本身无过期),但**微信内置浏览器会不定期清理 localStorage** → 用户被迫重新登录。
 +
 +**实现**(`family.html`)
 +新增统一登录态管理(cookie 有效期 **10 年**,`SameSite=Lax`,`path=/`):
 +
 +| 函数 | 作用 |
 +|---|---|
 +| `saveUser(u)` | 写入:`localStorage` + **cookie** 双份 |
 +| `loadUser()` | 启动恢复:**localStorage 优先 → cookie 兜底**(若从 cookie 恢复,顺带回写 localStorage)|
 +| `clearUser()` | 退出登录:**双清**(两处都要清,防残留)|
 +| `_ckSet/_ckGet/_ckDel` | cookie 读写删(带过期时间)|
 +
 +**接入点**
 +- 登录写入:3 处(验证码登录 / 密码登录 / 切换账号)→ 统一改 `saveUser(d.user)`
 +- 启动恢复:`(function(){ USER=loadUser(); … })()`
 +- 退出登录:`logout()` → `clearUser()`
 +
 +**验证**
 +| 场景 | 结果 |
 +|---|---|
 +| 登录后 | localStorage ✅ + cookie ✅(cookie 含 10 年过期)|
 +| **清除 localStorage**(模拟微信清理)| cookie 仍在 ✅,`loadUser()` **成功恢复**为「武燕青」✅ |
 +| 退出登录(含 cookie 清除)| `loadUser()` 返回 null ✅(需重新登录,符合预期)|
 +
 +> 说明:cookie 与 localStorage 同域,属于**同一浏览器**范围内持久化;只要不手动「退出登录」、不清除浏览器数据,即可长期免登录。
 +
 +====== 4.56 登录态持久化增强:三重存储(覆盖全部账号)(2026-10-10) ======
 +
 +**需求**:18932573927(武燕青)与 **16603395188(倾心)** 的登录状态永久保持。
 +
 +**说明**:登录态持久化是**通用机制**(与手机号无关),任何账号登录都会写入三处,因此**所有账号同时生效**:
 +| 账号 | 姓名 | 角色 |
 +|---|---|---|
 +| 18932573927 | 武燕青 | admin |
 +| 16603395188 | 倾心 | user |
 +| 13780562913 | 果果 | user |
 +
 +**三重存储(按可靠性递进)**
 +| 层 | 介质 | 说明 |
 +|---|---|---|
 +| ① | `localStorage.family_user` | 常规读写,最快 |
 +| ② | **cookie** `family_user`(10 年有效,SameSite=Lax)| ★ 微信清理 localStorage 后仍可恢复(**已实测有效**)|
 +| ③ | **IndexedDB** `family_auth/u` | 额外保险;写入采用 `onupgradeneeded` + `onsuccess` 双写,规避首次建库时序问题 |
 +
 +**恢复顺序**:`localStorage → cookie(同步)`,都无则 `IndexedDB(异步兜底)` → 任一成功即自动登录并回写其它层。
 +
 +**验证**
 +| 场景 | 结果 |
 +|---|---|
 +| 登录(如 16603395188)| localStorage ✅ + cookie ✅ |
 +| **清除 localStorage**(模拟微信清理)| cookie 仍在 → `loadUser()` **成功恢复**为「倾心」✅ |
 +| 同时清除 localStorage + cookie | 交由 IndexedDB 兜底(★ 本测试浏览器沙箱限制 IndexedDB 未生效;真实手机浏览器一般可用;**前两重已足够**)|
 +| 手动「退出登录」| 三层全清 ✅(需重新登录,符合预期)|
 +
 +**给用户的使用建议**:微信里把家庭管理页面**加入浮窗/收藏**,之后打开即可(无需重复登录)。
 +
 +====== 4.57 果果工资对普通用户开放(只读)(2026-10-10) ======
 +
 +**需求**:果果工资模块**对普通用户可见**,可查看每月工资详情,但**只读、不能编辑**。
 +
 +**前端(`family.html`)**
 +| 位置 | 改动 |
 +|---|---|
 +| `USER_TABS` | 增加 `"salary"` → 普通用户可见「💰 果果工资」tab |
 +| 新增按钮 | `+ 新增月份工资` 仅 `isAdminNow()` 显示;普通用户改为提示「👀 仅可查看(如需修改请联系管理员)」|
 +| 操作列 | 「编辑 / 删」仅管理员显示,普通用户显示 `—` |
 +| `salEdit()` | 增加 `isAdminNow()` 保护(防绕过前端直接调用)|
 +
 +**后端(`family_api.py`)**
 +- 权限白名单新增:
 +<code>
 +  if path.startswith("/api/family/salary_month") and m == "GET": return None
 +  if path.startswith("/api/family/salary") and m == "GET": return None
 +</code>
 +  → 普通用户**只能读**;`POST/DELETE` 依然 403
 +- 403 提示文案更新为「无权限(普通用户仅可使用家务/预警/积分/生日;工资仅可查看)」
 +
 +**验证(普通用户用 16603395188 倾心实测)**
 +| 项 | 结果 |
 +|---|---|
 +| 可见 tab | 🏠家务 / ⭐积分 / 🎂生日 / ⚠️预警 / **💰果果工资** / 👤我的 ✅ |
 +| 数据 | 正常显示 **8 个月**,累计实发 ¥37719.23 ✅ |
 +| 新增按钮 | ✅ 已隐藏(显示只读提示)|
 +| 编辑 / 删 链接 | ✅ 已隐藏(操作列 `—`)|
 +| 后端 GET | **200** ✅(返回 8 个月)|
 +| 后端 POST | **403 无权限** ✅ |
 +| 管理员 | 增删改一切正常 ✅(验证用测试记录已清理)|
 +
 +====== 4.58 新增「成长记录」模块(身高/体重/脚长)(2026-10-16) ======
 +
 +**需求**:家庭管理增加模块,记录 **姓名 / 时间 / 身高 / 体重 / 脚长**;每个人按**固定时间间隔**记录一次。
 +
 +===== 数据表(family.db) =====
 +<code>
 +CREATE TABLE growth(id INTEGER PK, name TEXT, date TEXT,
 +                    height REAL, weight REAL, foot REAL,
 +                    note TEXT DEFAULT '', created TEXT DEFAULT '');
 +CREATE TABLE growth_cfg(name TEXT PRIMARY KEY, days INTEGER DEFAULT 30, created TEXT DEFAULT '');
 +</code>
 +
 +===== 接口(family_api.py) =====
 +| 接口 | 方法 | 说明 |
 +|---|---|---|
 +| `/api/family/growth` | GET | 返回 `records`(按日期倒序)+ `people`(每人:间隔天数/上次日期/距今天数/下次日期/超期天数/has)+ `cfg` |
 +| `/api/family/growth` | POST | 新增记录;**同一人同一天重复提交 → 覆盖**(不产生重复行);传 `id` 则更新该条 |
 +| `/api/family/growth?id=` | DELETE | 删除一条(仅管理员)|
 +| `/api/family/growth/cfg` | POST | 设置某人的记录间隔天数(默认 30)|
 +
 +**权限**:普通用户 **GET 放行(只读)**,POST/DELETE/cfg **403 仅管理员**(`_guard` 白名单新增一行)。
 +
 +===== 前端(family.html) =====
 +- 新增 tab **「📏 成长」**(`ALL_TABS` 管理员 / `USER_TABS` 家人只读)
 +- 每人一张卡片:`每 N 天` + 状态(⏳ 还没有记录 / ✅ 下次 YYYY-MM-DD / ⚠️ 已超期 N 天)+ 上次数据(身高/体重/脚长 + N 天前)
 +- 管理员卡片右侧:`⚙️ 间隔`(prompt 设置天数)、`+ 记录`;右下 FAB 也可新增
 +- 「历史数据」区:日期 + 姓名 + 身高/体重/脚长 + 备注,管理员可 ✕ 删除
 +- 新增表单(底部弹出 sheet):姓名下拉(来自 members)、日期(默认今天)、身高/体重/脚长(数字,至少填一项)、备注
 +
 +===== 验证 =====
 +| 项 | 结果 |
 +|---|---|
 +| 建表 | ✅ growth / growth_cfg 自动创建 |
 +| GET(空库)| ✅ people 自动从 members 生成(席子初、席子恩),间隔默认 30 |
 +| POST 录入 | ✅ 返回 id;同人同日重复提交覆盖 |
 +| 状态计算 | ✅ 录入 2026-10-16 → 「2 天前」、下次 2026-11-15(30 天档)|
 +| 改间隔 | ✅ 席子恩设为 90 天 → 下次变 2027-01-14 |
 +| 权限 | 普通用户 GET **200** / POST **403** / DELETE **403** ✅ |
 +| 管理员视图 | ✅ 标题/两人卡片/数据/按钮/删除全部正常,无 JS 错误 |
 +| 普通用户视图 | ✅ tab 可见、数据可见、**无 新增/间隔/删除** 入口 |
 +| 收尾 | 测试数据已清理(growth 0 条、cfg 空,回到默认 30 天)|
 +
 +⚠️ 注意:`family_api.py` 是 Blueprint,新增路由必须用 `@bp.route`。
  
 ====== 5. 排障速查 ====== ====== 5. 排障速查 ======
家庭管理系统h5/冷启动文件.1790593272.txt.gz · Last modified: by 172.17.0.1