iven
|
32a91551c4
|
perf(app): Phase 2 前端性能优化 5 项 — 8b-D01/D02/D03/M02/N01
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
- 8b-D01: Isar 添加 authorId+dateEpoch 复合索引和 dateEpoch 单独索引
- 8b-D02: getJournals 分页改为 DB 层 .offset().limit() 替代 Dart 层 sublist
- 8b-D03: home_bloc monthCount 改用日期范围独立查询(不受分页限制)
- 8b-M02: 笔画光栅化改为 BBox 裁剪 — 短笔画不再创建全画布尺寸图像
- _CacheEntry 增加 offset 字段记录 BBox 偏移
- _rasterizeStroke 计算包围盒 + 4px padding
- _compositeIncremental 使用 offset 定位
- 8b-N01: SyncEngine enqueue 合并同一资源的操作
- create+update → create(最新数据)
- update+update → update(最新数据)
- update+delete → delete
- create+delete → 取消(不发送)
- 注意: Isar .g.dart 需运行 build_runner 重新生成
|
2026-06-03 16:05:11 +08:00 |
|
iven
|
99db8e5cb0
|
fix(app): 家长同意验证流程 — PIPL 第28条合规
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
- 新增 ParentalConsentPage: 显示隐私政策要点 + 双重确认复选框
- 角色选择流程: 学生 → 家长同意确认 → 班级码输入
- Authenticated 状态: 添加 needsParentalConsent/parentalConsentAt/selectedRole
- ParentalConsentAccepted 事件: 记录同意时间戳
- 路由守卫: 注册 /parental-consent 路径和重定向逻辑
- 非学生角色(老师/家长/独立用户)不需要经过同意流程
审计 ID: S-03
|
2026-06-03 10:25:23 +08:00 |
|
iven
|
a34c9fd176
|
fix(app): 强制 HTTPS — Android 网络安全配置 + 生产默认 HTTPS
- Android: 添加 network_security_config.xml,默认禁止明文流量
- Android: 仅允许 localhost/127.0.0.1/10.0.2.2 明文(开发调试)
- Android: 更新 AndroidManifest 引用网络安全配置
- ApiClient: 默认 URL 改为 https://api.nuanji.app/api/v1
- AppConfig: fromEnvironment 默认值改为 HTTPS 生产地址
- AppConfig: dev 常量保留 localhost(仅用于本地开发)
- iOS: ATS 默认已强制 HTTPS,无需修改
审计 ID: 6b-C01
|
2026-06-03 10:13:20 +08:00 |
|
iven
|
45949e3ed0
|
fix(app): Token 自动刷新拦截器 — 401 时自动刷新 + 重试原请求
- ApiClient: 添加 onRefreshToken 回调,401 时自动调用刷新
- ApiClient: 并发保护(_isRefreshing),防止多个 401 触发多次刷新
- ApiClient: 跳过 /auth/refresh 自身的 401(避免无限循环)
- ApiClient: 刷新成功后自动重试原始请求
- AuthRepository: 注册 _handleAutoRefresh 回调
- 使用回调模式避免 ApiClient ↔ AuthRepository 循环依赖
审计 ID: 9a-AUTH-01
|
2026-06-03 10:07:33 +08:00 |
|
iven
|
11d0971a67
|
feat(app): pnpm 一键启动 + Flutter Web 编译修复
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
1. 新增 pnpm start:dev / pnpm start:stop 命令
- scripts/dev.mjs: 跨平台启动脚本(后端+管理端+学生端)
- scripts/stop.mjs: 端口清理停止脚本
- 根 package.json 定义 pnpm 脚本
2. 修复 Flutter Web 编译(Isar 3.x + flutter_secure_storage 不兼容)
- isar_database: 条件导出,Web 用空 stub
- isar_journal_repository: 条件导出,Web 用空 stub
- sync_engine: 条件导出,Web 用内存队列(无 Isar 持久化)
- 移除 flutter_secure_storage(v9 web 插件用 dart:html)
- 新增 SecureTokenStore 接口 + shared_preferences 实现
- auth_repository 改用 SecureTokenStore 接口
|
2026-06-03 09:50:19 +08:00 |
|
iven
|
9ce300ddb9
|
fix(app): 修复笔画缓存 use-after-dispose — 移除增量合成时的提前 dispose
- _compositeIncremental 中不再 dispose strokeImage,因为 _cache 持有同一引用
- 提前 dispose 导致 syncStrokes/clear/dispose 时 double-dispose(use-after-free)
- 单笔画 image 生命周期由缓存统一管理:移除/清除/销毁时释放
- 更新 _rebuildComposite 注释,移除过时说明
审计 ID: 8b-R01
|
2026-06-03 01:06:34 +08:00 |
|
iven
|
f0741450bc
|
feat(app): 家长端数据导出 — 添加 JSON 文件下载 + 预览
- 新建 file_download.dart 跨平台下载工具(conditional import)
- download_impl_web.dart: Web 平台通过 html.AnchorElement + Blob 下载
- download_impl.dart: 非 Web 平台 stub(Phase 2 扩展 path_provider)
- _ExportDataView: 添加下载按钮 + JSON 折叠预览 + PIPL 提示
- 移除 'Phase 1 预览' 占位文案,替换为完整下载功能
|
2026-06-02 23:36:35 +08:00 |
|
iven
|
c9a69d0be1
|
feat(app): 添加评论列表展示组件 — FutureBuilder 轮询模式
|
2026-06-02 23:26:54 +08:00 |
|
iven
|
9e53ca8555
|
feat(app): EditorPage 顶栏添加评语入口 — 仅已有日记显示
- 添加评语图标按钮(仅 journalId != null 时显示)
- 实现 _showComments 方法打开 CommentListSheet
- 补充 api_client + comment_list_sheet imports
|
2026-06-02 23:26:24 +08:00 |
|
iven
|
6c9a38b27b
|
feat(app): 添加 EditorBloc.LoadJournal event — 加载已有日记数据
- LoadJournal event: 原子加载 title/mood/tags/strokes/elements/lastSavedAt
- _onLoadJournal handler: 不触发 auto-save (isDirty=false)
- 单元测试: 验证 LoadJournal 正确还原所有状态字段
- mood_bloc: linter 补充 foundation.dart import
|
2026-06-02 23:23:17 +08:00 |
|
iven
|
e57c3427a4
|
fix(app): 18 处 catch(e) 添加 debugPrint 异常日志
- parent_bloc: 6 处 (LoadChildren/BindChild/ViewJournals/ExportData/DeleteData/UnbindChild)
- search_bloc: 3 处 (SearchByMood/SearchByTag/SearchByKeyword)
- achievement_bloc: 1 处 (_fetchAchievements)
- sticker_bloc: 2 处 (_fetchPacks/fetchStickersInPack)
- template_bloc: 1 处 (_fetchTemplates)
- mood_bloc: 1 处 (_loadStats)
- home_bloc: 1 处 (_onLoadData)
- calendar_bloc: 1 处 (_onMonthChanged)
- sync_engine: 1 处 (trySync)
- weekly_page: 已有 debugPrint,无需修改
|
2026-06-02 23:21:16 +08:00 |
|
iven
|
c92ead60e3
|
feat(app): EditorPage 加载已有日记 — 替换为 LoadJournal 原子事件
- _loadExistingJournal 改用单一 LoadJournal event 替代多个细粒度事件
- 添加 _titleController 同步,确保 LoadJournal 后标题输入框正确显示
- 不触发 auto-save (isDirty=false),因为这是加载而非用户编辑
|
2026-06-02 23:16:58 +08:00 |
|
iven
|
85d6781372
|
fix: Phase 1.3 完善修复 — 管理端对接 + HMS清理 + 编辑器加载
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
- feat(web): ClassList.tsx 对接 update/deactivate/reset-code API
- 编辑班级: PUT /diary/classes/:id
- 停用班级: PATCH /diary/classes/:id/deactivate (Popconfirm 确认)
- 重置班级码: POST /diary/classes/:id/reset-code (Popconfirm 确认)
- 数据源改用 listAll() 获取所有班级
- fix(web): JournalList.tsx 班级筛选改用 classApi.listAll()
- fix(app): EditorPage 加载已有日记数据 (journalId 非空时)
- 从 Isar 恢复笔画/元素/标签/心情/标题
- _EditorView 改为 StatefulWidget + initState 加载
- chore(web): HMS 遗留代码清理
- 删除 api/copilot.ts, healthFixtures.ts, healthHandlers.ts
- AuditLogViewer 资源类型替换为日记模块类型
- auth.test.ts / renderWithProviders 权限码 health.* → diary.*
- docs: 确认 M6 NotificationService 为误报 (已在 3 处调用)
|
2026-06-02 22:54:09 +08:00 |
|
iven
|
49d4aa36a7
|
fix(app): Phase 1.1 紧急修复 — SyncEngine 接入 + authorId + catch 异常处理
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
- feat(sync): SyncEngine 接入 EditorPage, 保存时 enqueue + 网络恢复自动 trySync
- fix(editor): authorId 从 AuthBloc 获取, 替代硬编码 'local'
- fix(bloc): class_bloc/calendar/profile/parent catch(_).全部改为 debugPrint
- feat(editor): 编辑器工具栏拆分 (brush_panel/tag_panel/text_format_bar/dot_grid_painter)
- feat(editor): EditorBloc 扩展 + EditorPage 增强
- feat(search): SearchBloc 扩展搜索功能
- feat(home): HomeBloc/HomePage 增强
- feat(auth): LoginPage 增强
- feat(templates): TemplateGalleryPage 重构
- fix(web): 管理端班级/日记页面修复
- fix(server): comment_service + theme_handler 修复
- docs: 添加全链路审计报告和验证截图
|
2026-06-02 21:21:43 +08:00 |
|
iven
|
7e928ae1e1
|
fix(app): 修复 P2~P4 共 10 项前端问题
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
P2 必须修复:
- 教师布置主题 classId 从硬编码改为班级下拉选择器
- 班级日记墙使用服务端 classId 过滤替代前端过滤
- Profile 统计栏接入 JournalRepository 真实数据
- WeeklyPage 从全硬编码改为 JournalRepository 数据驱动
P3 建议改进:
- 提取 mood_utils.dart 公共函数,消除 4 处重复定义
- 贴纸库搜索框连接 StickerBloc 按名称过滤
P4 细节打磨:
- 家长页多孩子时显示 DropdownButton 选择器
- 搜索结果日记卡片点击跳转 /editor?id=
- MonthlyPage 照片数量从 JournalElement 统计
- calendar_page/mood_page/search_page 统一使用 moodToEmoji/moodToLabel
|
2026-06-02 20:21:51 +08:00 |
|
iven
|
181bfb1f3e
|
fix(app): 对齐 Open Design spec — 字体/Token/首页/Tab栏/路由/Discover页
针对 docs/opendesign/warm-notes-design-spec.md 全面审查的修复:
## 🔴 阻断级修复(商用合规)
- 下载真实 Quicksand/Nunito 字体文件(原 0 字节)
- 添加 OFL.txt 许可证文件,履行 SIL Open Font License 分发义务
## 🟠 设计 Token 偏差
- AppRadius: 删除非规范的 xs=8px,所有引用迁移至 sm=10px
- AppColors.moodColors: 对齐 spec §3.6
- happy #FFD93D → secondary #81B29A
- calm #81B29A → tertiary #F2CC8F
- sad #7B9CC4 → #5B7DB1
- thinking #B8A9C9(淡紫,spec 无)→ #8B7E74
- AppShadows: blurRadius/alpha 精确对齐 spec §1 (12/20/32 + 0.06/0.08/0.12)
- DesignTokens: 补 spacing40 + 新增 safe-top/safe-bottom/tab-height/touch-min 常量
## 🟠 首页 §3.4 完全重构
- 新增问候语头部(xx好,小暖 + accent 色高亮名字)
- 新增 streak-badge pill 徽章(tertiary-soft + #B8860B 暖金)
- 心情选择器卡片背景从 primaryContainer 改为 surface(spec 规定 #FFFFFF)
- 心情卡片圆角 lg(22) → md(16) 对齐 spec
- 新增 today-card 渐变卡片 + 浮动右下圆形写按钮
- 新增 quick-stats 三栏统计(本月日记/连续天数/总日记数)
- 移除 AppBar 多余的贴纸/模板按钮,搜索按钮改路由到 /search
- HomeBloc 扩展 monthCount/totalCount 字段
- 日记卡片:72×72 预览图 + 标签摘要 + 心情圆点
## 🟠 路由 §3.12 + §3.13 拆分
- 新建 DiscoverPage (features/discover/views/discover_page.dart)
- 搜索框(跳转 /search)
- 每日推荐渐变卡片
- 热门话题横向 chips(前 3 个 accent 高亮)
- 精选模板 2 列网格
- 达人日记列表
- /discover 路由从指向 SearchPage 改为 DiscoverPage
- 新增 /search 路由(全屏无 Tab)指向 SearchPage
## 🟠 Tab 栏 §2.2 重构
- 高度从 64px 改为 56+bottomPadding(含 safe-bottom,约 90px)
- 中心按钮从 CircularNotchedRectangle 凹槽改为 margin-top:-16px 凸起
- FAB 尺寸从默认改为 48×48 spec 规格
- FAB 图标从 edit_rounded 改为 add_rounded(spec §2.2)
- 删除未使用的 _navItems 旧常量
## 🟡 登录页圆角统一
- 移除 3 处 InputBorder 显式 mdBorder(16px) 覆盖
- 全局主题 smBorder(10px) 生效,对齐 spec
- 提交按钮圆角改为 pill(spec §2.6 Primary 按钮)
## 验证
- flutter analyze: 0 errors (剩余 40 个 warning/info 全为预存)
- flutter test: 84/85 通过(widget smoke test 预存失败,与本次无关)
|
2026-06-02 09:11:46 +08:00 |
|
iven
|
b320641d9c
|
fix(app): 全链路验证修复 — 编译错误/CORS/迁移/启动脚本
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
前端修复:
- calendar_page: 移除不存在的 JournalEntry.content getter
- responsive_scaffold: 移除不存在的 notchThickness 参数
- splash_page: SingleTickerProvider → TickerProvider (多 AnimationController)
- profile_page: UserRoleType.name → .code (修复运行时崩溃)
- 导入缺失的 user.dart
后端修复:
- class_service: generate_class_code 取 UUID 后6位(随机部分)避免碰撞
- diary_role_seed: 移除不存在的 id 列,使用复合主键 ON CONFLICT
基础设施:
- config/default.toml: CORS 改为通配符(开发模式)
- scripts/dev.sh: 统一启动脚本(自动清理端口)
- docs/opendesign/: Open Design 设计规格 HTML 原型稿
验证结果: flutter analyze 0 error, cargo test 77/77 通过, 17个页面全部渲染正常
|
2026-06-02 01:03:58 +08:00 |
|
iven
|
749ef55b89
|
feat: Week 4 收尾 + 架构治理 — 搜索/家长中心/Feature Flag/Docker/环境配置
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
架构治理:
- Feature Flag 落地: Cargo.toml [features] default=["diary"] + main.rs cfg 条件编译
- 环境配置统一: AppConfig 类 + --dart-define 注入 + SSE 端口 8080→3000 修复
搜索替代方案 (无 FTS):
- SearchBloc + 标签/心情筛选接入后端 API
- JournalRepository 扩展 mood/tag 筛选参数
- 搜索页 UI 接入实际数据(替换占位文本)
家长中心最小集 (PIPL 合规):
- 后端: parent_service (绑定/查看/导出/删除/解绑) + parent_handler (6 个 API 端点)
- 前端: ParentBloc + ParentPage 功能完整实现
- 绑定孩子、只读查看日记、导出数据、删除数据、解绑
Docker 部署:
- verify.sh 健康检查脚本 (Axum/PG/Redis/OpenAPI 四项检查)
测试修复:
- home_bloc_test / calendar_bloc_test 适配 JournalRepository 新参数
验证: flutter test 84/84 pass, cargo test 76/76 pass, cargo check pass
|
2026-06-01 23:53:34 +08:00 |
|
iven
|
f0921d554c
|
fix(app): 修复 ShareBottomSheet nullable 检查
|
2026-06-01 23:06:39 +08:00 |
|
iven
|
3eaf83c79a
|
feat(app): 老师点评功能 — CommentCreate事件 + CommentBottomSheet + 日记墙点评按钮
|
2026-06-01 22:49:56 +08:00 |
|
iven
|
973bb56af6
|
feat(app): 编辑器完成按钮接入分享面板 — ShareBottomSheet + sharedToClass更新
|
2026-06-01 22:45:56 +08:00 |
|
iven
|
55285b57a7
|
feat(app): 班级码验证前后端联调 — AuthBloc接入API + 错误计数锁定UI
|
2026-06-01 22:42:33 +08:00 |
|
iven
|
0c6a33d96b
|
chore(app): linter 格式化 + image_picker 自动生成插件注册
|
2026-06-01 21:44:07 +08:00 |
|
iven
|
6378da055f
|
feat(app): EditorPage 读取 template 参数 — 模板选择框架
|
2026-06-01 21:41:53 +08:00 |
|
iven
|
db881c25a0
|
feat(app): 集成贴纸选择到编辑器 — 底部面板 + 自动放置
|
2026-06-01 21:38:26 +08:00 |
|
iven
|
57b45f7cbf
|
feat(app): 创建贴纸选择底部面板 — 6 类 60 个 emoji 贴纸
|
2026-06-01 21:36:51 +08:00 |
|
iven
|
89c1cefb11
|
feat(app): 集成图片上传到编辑器 — 拍照/相册 + 压缩 + 拖拽定位
|
2026-06-01 21:35:43 +08:00 |
|
iven
|
cd86156590
|
feat(app): 创建图片选择+压缩处理器 — ImagePickerHandler
|
2026-06-01 21:32:55 +08:00 |
|
iven
|
9785370922
|
feat(app): 增强文字元素渲染 — 多行+字号+颜色
|
2026-06-01 21:28:15 +08:00 |
|
iven
|
fef2d629e5
|
feat(app): 集成文字输入到编辑器 — TextInputOverlay + 工具栏选项行
|
2026-06-01 21:27:15 +08:00 |
|
iven
|
d392515f4a
|
feat(app): 创建文字输入覆盖层组件 — TextInputOverlay
|
2026-06-01 21:23:30 +08:00 |
|
iven
|
417dcb08e4
|
feat(app): 添加 JournalElement 类型便利工厂方法 — text/image/sticker
|
2026-06-01 21:22:27 +08:00 |
|
iven
|
c2a95798bd
|
fix(app): 修复日历页日期查询参数格式 — 去除毫秒匹配后端 NaiveDateTime
|
2026-06-01 18:12:51 +08:00 |
|
iven
|
8e3e232278
|
fix: 全链路问题修复 — 编辑器返回/Tab导航/数据库编码/Token注入
修复内容:
- 编辑器返回按钮: 所有 context.go('/editor') 改为 context.push(),pop() 加安全守卫 fallback 到 /home
- Tab 导航: Web 平台强制使用移动端底部 TabBar 布局 (kIsWeb 守卫)
- 数据库编码: db.rs 自动追加 client_encoding=utf8 参数,修复中文 display_name 乱码
- AuthBloc token: 清理冗余 TODO,token 注入已在 AuthRepository 中正常工作
- 影响 9 个文件的编辑器导航调用点统一修改
|
2026-06-01 18:08:09 +08:00 |
|
iven
|
33dc5e19e4
|
fix(app): Web 平台兼容性修复 + 字体资源 + API base URL
- 添加 Web/Windows 平台支持 (flutter create --platforms)
- 下载字体资源 (NotoSansSC/Caveat Regular+Bold)
- Isar 3.x Web 不兼容:添加 kIsWeb 守卫,Web 上跳过 Isar 初始化
- IsarJournalRepository: instance 返回 nullable,Web 上使用 RemoteJournalRepository
- SyncEngine: persistPendingQueue/restorePendingQueue Web 安全
- SettingsBloc: 从 RepositoryProvider 改为 ListenableProvider
- ApiClient base URL: 8080 → 3000 匹配后端端口
- Isar .g.dart: 64 位 ID 替换为 JS 安全范围值
|
2026-06-01 17:30:27 +08:00 |
|
iven
|
2481c8fce6
|
feat(app): Isar 本地数据库集成 — Collection + Repository + 编辑器持久化 + SyncEngine 队列
新增文件:
- data/local/collections/ 3 个 Isar Collection 定义 + 生成 Schema
- data/repositories/isar_journal_repository.dart 完整 CRUD + 乐观锁
修改文件:
- app.dart: IsarJournalRepository 注册为主 JournalRepository + SyncEngine 注入
- editor_page.dart: onSave 接入 JournalRepository,笔画/元素自动保存到 Isar
- sync_engine.dart: 新增 persistPendingQueue/restorePendingQueue Isar 持久化
- isar_database.dart: 注册 3 个 Collection Schema
- main.dart: 启动时初始化 Isar
架构: 离线优先 — Isar 为本地主仓库,Remote 供 SyncEngine 推送
|
2026-06-01 14:41:40 +08:00 |
|
iven
|
e07da7addb
|
perf(app): 手写引擎性能优化 — 双层架构 + 光栅化缓存 + O(1) 点缓冲
性能优化:
- 新建 StrokeRasterCache: 已完成笔画光栅化为 ui.Image 合成位图
- 新建 CachedStrokesPainter: 每帧仅 drawImage,O(1) 开销
- 新建 ActiveStrokePainter: 仅渲染当前笔画,isComplete: false
- _currentPoints 改为可变缓冲区 + ValueNotifier 驱动,消除 O(N²) 列表拷贝
- 双层 Stack 架构: 已缓存层(不随指针移动重绘) + 实时层(仅当前笔画)
Bug 修复:
- 橡皮擦 saveLayer 合成: BlendMode.dstOut 在离屏缓冲区中正确工作
- pointsToOutline 新增 isComplete 参数: 实时绘制传 false,完成笔画传 true
- 模式切换不再销毁 HandwritingCanvas: IgnorePointer 替代 if/else 分支
架构改进:
- 提取 createPaintForStroke() 为顶层函数,供缓存和 Painter 共用
- 移除旧 StrokePainter 类,由双层 Painter 替代
- LayoutBuilder 跟踪画布尺寸,尺寸变化时缓存自动失效
文件变更:
- 新建 stroke_cache.dart (~210 行)
- 新建 cached_strokes_painter.dart (~35 行)
- 新建 active_stroke_painter.dart (~70 行)
- 重写 handwriting_canvas.dart (~300 行)
- 重构 stroke_renderer.dart (~185 行, 移除旧 Painter)
- 修改 editor_page.dart (IgnorePointer 模式切换)
验证: flutter analyze 0 error
|
2026-06-01 13:18:36 +08:00 |
|
iven
|
8331db63ba
|
feat(app): 设置页 UI + Mood/成就/贴纸 BLoC 接入 API + B7 测试扩展
前端改动:
- 新建设置页面 (主题切换/关于/隐私政策/用户协议/儿童隐私保护)
- SettingsBloc 注册到 MultiRepositoryProvider 全局可访问
- MoodBloc 修复编译错误 + 接入 /diary/stats/mood API
- MoodPage 添加错误状态展示和重试按钮
- AchievementBloc + 页面改造接入 /diary/achievements API
- StickerBloc + 页面改造接入 /diary/sticker-packs API
- TemplateBloc + 页面改造接入 /diary/templates API
- ProfilePage 设置入口改为跳转 /settings
- 添加 /settings 路由
后端改动:
- 扩展 mood_stats_service 测试 (连续天数算法/心情计数/边界场景)
- 新增 class_service 测试 (班级码生成/唯一性/错误映射)
- 新增 achievement_service 测试 (DTO 结构/序列化/map 构建)
- 新增 sticker_service 测试 (DTO 序列化/错误处理)
- 扩展 dto.rs 测试 (achievement/mood_stats/sticker/template/notification)
- 清理 2 个 unused import warning
验证:
- cargo check 0 error 0 warning
- flutter analyze 0 error
|
2026-06-01 11:19:43 +08:00 |
|
iven
|
860e9e5d22
|
feat(app): BLoC 集成 Repository + SettingsBloc 主题切换
全局依赖注入:
- app.dart 注入 JournalRepository + ClassRepository + SettingsBloc
- ApiClient token 自动注入(监听 AuthBloc 状态)
BLoC 重构 (占位数据 → Repository):
- CalendarBloc: 通过 JournalRepository 加载月度日记
- ClassBloc: 通过 ClassRepository + JournalRepository 加载班级数据
- 新增 ClassJoin 事件支持班级码加入
- HomeBloc: 加载最近日记 + 心情概览 + 连续天数 + 今日是否已写
设置系统:
- SettingsBloc: ThemeMode 切换 (system/light/dark)
- app.dart 通过 ListenableBuilder 响应主题变化
- HomeBloc 支持下拉刷新
首页增强:
- 连续天数徽章 + 今日已写标记 + 最常用心情高亮
- RefreshIndicator 下拉刷新
- 日记列表卡片显示日期
验证: flutter analyze 0 error
|
2026-06-01 10:32:20 +08:00 |
|
iven
|
263ddf31a6
|
feat(app): 数据层集成 — RemoteJournalRepository + ClassRepository + SSE 通知
数据层新增:
- RemoteJournalRepository: 日记 CRUD + 元素管理,通过 ApiClient 连接后端
- ClassRepository: 班级/主题/评语 API 操作(getMyClasses/joinClass/assignTopic/createComment)
- SseNotificationService: SSE 实时通知监听 + 自动重连 + 事件流
- ApiException: 统一 API 错误封装
- DTO: ClassMemberDto + TopicDto + CommentDto
设计:
- Repository 模式: 抽象接口 + 远程实现 + 内存实现
- SSE: Dio stream + SSE 协议解析 + 3秒自动重连
- 所有 Repository 通过 ApiClient 注入,依赖现有 JWT 拦截器
验证: flutter analyze 0 error
|
2026-06-01 10:11:47 +08:00 |
|
iven
|
05317d50d5
|
fix(diary): B7 测试套件 + F11 深色模式修复
B7 API 打磨:
- DTO 序列化/反序列化测试 12 个 (Mood/Weather/SyncChange/NotificationType等)
- 测试总数 17 → 29,全部通过
- SyncChange 添加 Serialize derive (测试发现遗漏)
F11 深色模式:
- 修复 mood_page.dart 唯一硬编码颜色 Colors.white → colorScheme.onPrimary
- 全面审计确认所有页面均使用 AppColors/colorScheme,无其他硬编码
验证: cargo test 29/29 ✓ flutter analyze 0 error ✓
|
2026-06-01 10:07:44 +08:00 |
|
iven
|
c4a317c90f
|
feat(app): F8 班级系统 + F9/F10 占位页面
F8 班级系统:
- ClassBloc 状态管理 (班级列表/日记墙/成员/主题/评语)
- 班级主页: 日记墙 + 主题布置 Tab + 成员列表
- 老师管理页: 创建班级 + 布置主题 + 点评入口
- 班级码展示 + 评语卡片
F9 家长功能 (占位):
- 家长中心页面框架: 日记查看/心情统计/使用时间/数据管理
- PIPL 合规提示卡片
F10 搜索/设置 (部分):
- 个人中心: 用户信息 + 角色展示 + 功能入口 + 退出登录
- 搜索页: 标签筛选 + 心情过滤 + 搜索框
验证: flutter analyze 0 error
|
2026-06-01 09:43:54 +08:00 |
|
iven
|
7e3597dc77
|
feat(diary): B4+B5+B6 后端服务 + F5/F6/F7 前端模块
后端 (erp-diary):
- B4: CommentService 班级成员验证 + 删除评语 + SSE 通知推送
- B4: NotificationService 评语/主题/成就三类通知事件
- B5: StickerService 贴纸包列表 + 贴纸查询 + 模板管理
- B5: AchievementService 成就列表 + 解锁 + SSE 通知
- B6: MoodStatsService 心情统计 + 连续天数
- B6: ContentSafetyService 敏感词过滤框架
- SSE handler 增加 diary.notification.* 事件处理
- 新增 14 个 API 端点 + diary.comment.delete 权限
前端 (Flutter):
- F5: CalendarBloc + 月视图日历 + 日记列表
- F6: MoodBloc + fl_chart 心情饼图 + 统计卡片 + 连续天数
- F7: 贴纸库分类浏览 + 模板画廊
- 首页改为日记流 + 心情快速选择
- 成就页改为徽章收集展示
验证: cargo check ✓ cargo test 17/17 ✓ flutter analyze 0 error
|
2026-06-01 09:32:09 +08:00 |
|
iven
|
482eb244d5
|
feat(app): 实现手账编辑器三层架构 (Phase F4)
新增组件:
- DraggableElement: 可拖拽日记元素组件 (移动/缩放/选中/删除)
- EditorToolbar: 底部工具栏 (8种工具 + 8色 + 5级笔宽 + 撤销/重做)
- EditorStack: 三层 Stack 架构 (Canvas + 元素 + 工具栏)
重写文件:
- editor_bloc.dart: 扩展为完整编辑器 BLoC
- 元素管理: 添加/删除/移动/缩放/旋转/选中 (7种事件)
- 工具栏: 8种工具切换 (pen/pencil/marker/eraser/select/text/sticker/image)
- 自动保存: 2秒 debounce 回调
- 状态扩展: elements/selectedElementId/activeTool/isDirty
- editor_page.dart: 从占位页面重写为完整编辑器
- 顶栏: 返回/标题/完成按钮
- 中间: 三层 Stack (手写层 + 元素层 + 空状态提示)
- 底部: EditorToolbar
- 交互逻辑: 画笔模式→Canvas接收, 选择模式→元素层接收
验证: flutter analyze (0 error)
|
2026-06-01 01:45:35 +08:00 |
|
iven
|
0fe3bc705c
|
feat(app): 实现认证模块 — F2 Auth BLoC + 登录/注册/角色选择/班级码加入
新增文件 (10):
- data/models/user.dart — 用户+角色模型 (匹配后端 UserResp/RoleResp)
- data/models/auth_token.dart — 认证令牌模型 (匹配后端 LoginResp)
- data/repositories/auth_repository.dart — 认证仓库 (JWT 安全持久化 + PIPL 合规)
- features/auth/bloc/auth_bloc.dart — 认证 BLoC (8 种事件, 6 种状态)
- features/auth/bloc/auth_event.dart — 认证事件 (sealed class 穷尽匹配)
- features/auth/bloc/auth_state.dart — 认证状态 (Authenticated 含角色/班级码流程)
- features/auth/views/login_page.dart — 登录/注册页面 (重写占位页面)
- features/auth/views/role_selection_page.dart — 角色选择页 (4 种角色卡片)
- features/auth/views/class_code_join_page.dart — 班级码加入页 (6 位输入)
修改文件 (5):
- pubspec.yaml — 添加 flutter_secure_storage 依赖
- app.dart — 注入 AuthBloc + RepositoryProvider
- main.dart — 简化入口 (认证恢复在 BLoC 中处理)
- core/routing/app_router.dart — 添加认证路由守卫 + 2 新路由
- erp-diary/service/class_service.rs — 移除未使用的 PaginatorTrait import
验证: flutter analyze (0 error) + cargo check 通过
|
2026-06-01 01:22:53 +08:00 |
|
iven
|
5e6c6fdd62
|
feat(diary): 数据层 + 班级系统 (Phase F1 + B3)
Flutter 数据层 (Phase F1):
- journal_entry.dart: 日记数据模型 (Mood/Weather/tags/version)
- journal_element.dart: 元素模型 (text/image/sticker/handwriting_ref/tape)
- school_class.dart: 班级模型
- user_settings.dart: 用户设置 (主题/画笔/字号)
- isar_database.dart: Isar 初始化
- api_client.dart: Dio + JWT注入 + 离线感知 + 401处理
- journal_repository.dart: 抽象接口 + InMemory实现 (乐观锁)
- sync_engine.dart: WiFi同步 + 操作队列 + 重试(5次) + 快照持久化
Rust 班级系统 (Phase B3):
- class_service.rs: 创建班级(6位码) + 加入班级 + 成员管理
- topic_service.rs: 老师布置主题 + 主题列表
- comment_service.rs: 老师点评 + 评语列表
- class_handler.rs: 5个API端点 + 权限守卫
- topic_handler.rs: 2个API端点
- comment_handler.rs: 2个API端点
- dto.rs: 新增5个DTO (ClassMemberResp/CreateTopicReq/TopicResp/CreateCommentReq/CommentResp)
- 6条新路由注册
验证: cargo check 通过, 433测试全绿, flutter analyze 1 warning
|
2026-06-01 00:55:51 +08:00 |
|
iven
|
d0653614e0
|
feat(diary): 手写引擎 + 日记 CRUD + 同步 API (Phase F3 + B2)
Flutter 手写引擎 (Phase F3):
- stroke_model.dart: 笔画数据模型 (StrokePoint/Stroke/BrushType)
- stroke_renderer.dart: perfect_freehand 渲染管线 + 四画笔参数
- handwriting_canvas.dart: Listener 输入 + 掌心抑制 + 去抖过滤
- editor_bloc.dart: BLoC 状态管理 + 撤销/重做 (50步)
Rust 日记 CRUD + 同步 (Phase B2):
- journal_service.rs: CRUD + 软删除 + 分页列表 + 事件发布
- sync_service.rs: 版本号同步 + 冲突检测
- journal_handler.rs: 5个API端点 + utoipa注解 + 权限守卫
- sync_handler.rs: 同步API端点
- error.rs: From<DiaryError> for AppError + 8个单元测试
- 路由注册: /diary/journals + /diary/sync
验证:
- cargo check: 0 error
- cargo test: 433 测试全通过
- flutter analyze: 1 warning (unused private param)
|
2026-06-01 00:36:05 +08:00 |
|
iven
|
ee5ce9bc56
|
feat(app): 初始化 Flutter 前端项目 (Phase F0)
- Flutter 3.44.0 + Dart 3.12.0
- 设计系统: 7色Token×浅/深模式, NotoSansSC/Caveat字体, 圆角10/16/22/28/pill, 三级阴影
- ResponsiveScaffold: 手机底部TabBar / 平板侧边Rail / 桌面三栏
- go_router 路由表: 13个页面 (5个Tab + 8个全屏页面)
- 13个功能模块占位页面 (home/calendar/mood/search/profile/editor/auth/class/teacher/parent/achievement/stickers/templates)
- 依赖: flutter_bloc, go_router, freezed, isar, dio, perfect_freehand, fl_chart
- 中国镜像: PUB_HOSTED_URL + FLUTTER_STORAGE_BASE_URL
- flutter analyze: No issues found
|
2026-06-01 00:17:16 +08:00 |
|