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
This commit is contained in:
iven
2026-06-01 00:55:51 +08:00
parent d0653614e0
commit 5e6c6fdd62
18 changed files with 2205 additions and 1 deletions

View File

@@ -123,3 +123,58 @@ pub struct ConflictInfo {
pub local_version: i32,
pub server_version: i32,
}
// ========== 班级成员 ==========
/// 班级成员响应
#[derive(Debug, Serialize, ToSchema)]
pub struct ClassMemberResp {
pub user_id: uuid::Uuid,
pub role: String,
pub nickname: Option<String>,
pub joined_at: chrono::DateTime<chrono::Utc>,
}
// ========== 主题布置 ==========
/// 创建主题请求
#[derive(Debug, Deserialize, ToSchema)]
pub struct CreateTopicReq {
/// 主题标题
pub title: String,
/// 主题描述/要求
pub description: Option<String>,
/// 截止日期
pub due_date: Option<chrono::NaiveDate>,
}
/// 主题响应
#[derive(Debug, Serialize, ToSchema)]
pub struct TopicResp {
pub id: uuid::Uuid,
pub class_id: uuid::Uuid,
pub teacher_id: uuid::Uuid,
pub title: String,
pub description: Option<String>,
pub due_date: Option<chrono::NaiveDate>,
pub is_active: bool,
}
// ========== 评语 ==========
/// 创建评语请求
#[derive(Debug, Deserialize, ToSchema)]
pub struct CreateCommentReq {
/// 评语内容
pub content: String,
}
/// 评语响应
#[derive(Debug, Serialize, ToSchema)]
pub struct CommentResp {
pub id: uuid::Uuid,
pub journal_id: uuid::Uuid,
pub author_id: uuid::Uuid,
pub content: String,
pub created_at: chrono::DateTime<chrono::Utc>,
}