56 lines
3.7 KiB
Markdown
56 lines
3.7 KiB
Markdown
# PROGRESS — C-06 · 关注 feed + 首页签到卡 + 学习数据钩子
|
||
|
||
- 状态:done
|
||
|
||
> 日期 2026-09-13 · 范围:`chunyu_project/article+learn+user`(后端只加字段/修bug/加用例,不改契约)+ `chunyu_project_react`
|
||
|
||
## 现状 vs 差距(接手时)
|
||
- 已有:`Follow` 模型 + `POST /user/follow/<id>/` + `GET /api/article/list?feed=following`(后端)+
|
||
详情页关注按钮(`ArticleDetail.handleFollow`)+ 桌面端 `Home` 签到卡(含未登录引导态)+
|
||
课程 `students_count`(ChapterRead 去重)双端显示。
|
||
- 缺口:article/learn **零用例**;列表接口缺 `author_user_id/is_following`(卡上无法关注);
|
||
列表无关注空态;`HomeMobile` 无签到条;无 `total_minutes` 字段;
|
||
**`get_author_name` 在 ASGI 下同步碰 `obj.author` 外键 → 课程列表 500**(本轮真抓到的 bug)。
|
||
|
||
## 改动
|
||
后端(`chunyu_project/`):
|
||
1. `article/serializers.py`:`ArticleListSerializer` 加 `author_user_id` + `is_following`(登录态关注判定)。
|
||
2. `learn/serializers.py`:
|
||
- `get_author_name` 改 `sync_to_async` 线程取数(修课程列表 500 真 bug,list/detail 双处);
|
||
- 新增 `parse_duration_minutes`(中文“30分钟”/纯数字解析,不可解析返回 None 不伪造)+
|
||
`total_minutes` 字段(list/detail 双序列化器,可解析章节求和)。
|
||
3. `article/tests/`(新建包 + `test_following_feed.py` 7 条):仅关注作者可见/未关注空态/
|
||
双关注全可见/取关移除/匿名空态/普通列表不受影响/草稿不进 feed。
|
||
4. `learn/tests/`(新建包 + `test_c06_hooks.py` 8 条):签到双签 400+积分不变+单记录/
|
||
status 已签/匿名 401;聚合 2 用户交叉去重=2/零阅读=0/detail 对齐;
|
||
total_minutes 求和 75/全不可解析 null。
|
||
|
||
前端(`chunyu_project_react/src/`):
|
||
5. `pages/Articles/Articles.tsx`:`Article` 接口加 `author_user_id/is_following`;
|
||
`handleToggleFollow`(关注切换 + feed=5 下取关即时移除);grid/list 双卡作者行加关注按钮;
|
||
空态(关注态 vs 普通态两套文案)。
|
||
6. `pages/Articles/Articles.css`:`.articles-follow-btn` + `.articles-empty`(含 dark)。
|
||
7. `locales/{en,zh,zh-TW,ja,ko,ru}.json`:`articles.empty.{title,hint,followingTitle,followingHint}`。
|
||
8. `pages/Home/HomeMobile.tsx` + `.css`:移动签到条(状态/周进度/一键签到/未登录引导,与桌面同口径)。
|
||
9. `pages/Learn/Learn.tsx` + `LearnMobile.tsx`:`total_minutes` 映射 + 有值才显示时长徽标;
|
||
`locales` 六语言加 `learn.minutes`;Learn 加缺失的 `ClockCircleOutlined` 引入。
|
||
|
||
## 口径说明
|
||
- `total_minutes` 只对可解析 duration 求和;存量中文字符串解析不出 → null → 前端不显示。
|
||
- 签到幂等:第二次 400(`今日已签到`),积分不变(单测锁定)。
|
||
- 未动:推荐算法(无)、Follow/签到字段与契约(无)、弹窗动画(无)。
|
||
|
||
## 验证
|
||
```bash
|
||
DB_ENGINE=django.db.backends.sqlite3 DB_NAME=".../dev_db.sqlite3" python manage.py test article learn tool -v 1
|
||
# Ran 30 tests … OK(15 存量 + 15 新增;中途一次 sqlite 锁表抖动,重跑即绿)
|
||
tsc --noEmit -p chunyu_project_react/tsconfig.json # 零报错
|
||
pnpm build # ✓ built in 14.99s
|
||
```
|
||
手工等价:A 关注 B → `feed=following` 只见 B 文(单测同等价 7 条);连签两次 → 第二次 400
|
||
积分不变(单测锁定)。
|
||
|
||
## 状态
|
||
done。遗留:user 滑块验证码既有红(3 失败+9 错误,与本任务无关,未动);
|
||
dev_db.sqlite3 曾缺 `aitool` 表已补迁移(`migrate aitool`),验证残留已清零。
|